diff --git a/.github/workflows/CFF-test.yml b/.github/workflows/CFF-test.yml index d8c4cda611a6..8cf33d4ce198 100644 --- a/.github/workflows/CFF-test.yml +++ b/.github/workflows/CFF-test.yml @@ -12,6 +12,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: + contents: read + jobs: cffconvert: runs-on: ubuntu-latest diff --git a/.github/workflows/check_changelog.yml b/.github/workflows/check_changelog.yml index 1d440ad6f85a..48449546819a 100644 --- a/.github/workflows/check_changelog.yml +++ b/.github/workflows/check_changelog.yml @@ -8,6 +8,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: + pull-requests: read + jobs: changelog_checker: name: Check if towncrier change log entry is correct diff --git a/.github/workflows/check_milestone.yml b/.github/workflows/check_milestone.yml index 2d6550849642..027cf1d8e94f 100644 --- a/.github/workflows/check_milestone.yml +++ b/.github/workflows/check_milestone.yml @@ -9,7 +9,7 @@ concurrency: cancel-in-progress: true permissions: - contents: read + pull-requests: read jobs: # https://stackoverflow.com/questions/69434370/how-can-i-get-the-latest-pr-data-specifically-milestones-when-running-yaml-jobs diff --git a/.github/workflows/ci_benchmark.yml b/.github/workflows/ci_benchmark.yml index ea8f3fbf2a0b..5b57d3329d4f 100644 --- a/.github/workflows/ci_benchmark.yml +++ b/.github/workflows/ci_benchmark.yml @@ -28,9 +28,10 @@ jobs: steps: - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: + persist-credentials: false fetch-depth: 0 - - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + - uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 name: Install Python with: python-version: "3.11" @@ -53,7 +54,7 @@ jobs: ccache -z - name: "Restore ccache" - uses: actions/cache@2cdf405574d6ef1f33a1d12acccd3ae82f47b3f2 # v4.1.0 + uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2 with: path: .ccache key: ccache-${{ secrets.CACHE_VERSION }}-${{ steps.prepare-ccache.outputs.key }}-${{ steps.prepare-ccache.outputs.timestamp }} @@ -69,6 +70,8 @@ jobs: OMP_NUM_THREADS: 1 ASV_FACTOR: 1.3 ASV_SKIP_SLOW: 1 + BASE_SHA: ${{ github.event.pull_request.base.sha }} + BASE_LABEL: ${{ github.event.pull_request.base.label }} run: | set -x python -m pip install asv virtualenv packaging @@ -78,19 +81,19 @@ jobs: # ID this runner python -m asv machine --yes --conf asv.ci.conf.json - echo "Baseline: ${{ github.event.pull_request.base.sha }} (${{ github.event.pull_request.base.label }})" - echo "Contender: ${GITHUB_SHA} (${{ github.event.pull_request.head.label }})" + echo "Baseline: ${BASE_SHA} (${BASE_LABEL})" + echo "Contender: ${GITHUB_SHA} (${BASE_LABEL})" # Run benchmarks for current commit against base ASV_OPTIONS="--split --show-stderr --factor $ASV_FACTOR --conf asv.ci.conf.json" - python -m asv continuous $ASV_OPTIONS ${{ github.event.pull_request.base.sha }} ${GITHUB_SHA} + python -m asv continuous $ASV_OPTIONS ${BASE_SHA} ${GITHUB_SHA} - name: "Check ccache performance" shell: bash -l {0} run: ccache -s if: always() - - uses: actions/upload-artifact@604373da6381bf24206979c74d06a550515601b9 # v4.4.1 + - uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 if: always() with: name: asv-benchmark-results diff --git a/.github/workflows/ci_cron_daily.yml b/.github/workflows/ci_cron_daily.yml index 9d33731e7708..3560a1ca62b1 100644 --- a/.github/workflows/ci_cron_daily.yml +++ b/.github/workflows/ci_cron_daily.yml @@ -56,10 +56,11 @@ jobs: - name: Checkout code uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: + persist-credentials: false fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 with: python-version: ${{ matrix.python }} diff --git a/.github/workflows/ci_cron_weekly.yml b/.github/workflows/ci_cron_weekly.yml index acc4d70e40ae..fd7b289f36cd 100644 --- a/.github/workflows/ci_cron_weekly.yml +++ b/.github/workflows/ci_cron_weekly.yml @@ -28,6 +28,9 @@ concurrency: env: IS_CRON: 'true' +permissions: + contents: read + jobs: tests: runs-on: ${{ matrix.os }} @@ -75,9 +78,10 @@ jobs: - name: Checkout code uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: + persist-credentials: false fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 with: python-version: ${{ matrix.python }} - name: Install language-pack-de and tzdata @@ -99,8 +103,10 @@ jobs: # The following architectures are emulated and are therefore slow, so # we include them just in the weekly cron. These also serve as a test # of using system libraries and using pytest directly. + # No doctest run here due to architecture differences in some outputs + # (e.g., big-endian or 32-bit OS) with numpy 2. - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 name: Python 3.12 # keep condition in sync with test_arm64 if: (github.repository == 'astropy/astropy' && (github.event_name == 'schedule' || github.event_name == 'push' || github.event_name == 'workflow_dispatch' || contains(github.event.pull_request.labels.*.name, 'Extra CI'))) @@ -118,8 +124,9 @@ jobs: steps: - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: + persist-credentials: false fetch-depth: 0 - - uses: uraimo/run-on-arch-action@5397f9e30a9b62422f302092631c99ae1effcd9e # v2.8.1 + - uses: uraimo/run-on-arch-action@4141da824ffb5eda88d221d9cf835f6a61ed98d9 # v3.0.0 name: Run tests id: build with: @@ -165,28 +172,4 @@ jobs: pip install -U --no-build-isolation pyerfa ASTROPY_USE_SYSTEM_ALL=1 pip3 install -v --no-build-isolation -e .[test] pip3 list - python3 -m pytest -m "not hypothesis" - - test_arm64: - - # Native arm64 testing - we keep this in the weekly cron as we need to pay for it so we should - # minimize how many jobs we do. - - runs-on: linux-arm64 - name: Python 3.12 (arm64) - # keep condition in sync with test_more_architectures - if: (github.repository == 'astropy/astropy' && (github.event_name == 'schedule' || github.event_name == 'push' || github.event_name == 'workflow_dispatch' || contains(github.event.pull_request.labels.*.name, 'Extra CI'))) - env: - ARCH_ON_CI: "arm64" - - steps: - - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 - with: - fetch-depth: 0 - - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 - with: - python-version: '3.12' - - name: Set up dependencies - run: pip install tox - - name: Run tests - run: tox -e py312-test -- -n=2 + python3 -m pytest --pyargs astropy -m "not hypothesis" diff --git a/.github/workflows/ci_workflows.yml b/.github/workflows/ci_workflows.yml index ddec9a3a7003..833d577664d6 100644 --- a/.github/workflows/ci_workflows.yml +++ b/.github/workflows/ci_workflows.yml @@ -17,6 +17,9 @@ env: ARCH_ON_CI: "normal" IS_CRON: "false" +permissions: + contents: read + jobs: initial_checks: name: Mandatory checks before CI @@ -46,7 +49,7 @@ jobs: tests: needs: [initial_checks] - uses: OpenAstronomy/github-actions-workflows/.github/workflows/tox.yml@924441154cf3053034c6513d5e06c69d262fb9a6 # v1.13.0 + uses: OpenAstronomy/github-actions-workflows/.github/workflows/tox.yml@8c0fde6f7e926df6ed7057255d29afa9c1ad5320 # v1.16.0 secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: @@ -91,12 +94,18 @@ jobs: posargs: --durations=50 --run-slow runs-on: macos-latest + # FIXME: Add aarch64 to name when bump Python version. - name: Python 3.11 Double test (Run tests twice) linux: py311-test-double + runs-on: ubuntu-24.04-arm + posargs: -n=4 + setenv: | + ARCH_ON_CI: "arm64" + IS_CRON: "false" allowed_failures: needs: [initial_checks] - uses: OpenAstronomy/github-actions-workflows/.github/workflows/tox.yml@924441154cf3053034c6513d5e06c69d262fb9a6 # v1.13.0 + uses: OpenAstronomy/github-actions-workflows/.github/workflows/tox.yml@8c0fde6f7e926df6ed7057255d29afa9c1ad5320 # v1.16.0 with: setenv: | ARCH_ON_CI: "normal" @@ -117,7 +126,7 @@ jobs: # This ensures that a couple of wheel targets work fine in pull requests and pushes permissions: contents: none - uses: OpenAstronomy/github-actions-workflows/.github/workflows/publish.yml@924441154cf3053034c6513d5e06c69d262fb9a6 # v1.13.0 + uses: OpenAstronomy/github-actions-workflows/.github/workflows/publish.yml@8c0fde6f7e926df6ed7057255d29afa9c1ad5320 # v1.16.0 with: upload_to_pypi: false upload_to_anaconda: false diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index b7922add814d..38ac6094a163 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -40,6 +40,7 @@ jobs: - name: Checkout repository uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: + persist-credentials: false fetch-depth: 0 # Initializes the CodeQL tools for scanning. @@ -66,7 +67,7 @@ jobs: # uses a compiled language - name: Set up Python - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 if: matrix.language == 'cpp' with: python-version: '3.11' diff --git a/.github/workflows/open_actions.yml b/.github/workflows/open_actions.yml index fe03a912c1a6..d3be61b448d5 100644 --- a/.github/workflows/open_actions.yml +++ b/.github/workflows/open_actions.yml @@ -4,10 +4,13 @@ on: issues: types: - opened - pull_request_target: + pull_request_target: # zizmor: ignore[dangerous-triggers] types: - opened +permissions: + pull-requests: write + jobs: triage: runs-on: ubuntu-latest diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index dcb46d44363e..8b22debf0815 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,7 +26,7 @@ jobs: # or if triggered manually via the workflow dispatch, or for a tag. permissions: contents: none - uses: OpenAstronomy/github-actions-workflows/.github/workflows/publish.yml@924441154cf3053034c6513d5e06c69d262fb9a6 # v1.13.0 + uses: OpenAstronomy/github-actions-workflows/.github/workflows/publish.yml@8c0fde6f7e926df6ed7057255d29afa9c1ad5320 # v1.16.0 if: (github.repository == 'astropy/astropy' && ( startsWith(github.ref, 'refs/tags/v') || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || contains(github.event.pull_request.labels.*.name, 'Build all wheels'))) with: @@ -57,11 +57,14 @@ jobs: - cp312-manylinux_x86_64 - cp313-manylinux_x86_64 - # Note that following wheels are not currently tested: + - target: cp311-manylinux_aarch64 + runs-on: ubuntu-24.04-arm + - target: cp312-manylinux_aarch64 + runs-on: ubuntu-24.04-arm + - target: cp313-manylinux_aarch64 + runs-on: ubuntu-24.04-arm - - cp311-manylinux_aarch64 - - cp312-manylinux_aarch64 - - cp313-manylinux_aarch64 + # Note that following wheels are not currently tested: - cp311-musllinux_x86_64 - cp312-musllinux_x86_64 diff --git a/.github/workflows/stalebot.yml b/.github/workflows/stalebot.yml index cce64863ef6e..f2fccc701728 100644 --- a/.github/workflows/stalebot.yml +++ b/.github/workflows/stalebot.yml @@ -7,6 +7,9 @@ on: - cron: '30 5 * * *' workflow_dispatch: +permissions: + pull-requests: write + jobs: stalebot: runs-on: ubuntu-latest diff --git a/.github/workflows/update_astropy_iers_data_pin.yml b/.github/workflows/update_astropy_iers_data_pin.yml index 2721f38cae63..50868a623cbc 100644 --- a/.github/workflows/update_astropy_iers_data_pin.yml +++ b/.github/workflows/update_astropy_iers_data_pin.yml @@ -24,8 +24,10 @@ jobs: steps: - name: Checkout code uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + with: + persist-credentials: false - name: Set up Python - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 with: python-version: 3.x - name: Install dependencies @@ -41,7 +43,7 @@ jobs: git commit -m "Update minimum required version of astropy-iers-data" fi - name: Create Pull Request - uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5 + uses: peter-evans/create-pull-request@dd2324fc52d5d43c699a5636bcf19fceaa70c284 # v7.0.7 with: branch: update-astropy-iers-data-pin branch-suffix: timestamp diff --git a/.mailmap b/.mailmap index d0bc09cea7db..1a9ba0b9c526 100644 --- a/.mailmap +++ b/.mailmap @@ -93,6 +93,8 @@ David Grant <33813984+DavoGrant@ David Kirkby David Pérez-Suárez David Shupe +Deen-Dot Deen-dot +Deen-Dot Deen-dot <80238871+Deen-dot@users.noreply.github.com> Demitri Muna Demitri Muna Demitri Muna @@ -103,8 +105,7 @@ Diego Asterio de Zaballa Douglas Burke Dylan Gregersen Edward Gomez -Ed Slavich -Ed Slavich Edward Slavich +Edward Slavich Ed Slavich Eduardo Olinto <90293761+olintoeduardo@users.noreply.github.com> Eero Vaher Elijah Bernstein-Cooper @@ -148,6 +149,7 @@ Jaime Andrés Jake VanderPlas Jake VanderPlas Jake VanderPlas +James Davies James McCormac James Tocknell James Tocknell @@ -164,9 +166,12 @@ Javier Duran Javier Duran Javier Pascual Granado +Jeff Jennings Jeff Taylor Jennifer Karr Jero Bado +Jero Bado <10357742+jerobado@users.noreply.github.com> +Jo Bovy Joe Hunkeler Johannes Zeman John Parejko @@ -222,6 +227,7 @@ Magnus Persson Maneesh Yadav Mangala Gowri Krishnamoorthy Manon Marchand +Marcello Nascif <118627858+marcellonascif@users.noreply.github.com> Marten van Kerkwijk Marten van Kerkwijk Marten H. van Kerkwijk Marten van Kerkwijk Marten Henric van Kerkwijk @@ -245,6 +251,7 @@ Mihai Cara Mikhail Minin Moataz Hisham +Mridul Seth Mubin Manasia Mubin17 <48038715+Mubin17@users.noreply.github.com> Nabil Freij Nadia Dencheva @@ -267,6 +274,7 @@ Pauline Barmby Perry Greenfield P. L. Lim <2090236+pllim@users.noreply.github.com> P. L. Lim <2090236+pllim@users.noreply.github.com> +Porter Averett <46609497+paverett@users.noreply.github.com> Prajwel Joseph Pratik Patel Pritish Chakraborty @@ -285,19 +293,23 @@ Rohit Patil Rohit Patil Roman Tolesnikov Ryan Cooke -Sam Lee +Sam Lee +Sam Van Kooten Sam Verstocken Sanjeev Dubey Sara Ogaz Sarah Graves +Sashank Mishra sashmish Sebastian Meßlinger <39328484+krachyon@users.noreply.github.com> Sebastian Meßlinger Sebastian Sergio Pascual +Shane Maloney +Shane Maloney Shantanu Srivastava Shilpi Jain Shivansh Mishra Shivansh Mishra -Simon Alinder +Simon Alinder <92031780+AlinderS@users.noreply.github.com> Simon Conseil Simon Conseil Simon Conseil @@ -315,6 +327,7 @@ Stuart Mumford Sudheesh Singanamalla Sudheesh Singanamalla Sushobhana Patra +Tanvi Pooranmal Meena <96572616+mtanvi19@users.noreply.github.com> <96572616+TanviPooranmal@users.noreply.github.com> Thomas Erben Thompson Le Blanc Thompson Le Blanc diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b358e7d1dfb4..76d177a63ab8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ repos: exclude: "^(\ cextern/wcslib/C/flexed/.*|\ CHANGES.rst|\ - astropy/extern/jquery/data/js/jquery.dataTables.js|\ + astropy/extern/jquery/data/js/datatables.js|\ )$" # Prevent giant files from being committed. - id: check-case-conflict diff --git a/CHANGES.rst b/CHANGES.rst index 089579b245d7..f0d52b37da28 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,1082 @@ +Version 7.0.2 (2025-05-12) +========================== + +Bug Fixes +--------- + +astropy.config +^^^^^^^^^^^^^^ + +- Fix a bug where config file generation did not parse nested subclasses of ``astropy.config.ConfigNamespace``. [#18107] + +astropy.io.fits +^^^^^^^^^^^^^^^ + +- Fix a bug in ``nddata.Cutout2D`` when creating partial cutouts of ``Section`` objects by adding a ``dtype`` property to the ``Section`` class. [#17611] + +- Fixed a bug so that now the scaling state from the source HDU to the new appended HDU is copied on the + destination file, when the HDU is read with ``do_not_scale_image_data=True``. [#17642] + +- Fix setting a slice on table rows (``FITS_record``). [#17737] + +- Fix checksum computation for tables with VLA columns, when table is loaded in + memory. [#17806] + +- Fix ``.fileinfo()`` for compressed HDUs. [#17815] + +- Fix FITS_rec repr when a column has scaling factors, leading to a crash with + numpy>=2.0. [#17933] + +- Fixed a bug that caused THEAP, ZBLANK, ZSCALE, and ZZERO to not be correctly + removed during decompression of tile-compressed FITS files. [#18072] + +astropy.io.votable +^^^^^^^^^^^^^^^^^^ + +- ``astropy`` v7.0.0 erroneously refused to write a VOTable if it contained units that + could not be represented in the CDS format. + Now ``astropy`` correctly chooses the unit format based on the VOTable version. + The bug in question did not cause any corruption in tables that were successfully + written because the newer VOUnit format is backwards compatible with the CDS format. + Furthermore, any unit that is in neither formats would still be written out + but would issue a warning. [#17570] + +- ``unicodeChar`` fields can now be of bounded variable size (``arraysize="10*``). [#18075] + +astropy.modeling +^^^^^^^^^^^^^^^^ + +- Fixed an issue where the ``filter_non_finite`` option was not working + for 2D models. An error is raised when the ``filter_non_finite`` option + is set to ``True`` and all values are non-finite. [#17869] + +astropy.stats +^^^^^^^^^^^^^ + +- Now ``bayesian_blocks(t, x, fitness="events")`` correctly handles the case + when the input data ``x`` contains zeros. [#17800] + +astropy.table +^^^^^^^^^^^^^ + +- Prevent corrupting a column by mutating its name to an invalid type. + A ``TypeError`` is now raised when a name is set to anything other than a + string. [#17450] + +- Fix a bug in creating a ``Table`` from a list of rows that dropped the units + of non-scalar Quantity, e.g., ``Table(rows=[([1] * u.m,), ([2] * u.m,)])``. [#17936] + +astropy.units +^^^^^^^^^^^^^ + +- Ensured that the units of ``yp``, ``refa`` and ``refb`` are properly + taken into account when calling ``erfa.apio`` (previously, the + conversion required for ``xp`` was applied to those inputs too). [#17742] + +- The machinery that injects units into a namespace (used e.g. by ``def_unit()``) + now applies NFKC normalization to unit names when checking for name collisions. + This prevents name collisions if the namespace belongs to a module and the unit + is accessed as an attribute of that module. [#17853] + +- The string representations of the prefixed versions of ``solLum``, ``solMass`` + and ``solRad`` units can now be parsed by default. + Previously they could only be parsed if the ``required_by_vounit`` module had + been imported, possibly indirectly by using the ``"vounit"`` format. [#17868] + +astropy.utils +^^^^^^^^^^^^^ + +- Prevent corrupting a mixin column's ``info`` attribute by mutating its name to + an invalid type. A ``TypeError`` is now raised when a name is set to anything + other than a string. [#17450] + +astropy.visualization +^^^^^^^^^^^^^^^^^^^^^ + +- Ensure that the ``astropy.visualization.wcsaxes.custom_ucd_coord_meta_mapping`` + context manager performs a (correct) cleanup. [#17749] + +- Fixed interval classes for masked input (``MaskedArray`` and ``MaskedNDArray``). [#17927] + +- Fixed the limits of ``a`` parameter in the ``PowerDistStretch`` + and ``InvertedPowerDistStretch`` classes so that a value of + 0 in no longer allowed. That value gives infinity values in + ``InvertedPowerDistStretch`` and it makes the ``PowerDistStretch`` + results independent of the input data. [#17941] + +- Fixed an issue where LinearStretch values were not being clipped to + [0:1] when ``clip=True``. [#17943] + +astropy.wcs +^^^^^^^^^^^ + +- Fix UCD for air wavelengths, following the IVOA recommendation that ``'em.wl'`` + be reserved for vacuum wavelengths. ``'em.wl;obs.atmos'`` is now used to + represent air wavelengths instead. [#17769] + + +Other Changes and Additions +--------------------------- + +- Updated the bundled CFITSIO library to 4.6.0. [#17904] + +Version 7.0.1 (2025-02-06) +========================== + +API Changes +----------- + +astropy.table +^^^^^^^^^^^^^ + +- The use of the keyword ``use_local_files`` for the js viewer in + ``astropy.table.Table.show_in_browser`` is now deprecated. Starting in Astropy + 7.1 this keyword will be ignored and use of it will issue a warning. The + default behavior will be to use the remote versions of jQuery and DataTables + from a CDN. [#17480] + +Bug Fixes +--------- + +astropy.config +^^^^^^^^^^^^^^ + +- With ``astropy`` v7.0.0 the cache directory cannot be customized with the + ``XDG_CACHE_HOME`` environment variable. + Instead, ``XDG_CONFIG_HOME`` erroneously controls both configuration and cache + directories. + The correct pre-v7.0.0 behaviour has been restored, but it is possible that + ``astropy`` v7.0.0 has written cache files to surprising locations. + Concerned users can use the ``get_cache_dir_path()`` function to check where + the cache files are written. + + The bug in question does not affect systems where the ``XDG_CACHE_HOME`` and + ``XDG_CONFIG_HOME`` environment variables are unset. [#17514] + +astropy.coordinates +^^^^^^^^^^^^^^^^^^^ + +- Fixed a numerical-precision bug with the calculation of the ``theta`` + component when converting from ``CylindricalRepresentation`` to + ``PhysicsSphericalRepresentation`` for vectors very close to the Z axis (within + milliarcseconds). [#17693] + +astropy.io.ascii +^^^^^^^^^^^^^^^^ + +- Fixed parsing ASCII table with data that starts with a tilda. [#17565] + +- Find and read ASCII tables even if there is white space before + ``\begin{tabular}``, ``\tablehead``, and similar markers. [#17624] + +astropy.io.fits +^^^^^^^^^^^^^^^ + +- Fix memory leak in ```BinTableHDU.copy()``` [#16143] + +- Fix overflow error with Numpy 2 and VLA columns using P format. [#17328] + +- Fix ``ImageHDU.scale`` with float. [#17458] + +- Fixed ``Table.write(..., format="fits", overwrite=True)`` when filename is + provided as ``pathlib.Path``. [#17552] + +astropy.io.votable +^^^^^^^^^^^^^^^^^^ + +- Updated XML writer for ``VOTableFile`` element to include or drop + ``coordinate_systems`` regardless of version. [#17356] + +astropy.modeling +^^^^^^^^^^^^^^^^ + +- Fix fitting of compound models when inputs has more than one dimension, and + specifically fix fitting of compound models with Polynomial2D components + [#17618] + +astropy.table +^^^^^^^^^^^^^ + +- Ensure that representations and differentials, like SkyCoord, can be used in + table join operations, by making use of the fact that they can now be masked. [#17381] + +- Fix a crash in ``Table.show_in_browser`` due to an internal type inconsistency. [#17513] + +- Fix incorrect description of the ``unique`` parameter in ``Table.add_index``'s + docstring. Add missing Raises section. [#17677] + +astropy.units +^^^^^^^^^^^^^ + +- Ensure that ``Unit.to`` allows as ``value`` argument all array types that + follow the array API standard and define ``__array_namespace__``. Furthermore, + for backwards compatibility, generally pass through arguments that define a + ``.dtype``, independent of whether that is a numpy data type. [#17469] + +- The zebi (Zi, 2^70) and yobi (Yi, 2^80) binary prefixes are now supported. [#17692] + +astropy.visualization +^^^^^^^^^^^^^^^^^^^^^ + +- Fix ``CoordinateHelper.ticklabels``. The getter was incorrectly returning + the helper's ticks rather than the labels. [#17444] + +- The following private classes from ``astropy.visualization.lupton_rgb``, that + were dropped without deprecation in astropy 7.0.0, were re-introduced following + a report that they were used downstream. The following classes are now + considered public: + + - ``Mapping`` + - ``AsinhMapping`` + - ``LinearMapping`` + - ``AsinhZScaleMapping`` [#17531] + +Other Changes and Additions +--------------------------- + +- Update bundled js library datatables to version 2.1.8, which is current at the time of this PR. [#17480] + +Version 7.0.0 (2024-11-21) +========================== + + +New Features +------------ + +astropy.config +^^^^^^^^^^^^^^ + +- Added ``get_config_dir_path`` (and ``get_cache_dir_path``) which is equivalent + to ``get_config_dir`` (respectively ``get_cache_dir``) except that it returns a + ``pathlib.Path`` object instead of ``str``. [#17118] + +astropy.coordinates +^^^^^^^^^^^^^^^^^^^ + +- ``BaseCoordinateFrame`` instances such as ``ICRS``, ``SkyOffsetFrame``, etc., + can now be stored directly in tables (previously, they were stored as + ``object`` type columns). Furthermore, storage in tables is now also possible + for frames that have no data (but which have attributes with the correct shape + to fit in the table). [#16831] + +- ``BaseCoordinateFrame`` now has a ``to_table()`` method, which converts the + frame to a ``QTable``, analogously to the ``SkyCoord.to_table()`` method. [#17009] + +- ``SkyCoord``, coordinate frames, and representations have all have gained the + ability to deal with ``Masked`` data. In general, the procedure is similar to + that of ``Time``, except that different representation components do not share + the mask, to enable holding, e.g., a catalogue of objects in which only some + have associated distances. [#17016] + +astropy.io.ascii +^^^^^^^^^^^^^^^^ + +- Add support for ``pathlib.Path`` objects in + ``astropy.io.ascii.core.BaseInputter.get_lines``. [#16930] + +astropy.io.fits +^^^^^^^^^^^^^^^ + +- Expanded ``FITSDiff`` output for ``PrimaryHDU`` and ``ImageHDU`` to include the + maximum relative and absolute differences in the data. [#17097] + +astropy.io.misc +^^^^^^^^^^^^^^^ + +- The HDF5 writer, ``write_table_hdf5()``, now accepts ``os.PathLike`` objects + as ``output``. [#16955] + +astropy.io.votable +^^^^^^^^^^^^^^^^^^ + +- Support reading and writing of VOTable version 1.5, including the new + ``refposition`` attribute of ``COOSYS``. [#16856] + +astropy.modeling +^^^^^^^^^^^^^^^^ + +- Added ``Model.has_tied``, ``Model.has_fixed``, and ``Model.has_bounds`` attributes to make + it easy to check whether models have various kinds of constraints set without having to + inspect ``Model.tied``, ``Model.fixed``, and ``Model.bounds`` in detail. [#16677] + +- Added a new ``parallel_fit_dask`` function that can be used to fit models to + many sections (e.g. spectra, image slices) on an N-dimensional array in + parallel. [#16696] + +- Added a ``Lorentz2D`` model. [#16800] + +- Added ``inplace=False/True`` keyword argument to the ``__call__`` method of most fitters, + to optionally allow the original model passed to the fitter to be modified with the fitted + values of the parameters, rather than return a copy. This can improve performance if users + don't need to keep hold of the initial parameter values. [#17033] + +astropy.stats +^^^^^^^^^^^^^ + +- Added a ``SigmaClippedStats`` convenience class for computing sigma-clipped + statistics. [#17221] + +astropy.table +^^^^^^^^^^^^^ + +- Changed a number of dict-like containers in ``io.ascii`` from ``OrderedDict`` to + ``dict``. The ``dict`` class maintains key order since Python 3.8 so ``OrderedDict`` is + no longer needed. The changes are largely internal and should not affect users in any + way. See also the API change log entry for this PR. [#16250] + +- Add a ``keep_order`` argument to the ``astropy.table.join`` function which specifies to + maintain the original order of the key table in the joined output. This applies for + inner, left, and right joins. The default is ``False`` in which case the output is + ordered by the join keys, consistent with prior behavior. [#16361] + +astropy.units +^^^^^^^^^^^^^ + +- Add a ``formatter`` argument to the ``to_string`` method of the ``Quantity`` + class. Enables custom number formatting with a callable formatter or + format_spec, especially useful for consistent notation. [#16087] + +- Add the unit foe (or Bethe, equivalent to 1e51 erg), which is often used to + express the energy emitted by a supernova explosion. [#16441] + +- Add ``magnetic_flux_field`` equivalency to convert magnetic field between + magnetic field strength (H) and magnetic flux density (B). [#16516] + +- Added SI-units ``sievert``, ``gray``, ``katal``, and ``hectare`` in ``astropy.units.si``. [#16729] + +- When parsing invalid unit strings with ``u.Unit(..., parse_strict="warn")`` or + ``u.Unit(..., parse_strict="silent")``, a normal unit may be returned if the + problem is not too serious. + If parsing the string fails completely then an ``UnrecognizedUnit`` instance is + returned, just as before. [#16892] + +- Added a ``np.arange`` dispatch for ``Quantity`` (requires one to use + ``like=``). [#17059] + +- Added support for calling numpy array constructors (``np.empty``, ``np.ones``, + ``np.zeros`` and ``np.full``) with ``like=Quantity(...)`` . [#17120] + +- Added support for calling numpy array constructors (``np.array``, + ``np.asarray``, ``np.asanyarray``, ``np.ascontiguousarray`` and + ``np.asfortranarray``) with ``like=Quantity(...)`` . [#17125] + +- Added support for calling numpy array constructors (``np.frombuffer``, + ``np.fromfile``, ``np.fromiter``, ``np.fromstring`` and ``np.fromfunction``) + with ``like=Quantity(...))`` . [#17128] + +- Added support for calling numpy array constructors (``np.require``, + ``np.identity``, ``np.eye``, ``np.tri``, ``np.genfromtxt`` and ``np.loadtxt``) + with ``like=Quantity(...))`` . [#17130] + +astropy.utils +^^^^^^^^^^^^^ + +- Added the ``astropy.system_info`` function to help document runtime systems in + bug reports. [#16335] + +- Add support for specifying files as ``pathlib.Path`` objects in ``IERS_A.read`` + and ``IERS_B.read``. [#16931] + +astropy.visualization +^^^^^^^^^^^^^^^^^^^^^ + +- Add ``make_rgb()``, a convenience + function for creating RGB images with independent scaling on each filter. + Refactors ``make_lupton_rgb()`` to work with instances of subclasses of + ``BaseStretch``, including the new Lupton-specific classes + ``LuptonAsinhStretch`` and ``LuptonAsinhZscaleStretch``. [#15081] + +- Add support for custom coordinate frames for ``WCSAxes`` through a context + manager ``astropy.visualization.wcsaxes.custom_ucd_coord_meta_mapping``. [#16347] + +- Added ``get_ticks_position``, ``get_ticklabel_position``, and + ``get_axislabel_position`` methods on ``CoordinateHelper`` in WCSAxes. [#16686] + +- Added the ability to disable the automatic simplification of WCSAxes tick labels + by specifying ``simplify=False`` to ``set_ticklabel()`` for a coordinate axis. [#16938] + +- Added the ability to specify that WCSAxes tick labels always include the sign + (namely for positive values) by starting the format string with a ``+`` + character. [#16985] + +- Allow ``astropy.visualization.units.quantity_support`` to be used as a + decorator in addition to the already supported use as a context manager. [#17006] + +- Added the ability to specify a callable function in ``CoordinateHelper.set_major_formatter`` [#17020] + +- Added a ``SimpleNorm`` class to create a matplotlib normalization object. [#17217] + +- WCSAxes will now select which axis to draw which tick labels and axis labels on based on the number of drawn tick labels, rather than picking them in the order they are listed in the WCS. This means that axes may be swapped in comparison with previous versions of Astropy by default. [#17243] + + +API Changes +----------- + +astropy.coordinates +^^^^^^^^^^^^^^^^^^^ + +- For non-scalar frames without data, ``len(frame)`` will now return the first + element of its ``shape``, just like for frames with data (or arrays more + generally). For scalar frames, a ``TypeError`` will be raised. Both these + instead of raising a ``ValueError`` stating the frame has no data. [#16833] + +- The deprecated ``coordinates.get_moon()`` function has been removed. Use + ``coordinates.get_body("moon")`` instead. [#17046] + +- The deprecated ``BaseCoordinateFrame.get_frame_attr_names()`` is removed. + Use ``get_frame_attr_defaults()`` instead. [#17252] + +astropy.cosmology +^^^^^^^^^^^^^^^^^ + +- Passing redshift arguments as keywords is deprecated in many methods. [#16597] + +- Deprecated ``cosmology.utils`` module has been removed. Any public API may + be imported directly from the ``cosmology`` module instead. [#16730] + +- Setting ``Ob0 = None`` in FLRW cosmologies has been deprecated in favor of ``Ob0 = + 0.0``. Conceptually this is a change in that baryons are now always a component of the + cosmology. Practically, the only change (besides that ``Ob0`` is never ``None``) is that + methods relying on ``Ob0`` always work, rather than sometimes raising an exception, + instead by default taking the contribution of the baryons to be negligible. [#16847] + +astropy.io.ascii +^^^^^^^^^^^^^^^^ + +- Remove all deprecated arguments from functions within ``astropy.io.ascii``. + + ``read()``: + - ``Reader`` is removed. Instead supply the equivalent ``format`` argument. + - Use ``inputter_cls`` instead of ``Inputter``. + - Use ``outputter_cls`` instead of ``Outputter``. + + ``get_reader()``: + - Use ``reader_cls`` instead of ``Reader``. + - Use ``inputter_cls`` instead of ``Inputter``. + - Use ``outputter_cls`` instead of ``Outputter``. + + ``write()``: + - ``Writer`` is removed. Instead supply the equivalent ``format`` argument. + + ``get_writer()``: + - Use ``writer_cls`` instead of ``Writer``. [#15758] + +astropy.io.fits +^^^^^^^^^^^^^^^ + +- The ``CompImageHDU`` class has been refactored to inherit from ``ImageHDU`` + instead of ``BinTableHDU``. This change should be for the most part preserve the + API, but any calls to ``isinstance(hdu, BinTableHDU)`` will now return ``False`` + if ``hdu`` is a ``CompImageHDU`` whereas before it would have returned ``True``. + In addition, the ``uint`` keyword argument to ``CompImageHDU`` now defaults to + ``True`` for consistency with ``ImageHDU``. [#15474] + +- Remove many unintended exports from ``astropy.io.fits.hdu.compressed``. + The low-level functions ``compress_image_data`` and ``decompress_image_data_section`` + are now only available at the qualified names + ``astropy.io.fits.hdu.compressed._tiled_compression.compress_image_data`` + and ``astropy.io.fits.hdu.compressed._tiled_compression.decompress_image_data_section``. + The rest of the removed exports are external modules or properly exported + elsewhere in astropy. May break imports in rare cases that relied + on these exports. [#15781] + +- The ``CompImageHeader`` class is now deprecated, and headers on ``CompImageHDU`` + instances are now plain ``Header`` instances. If a reserved keyword is set on + ``CompImageHDU.header``, a warning will now be emitted at the point where the + file is written rather than at the point where the keyword is set. [#17100] + +- - Remove code that was deprecated in previous versions: ``_ExtensionHDU`` and + ``_NonstandardExtHDU``, ``(Bin)Table.update``, ``tile_size`` argument for + ``CompImageHDU``. Also specifying an invalid ``tile_shape`` now raises an + error. [#17155] + +astropy.io.misc +^^^^^^^^^^^^^^^ + +- New format ``"parquet.votable"`` is added to read and write a parquet file + with a votable metadata included. [#16375] + +astropy.io.votable +^^^^^^^^^^^^^^^^^^ + +- ``Table.read(..., format='votable')``, ``votable.parse`` and + ``votable.parse_single_table`` now respect the ``columns`` argument and will only output + selected columns. Previously, unselected columns would just be masked (and unallocated). + ``astropy.io.votable.tree.TableElement.create_arrays`` also gained a ``colnumbers`` + keyword argument to allow column selection. [#15959] + +astropy.modeling +^^^^^^^^^^^^^^^^ + +- Subclasses of ``_NonLinearLSQFitter``, so any subclasses of the public ``LevMarLSQFitter``, ``TRFLSQFitter``, ``LMLSQFitter`` or ``DogBoxLSQFitter``, should now accept an additional ``fit_param_indices`` kwarg in the function signature of their ``objective_function`` methods. + Nothing is needed to be done with this kwarg, and it might not be set, but it can optionally be passed through to ``fitter_to_model_params_array`` for a performance improvement. + We also recommended accepting all kwargs (with ``**kwargs``) in this method so that future additional kwargs do not cause breakage. [#16673] + +- Exception message for when broadcast shapes mismatch has changed. + Previously, it used complicated regex to maintain backward compatibility. + To ease maintenance, this regex has been removed and now directly + passes exception from ``numpy.broadcast_shapes`` function. [#16770] + +- Using the ``LMLSQFitter`` fitter with models that have bounds is now deprecated, + as support for bounds was very basic. Instead, non-linear fitters with more + sophisticated support for bounds should be used instead. [#16994] + +- The optional ``use_min_max_bounds`` keyword argument in ``TRFLSQFitter`` and + ``DogBoxLSQFitter`` has now been deprecated and should not be used. These + fitters handle bounds correctly by default and this keyword argument was only + provided to opt-in to a more basic form of bounds handling. [#16995] + +- The deprecated ``comb()`` function has been removed. + Use ``math.comb()`` from the Python standard library instead. [#17248] + +astropy.stats +^^^^^^^^^^^^^ + +- Integer inputs to ``sigma_clip`` and ``SigmaClip`` are not converted to + ``np.float32`` instead of ``float`` if necessary. [#17116] + +astropy.table +^^^^^^^^^^^^^ + +- Change the default type for the ``meta`` attribute in ``Table`` and ``Column`` (and + subclasses) from ``OrderedDict`` to ``dict``. Since Python 3.8 the ``dict`` class is + ordered by default, so there is no need to use ``OrderedDict``. + + In addition the ECSV table writer in ``astropy.io.ascii`` was updated to consistently + write the ``meta`` attribute as an ordered map using the ``!!omap`` tag. This + convention conforms to the ECSV specification and is supported by existing ECSV readers. + Previously the ``meta`` attribute could be written as an ordinary YAML map, which is not + guaranteed to preserve the order of the keys. [#16250] + +- An exception is now raised when trying to add a multi-dimensional column as an + index via ``Table.add_index``. [#16360] + +- Aggregating table groups for ``MaskedColumn`` no longer converts + fully masked groups to ``NaN``, but instead returns a masked element. [#16498] + +- Always use ``MaskedQuantity`` in ``QTable`` to represent masked ``Quantity`` + data or when the ``QTable`` is created with ``masked=True``. Previously the + default was to use a normal ``Quantity`` with a ``mask`` attribute of type + ``FalseArray`` as a stub to allow a minimal level of compatibility for certain + operations. This update brings more consistent behavior and fixes functions + like reading of table data from a list of dict that includes quantities with + missing entries, and aggregation of ``MaskedQuantity`` in table groups. [#16500] + +- Setting an empty table to a scalar no longer raises an exception, but + creates an empty column. This is to support cases where the number of + elements in a table is not known in advance, and could be zero. [#17102] + +- ``show_in_notebook`` method for Astropy tables has been un-deprecated and the API has + been updated to accept a ``backend`` keyword and require only keyword arguments. The new + default ``backend="ipydatagrid"`` relies on an optional dependency, ``ipydatagrid``. The + previous default table viewer (prior to v7.0) is still available as + ``backend="classic"``, but it has been deprecated since v6.1 and will be removed in a future release. [#17165] + +- The default behavior of ``Table.pformat`` was changed to include all rows and columns + instead of truncating the outputs to fit the current terminal. The new default + keyword arguments ``max_width=-1`` and ``max_lines=-1`` now match those in + ``Table.pformat_all``. Since the ``Table.pformat_all`` method is now redundant, it is + pending deprecation. Similarly, the default behavior of ``Column.pformat`` was changed + to include all rows instead of truncating the outputs to fit the current terminal. [#17184] + +astropy.time +^^^^^^^^^^^^ + +- ``Time.ptp`` now properly emits a deprecation warning independently of NumPy's + version. This method was previously deprecated in astropy 6.1, but the warning + was not visible for users that had NumPy 1.x installed. Because of this, the + warning message was updated to state that ``Time.ptp`` is deprecated since + version 7.0 instead. [#17212] + +astropy.units +^^^^^^^^^^^^^ + +- The deprecated ``Quantity.nansum()`` method has been removed. Use + ``np.nansum`` instead. [#15642] + +- The ``factor`` parameter of the ``spectral_density`` equivalency, the use of + which has been discouraged in the documentation since version 0.3, is now + deprecated. + Use the ``wav`` parameter as a ``Quantity``, not as a bare unit. [#16343] + +- The ``format.Fits`` formatter class has been renamed to ``format.FITS`` and the + old name is deprecated. + Specifying the FITS format for converting ``Quantity`` and ``UnitBase`` + instances to and from strings is not affected by this change. [#16455] + +- Conversion from one unit to another using ``old_unit.to(new_unit, value)`` no longer + converts ``value`` automatically to a numpy array, but passes through array duck types + such as ``dask`` arrays, with equivalencies properly accounted for. [#16613] + +- The ``format_exponential_notation()`` method of the ``Base`` unit formatter has + changed. + Any unit formatters that inherit directly from ``Base`` but have not + implemented their own ``format_exponential_notation()`` and wish to retain + previous behavior should implement it as: + + .. code-block:: python + + def format_exponential_notation(cls, val, format_spec): + return format(val, format_spec) + + Any formatters that inherit directly from ``Base`` and call + ``super().format_exponential_notation(val, format_spec)`` should instead call + ``format(val, format_spec)`` + The specific unit formatters in ``astropy.units`` and custom formatters that + inherit from any of them are not affected. [#16676] + +- The deprecated ``units.format.Unscaled`` has been removed. Use ``units.format.Generic`` + instead. [#16707] + +- Added a __round__() dunder method to ``Quantity`` + in order to support the built-in round() function. [#16784] + +- For ``Masked`` initialization in which a mask is passed in, ensure that that + mask is combined with any mask present on the input. [#16875] + +- The ``get_format_name()`` method of ``NamedUnit`` and its subclasses is + deprecated. + The ``to_string()`` method can be used instead. [#16958] + +- The ``UnitBase.in_units()`` method is deprecated. + The ``to()`` method can be used as a drop-in replacement. [#17121] + +- Unit conversions to a given system with ``unit.to_system()``, + ``unit.si``, and ``unit.cgs``, will now prefer the simplest unit if it + is in the given system, rather than prioritizing more complicated + units if those had a base unit component. E.g., ``u.Pa.si`` will now + simply return ``Unit("Pa")`` rather than ``Unit("N / m2")``. However, + the case where a unit can be simply described in base units remains + unchanged: ``u.Gal.cgs`` will still give ``Unit("cm / s2")``. [#17122] + +- The ``CDS``, ``OGIP`` and ``VOUnit`` unit formatters are now subclasses of the + ``FITS`` unit formatter. [#17178] + +- The ``eV`` and ``rydberg`` units were moved to ``astropy.units.misc`` (from + ``astropy.units.si`` and ``astropy.units.astrophys``, respectively). + Practically, this means that ``Unit.to_system(u.si)`` no longer includes + ``eV`` as a SI-compatible unit. [#17246] + +astropy.utils +^^^^^^^^^^^^^ + +- ``IERS_Auto.open()`` now always returns a table of type ``IERS_Auto`` that + contains the combination of IERS-A and IERS-B data, even if automatic + updating of the IERS-A file is disabled or if downloading the new file fails. + Previously, under those conditions, it would return a table of a different type + (``IERS_B``) with only IERS-B data. [#16187] + +- ``astropy.utils.check_broadcast`` is now deprecated in favor of + ``numpy.broadcast_shapes`` [#16346] + +- Added a new keyword ``pending_warning_type`` to ``deprecated`` decorator so downstream developers could customize the type of warning for pending deprecation state. [#16463] + +- The ``introspection.resolve_name()`` function is deprecated. + It is better to use the standard library ``importlib`` instead. [#16479] + +- ``format_exception()`` is deprecated because it provides little benefit, if + any, over normal Python tracebacks. [#16807] + +- The ``utils.masked`` module has gained a mixin class, ``MaskableShapedLikeNDArray``, + as well as two utility functions, ``get_data_and_mask`` and ``combine_masks``, + that can help make a container classes carry masked data. Within astropy, these + are now used in the implementation of masks for ``Time``. [#16844] + +- The deprecated ``compat.override__dir__()`` utility has been removed. [#17190] + +astropy.visualization +^^^^^^^^^^^^^^^^^^^^^ + +- Removed deprecated ``exp`` attribute in the ``LogStretch``, + ``InvertedLogStretch``, ``PowerDistStretch``, and + ``InvertedPowerDistStretch`` stretch classes, and the ``power`` + attribute in the ``PowerStretch``. Instead, use the ``a`` attribute, + which matches the input keyword. [#15751] + +- Removes the unintended NumPy export previously at ``astropy.visualization.np``. [#15781] + +- Accessing or setting the following attributes on ``CoordinateHelper`` has been deprecated: + + * ``ticks`` + * ``ticklabels`` + * ``axislabels`` + + Setting the following attributes on ``CoordinateHelper`` directly has been deprecated: + + * ``parent_axes`` + * ``parent_map`` + * ``transform`` + * ``coord_index`` + * ``coord_unit`` + * ``coord_type`` (use ``set_coord_type`` instead) + * ``coord_wrap`` (use ``set_coord_type`` instead) + * ``frame`` + * ``default_label`` + + Accessing or setting the following attributes on ``CoordinateHelper`` has been + removed (without deprecation, as these were clearly internal variables): + + * ``grid_lines_kwargs`` + * ``grid_lines`` + * ``lblinfo`` + * ``lbl_world`` + * ``minor_frequency`` (there were already public methods to set/get this) [#16685] + +- The deprecated ``nsamples`` parameter of ``ZScaleInterval`` is removed. [#17186] + +astropy.wcs +^^^^^^^^^^^ + +- Errors may now occur if a ``BaseLowLevelWCS`` class defines + ``world_axis_object_components`` which returns values that are not scalars or + plain Numpy arrays as per APE 14. [#16287] + +- ``WCS.pixel_to_world_values``, ``WCS.world_to_pixel_values``, + ``WCS.pixel_to_world`` and ``WCS.world_to_pixel`` now correctly return NaN values for + pixel positions that are outside of ``pixel_bounds``. [#16328] + + +Bug Fixes +--------- + +astropy.io.ascii +^^^^^^^^^^^^^^^^ + +- Fix the broken behavior of reading an ASCII table and filling values using column names. + This PR addresses the issue and improves the functionality. [#15774] + +astropy.io.fits +^^^^^^^^^^^^^^^ + +- Fix a number of bugs in ``CompImageHDU``: + + * Fix the ability to pickle ``CompImageHDU`` objects + * Ensure that compression settings are not lost if initializing ``CompImageHDU`` + without data but with compression settings and setting the data later + * Make sure that keywords are properly updated when setting the header of a + ``CompImageHDU`` to an existing image header. + * Fix the ability to use ``CompImageHDU.section`` on instances that have not yet + been written to disk + * Fix the image checksum/datasum in ``CompImageHDU.header`` to be those for the + image HDU instead of for the underlying binary table. [#15474] + +- Fix a spurious exception when reading integer compressed images with blanks. [#17099] + +- Fix creating ``CompImageHDU`` from header with BSCALE/BZERO: keywords are now + ignored, as done in ``ImageHDU``. [#17237] + +astropy.io.votable +^^^^^^^^^^^^^^^^^^ + +- Making the "votable.parquet" format available as a reader format to ensure + consistency with the writer formats, even though the format it recognised + automatically by "votable". [#16488] + +- Explicitly set ``usedforsecurity=False`` when using ``hashlib.md5``. Without this, ``hashlib.md5`` will be blocked in FIPS mode. + FIPS (Federal Information Processing Standards) is a set of standards created by NIST (National Institute of Standards and Technology) for US government agencies regarding computer security and interoperability. + This affects validation results ingestion. [#17156] + +astropy.modeling +^^^^^^^^^^^^^^^^ + +- Fixed the output representation of models with parameters that have + units of ``dimensionless_unscaled``. [#16829] + +astropy.stats +^^^^^^^^^^^^^ + +- Fixed accuracy of sigma clipping for large ``float32`` arrays when + ``bottleneck`` is installed. Performance may be impacted for computations + involving arrays with dtype other than ``float64``. This change has no impact + for environments that do not have ``bottleneck`` installed. [#17204] + +- Fix an issue in sigma-clipping where the use of ``np.copy()`` was causing + the input data mask to be discarded in cases where ``grow`` was set. [#17402] + +astropy.table +^^^^^^^^^^^^^ + +- Fix a bug where column names would be lost when instantiating ``Table`` from a list of ``Row`` objects. [#15735] + +- Aggregating table groups for ``MaskedColumn`` now ensures that fully-masked + groups result in masked elements rather than ``NaN``. [#16498] + +- Ensure that tables holding coordinates or representations can also be stacked + if they have zero length. This fix also ensures that the ``insert`` method + works correctly with a zero-length table holding a coordinate object. [#17380] + +- Fixed table aggregate with empty columns when float is present. [#17385] + +astropy.units +^^^^^^^^^^^^^ + +- Allow SI-prefixes for radioactivity units ``becquerel`` and ``curie`` in ``astropy.units.si``, conforming to BIPM's guidelines for SI units. [#16529] + +- The OGIP unit parser no longer accepts strings where a component unit is + followed by a parenthesized unit without a separator in between, such as + ``'m(s)'`` or ``'m(s)**2'``. + Such strings are not allowed by the OGIP standard. [#16749] + +- A few edge cases that could result in a power of a unit to be a numerical value + from ``numpy``, instead of the intended Python ``int``, ``float`` or + ``fractions.Fraction`` instance, have been fixed. [#16779] + +- The OGIP unit parser now detects negative powers that are not enclosed in + parenthesis. + For example, ``u.Unit("s**-1", format="ogip")`` now raises an error because the + OGIP standard expects the string to be written as ``"s**(-1)"`` instead, but it + is still possible to parse the unit with + ``u.Unit("s**-1", format="ogip", parse_strict="warn")`` or + ``parse_strict="silent"``. [#16788] + +- ``UnitScaleError`` can now be imported from the ``astropy.units`` namespace. [#16861] + +- Parsing custom units with ``u.Unit()`` using the ``"vounit"`` format now obeys + the ``parse_strict`` parameter, unless the custom units are made explicit with + quotation marks. + For example, ``u.Unit("custom_unit", format="vounit")`` now raises an error, + but ``u.Unit("custom_unit", format="vounit", parse_strict="silent")`` or + ``u.Unit("'custom_unit'", format="vounit")`` do not. [#17232] + +- It is now possible to use ``Unit`` to create dimensionless units with a scale + factor that is a complex number or a ``fractions.Fraction`` instance. + It was already possible to create such units directly with ``CompositeUnit``. [#17355] + +astropy.utils +^^^^^^^^^^^^^ + +- Fixed the unintended behavior where the IERS-A file bundled in ``astropy-iers-data`` would be ignored if automatic updating of the IERS-A file were disabled or if downloading the new file failed. [#16187] + +- Ensure ``MaskedQuantity`` can be initialized with a list of masked + quantities (as long as their shapes match), just like regular + ``Quantity`` and ``ndarray``. [#16503] + +- For ``Masked`` instances, ``np.put``, ``np.putmask``, ``np.place`` and + ``np.copyto`` can now handle putting/copying not just ``np.ma.masked`` but + also ``np.ma.nomask``; for both cases, only the mask of the relevant entries + will be set. [#17014] + +- Explicitly set ``usedforsecurity=False`` when using ``hashlib.md5``. Without this, ``hashlib.md5`` will be blocked in FIPS mode. + FIPS (Federal Information Processing Standards) is a set of standards created by NIST (National Institute of Standards and Technology) for US government agencies regarding computer security and interoperability. + This affects download caching. [#17156] + +- Fixed a bug where an old IERS-A table with stale predictive values could trigger + the download of a new IERS-A table even if automatic downloading was disabled. [#17387] + +astropy.wcs +^^^^^^^^^^^ + +- Avoid a ``RuntimeWarning`` in ``WCS.world_to_array_index`` by converting + NaN inputs to int. [#17236] + + +Performance Improvements +------------------------ + +astropy.io.ascii +^^^^^^^^^^^^^^^^ + +- The performance of guessing the table format when reading large files with + ``astropy.io.ascii`` has been improved. Now the process uses at most + 10000 lines of the file to check if it matches the format. This behavior can + be configured using the ``astropy.io.ascii.conf.guess_limit_lines`` + configuration item, including disabling the limit entirely. [#16840] + +astropy.io.fits +^^^^^^^^^^^^^^^ + +- Optimize checksum computation. [#17209] + +astropy.modeling +^^^^^^^^^^^^^^^^ + +- Improved the performance of 1D models, models with scalar parameters, and models + without units, when evaluating them with scalar or small arrays of inputs. For + models that satisfy all of the conditions above, the improvement can be on the + order of 30-40% in execution time. [#16670] + +- Performance of most non-linear fitters has been significantly improved by reducing the overhead in evaluating models inside the objective function. [#16673] + +- Improved the performance of ``parallel_fit_dask`` by avoiding unnecessary copies of the + model inside the fitter. [#17033] + +- ``CompoundModel`` now implements numerical derivatives of parameters when using the +, -, * or / operators. This improves the speed of fitting these models because numerical derivatives of the parameters are not calculated. [#17034] + +astropy.stats +^^^^^^^^^^^^^ + +- The performance of biweight_location, biweight_scale, + biweight_midvariance, and median_absolute_deviation has been improved by + using the bottleneck nan* functions when available. This requires the + bottleneck optional dependency to be installed. [#16967] + +astropy.units +^^^^^^^^^^^^^ + +- The ``units.quantity_input`` decorator has been optimized, especially in the case that no equivalencies are provided to the decorator, and the speed-up is very noticeable when wrapping short functions. [#16742] + +- Parsing composite units with the OGIP formatter is now up to 25% faster. [#16761] + +- Parsing units with scale factors is now up to 50% faster. [#16813] + +- Parsing strings representing non-composite units with ``Unit`` is now up to 25% + faster. [#17004] + +- Converting composite units to strings with the ``"cds"``, ``"fits"``, + ``"ogip"`` and ``"vounit"`` formatters is now at least twice as fast. [#17043] + +astropy.visualization +^^^^^^^^^^^^^^^^^^^^^ + +- Removed redundant transformations when WCSAxes determines the coordinate ranges + for ticks/gridlines, which speeds up typical plot generation by ~10%, and by + much more if ``astropy.visualization.wcsaxes.conf.coordinate_range_samples`` is + set to a large value [#16366] + + +Other Changes and Additions +--------------------------- + +- Updated minimum supported Python version to 3.11. As a result, minimum + requirements were updated to compatible versions. + Astropy now requires + - ``numpy>=1.23.2`` + - ``PyYAML>=6.0.0`` + - ``packaging>=22.0.0`` [#16903] + +- The minimum supported version of Pandas is now v2.0. + This is in line with https://scientific-python.org/specs/spec-0000/. [#16308] + +- Update minimal recommendation for matplotlib from version 3.3.4 to 3.6.0 [#16557] + +- The Contributor documentation has been significantly improved. It now includes a + Quickstart Guide with concise instructions on setting up a development environment and + making a pull request. In addition, the developer documentation was reorganized and + simplified where possible to improve readability and accessibility. [#16561] + +Version 6.1.7 (2024-11-22) +========================== + +Bug Fixes +--------- + +astropy.stats +^^^^^^^^^^^^^ + +- Fix an issue in sigma-clipping where the use of ``np.copy()`` was causing + the input data mask to be discarded in cases where ``grow`` was set. [#17402] + +Version 6.1.6 (2024-11-11) +========================== + +Bug Fixes +--------- + +astropy.coordinates +^^^^^^^^^^^^^^^^^^^ + +- Fixed instantiating ``Angle`` from a ``pandas`` ``Series`` object. [#17358] + +astropy.units +^^^^^^^^^^^^^ + +- Fixed calling ``np.nanvar`` and ``np.nanstd`` with ``Quantity`` ``out`` argument. [#17354] + + +Version 6.1.5 (2024-11-07) +========================== + +Bug Fixes +--------- + +astropy.coordinates +^^^^^^^^^^^^^^^^^^^ + +- Ensure that coordinates can be transformed to other coordinate frames + also if they have size zero (i.e., hold empty data arrays). [#17013] + +- ``Longitude`` and ``Latitude`` can no longer be initialized with strings + ending in "N" or "S", and "E" or "W", respectively, since those suggest + the other type. [#17132] + +- ``np.nanvar(angle)`` now produces a ``Quantity`` with the correct + unit, rather than raising an exception. [#17239] + +- Fix a crash when instantiating ``Angle`` (or ``Latitude``, or ``Longitude``) + from a non-numpy array (for instance pyarrow arrays). [#17263] + +astropy.io.fits +^^^^^^^^^^^^^^^ + +- Fix access to VLA columns after slicing ``.data``. [#16996] + +astropy.io.votable +^^^^^^^^^^^^^^^^^^ + +- Updated xml writer for VOTable Resource elements to include groups. [#17344] + +astropy.nddata +^^^^^^^^^^^^^^ + +- Add support for positional only and keyword only arguments when using the ``support_nddata`` decorator. [#17281] + +astropy.stats +^^^^^^^^^^^^^ + +- Fixed a bug where float32 inputs to sigma_clip and SigmaClip were + changed to float. [#17086] + +astropy.table +^^^^^^^^^^^^^ + +- Fix a crash when calling ``Column.pprint`` on a scalar column. [#15749] + +- Ensure that setting an existing column to a scalar always properly fills it + (rather than breaking the table if there was only one column in it). [#17105] + +astropy.units +^^^^^^^^^^^^^ + +- The unit parsers are now better at recognizing unusual composite + units: + + - units involving special unicode symbols, like "L☉/pc²"; + - units that include CDS units ending in a 0, like "eps0/s"; + - units including the degree symbol, "°". For example, "°C/s" is no + longer incorrectly interpreted as "°C/s^2". [#17011] + +- Converting the ohm to a string with the OGIP unit formatter (e.g. + ``f"{u.ohm:ogip}"``) previously produced the string ``'V / A'``, but now + produces ``'ohm'`` as expected. [#17200] + +- The ``OGIP`` unit formatter now handles the unit ``day`` and the corresponding + string ``"d"`` in full compliance with the standard. [#17216] + +- The ``"ogip"`` unit format now represents the unit angstrom as ``"angstrom"`` + instead of ``"0.1 nm"``. [#17241] + +astropy.utils +^^^^^^^^^^^^^ + +- Ensure that queries of ``.ut1_utc()`` and ``.pm_xy()`` return the correct + results also when passing in an empty array of times. [#17013] + +- Fixed a bug where astropy's logger wouldn't perform lazy string interpolation. [#17196] + +astropy.visualization +^^^^^^^^^^^^^^^^^^^^^ + +- Fixed a bug that caused ``CoordinateHelper.get_axislabel()`` to return an + empty string instead of the default label if no label has been explicitly + provided. [#17175] + +astropy.wcs +^^^^^^^^^^^ + +- Fixed a bug that caused ``WCS.slice`` to ignore ``numpy_order`` and always + interpret the slices as if ``numpy_order`` was ``True``, in the specific case + where the slices were such that dimensions in the WCS would be dropped. [#17147] + Version 6.1.4 (2024-09-26) ========================== diff --git a/README.rst b/README.rst index fd54e9ae752f..2a9241a09810 100644 --- a/README.rst +++ b/README.rst @@ -3,7 +3,9 @@ ---- |Actions Status| |CircleCI Status| |Coverage Status| |PyPI Status| |Documentation Status| |Pre-Commit| |Ruff| |Zenodo| + ---- + The Astropy Project is a community effort to develop a single core package for astronomy in Python and foster interoperability between packages used in the field. This repository contains the core library. @@ -30,13 +32,7 @@ For more detailed instructions, see the `install guide Contributing ============ -.. raw:: html - - - - - Astropy user statistics - +|User Stats| The Astropy Project is made both by and for its users, so we welcome and encourage contributions of many kinds. Our goal is to keep this a positive, @@ -89,6 +85,10 @@ Astropy is licensed under a 3-clause BSD style license - see the :target: https://www.astropy.org/ :alt: Astropy +.. |User Stats| image:: https://github.com/astropy/repo_stats/blob/cache/cache/astropy_user_stats_light.png + :target: https://docs.astropy.org/en/latest/impact_health.html + :alt: Astropy User Statistics + .. |Actions Status| image:: https://github.com/astropy/astropy/actions/workflows/ci_workflows.yml/badge.svg :target: https://github.com/astropy/astropy/actions :alt: Astropy's GitHub Actions CI Status diff --git a/astropy/config/configuration.py b/astropy/config/configuration.py index ecafcdef23df..1f310595a3a7 100644 --- a/astropy/config/configuration.py +++ b/astropy/config/configuration.py @@ -12,10 +12,12 @@ import contextlib import importlib import io +import operator import os import pkgutil import warnings from contextlib import contextmanager, nullcontext +from functools import reduce from pathlib import Path from textwrap import TextWrapper from warnings import warn @@ -632,6 +634,17 @@ def get_config(packageormod=None, reload=False, rootname=None): return cobj +def _recursive_subclasses(class_): + """ + Return all subclasses of all subclasses. + """ + subclasses = class_.__subclasses__() + if not subclasses: + return [] + next = reduce(operator.concat, [_recursive_subclasses(cls) for cls in subclasses]) + return [*next, *subclasses] + + def generate_config(pkgname="astropy", filename=None, verbose=False): """Generates a configuration file, from the list of `ConfigItem` objects for each subpackage. @@ -683,8 +696,7 @@ def generate_config(pkgname="astropy", filename=None, verbose=False): # assume it's a file object, or io.StringIO fp = filename - # Parse the subclasses, ordered by their module name - subclasses = ConfigNamespace.__subclasses__() + subclasses = _recursive_subclasses(ConfigNamespace) processed = set() for conf in sorted(subclasses, key=lambda x: x.__module__): diff --git a/astropy/config/paths.py b/astropy/config/paths.py index 21c3f71c7baf..0361e927808d 100644 --- a/astropy/config/paths.py +++ b/astropy/config/paths.py @@ -27,10 +27,9 @@ def _get_dir_path(rootname: str, cls: type, fallback: str) -> Path: path.mkdir(exist_ok=True) return path.resolve() - # first look for XDG_CONFIG_HOME if ( - (xdg_config_home := os.getenv("XDG_CONFIG_HOME")) is not None - and (xch := Path(xdg_config_home)).exists() + (xdg_dir := os.getenv(f"XDG_{fallback.upper()}_HOME")) is not None + and (xch := Path(xdg_dir)).exists() and not (xchpth := xch / rootname).is_symlink() ): if xchpth.exists(): diff --git a/astropy/config/tests/test_configs.py b/astropy/config/tests/test_configs.py index 99997fb78481..5b7e2c7ae93d 100644 --- a/astropy/config/tests/test_configs.py +++ b/astropy/config/tests/test_configs.py @@ -37,6 +37,21 @@ def test_paths(): assert "testpkg" in paths.get_cache_dir(rootname="testpkg") +@pytest.mark.parametrize( + "environment_variable,func", + [ + # Regression test for #17514 - XDG_CACHE_HOME had no effect + pytest.param("XDG_CACHE_HOME", paths.get_cache_dir_path, id="cache"), + pytest.param("XDG_CONFIG_HOME", paths.get_config_dir_path, id="config"), + ], +) +def test_xdg_variables(monkeypatch, tmp_path, environment_variable, func): + config_dir = tmp_path / "astropy" + config_dir.mkdir() + monkeypatch.setenv(environment_variable, str(tmp_path)) + assert func() == config_dir + + def test_set_temp_config(tmp_path, monkeypatch): # Check that we start in an understood state. assert configuration._cfgobjs == OLD_CONFIG @@ -153,7 +168,7 @@ def check_config(conf): assert "[table]" in conf assert "# replace_warnings = ," in conf assert "[table.jsviewer]" in conf - assert "# css_urls = https://cdn.datatables.net/1.10.12/css/jquery.dataTables.css," in conf # fmt: skip + assert "# css_urls = https://cdn.datatables.net/2.1.8/css/dataTables.dataTables.min.css" in conf # fmt: skip assert "[visualization.wcsaxes]" in conf assert "## Whether to log exceptions before raising them." in conf assert "# log_exceptions = False" in conf @@ -191,6 +206,29 @@ def test_generate_config2(tmp_path): check_config(conf) +def test_generate_config_subclasses(tmp_path): + """Test that generate_config works with subclasses of ConfigNamespace.""" + from astropy.config.configuration import ConfigItem, ConfigNamespace + + class MyPackageNamespace(ConfigNamespace): + pass + + class RecursiveTestConf(MyPackageNamespace): + ti = ConfigItem(5, "this is a Description") + + with set_temp_config(tmp_path): + from astropy.config.configuration import generate_config + + generate_config("astropy") + + assert os.path.exists(tmp_path / "astropy" / "astropy.cfg") + + with open(tmp_path / "astropy" / "astropy.cfg") as fp: + conf = fp.read() + + assert "# ti = 5" in conf + + def test_create_config_file(tmp_path, caplog): with set_temp_config(tmp_path): create_config_file("astropy") diff --git a/astropy/coordinates/angles/core.py b/astropy/coordinates/angles/core.py index 6d2ff95859e5..b91543a405db 100644 --- a/astropy/coordinates/angles/core.py +++ b/astropy/coordinates/angles/core.py @@ -180,9 +180,16 @@ def __new__(cls, angle, unit=None, dtype=np.inexact, copy=True, **kwargs): # Possible conversion to `unit` will be done below. angle = u.Quantity(angle, angle_unit, copy=COPY_IF_NEEDED) - elif isiterable(angle) and not ( - isinstance(angle, np.ndarray) and angle.dtype.kind not in "SUVO" + elif isinstance(angle, np.ndarray): + if angle.dtype.kind in "SUVO": + angle = [cls(x, unit, copy=COPY_IF_NEEDED) for x in angle] + + elif hasattr(angle, "__array__") and ( + not hasattr(angle, "dtype") or angle.dtype.kind not in "SUVO" ): + angle = np.asarray(angle) + + elif isiterable(angle): angle = [cls(x, unit, copy=COPY_IF_NEEDED) for x in angle] return super().__new__(cls, angle, unit, dtype=dtype, copy=copy, **kwargs) diff --git a/astropy/coordinates/baseframe.py b/astropy/coordinates/baseframe.py index 3a4348962ede..c69010f177cf 100644 --- a/astropy/coordinates/baseframe.py +++ b/astropy/coordinates/baseframe.py @@ -270,19 +270,17 @@ def new_like(self, coords, length, metadata_conflicts="warn", name=None): attrs = self.merge_cols_attributes( coords, metadata_conflicts, name, ("meta", "description") ) - coord0 = coords[0] - # Make a new coord object with the desired length and attributes - # by using the _apply / __getitem__ machinery to effectively return - # coord0[[0, 0, ..., 0, 0]]. This will have the all the right frame - # attributes with the right shape. - indexes = np.zeros(length, dtype=np.int64) - out = coord0[indexes] + # Make a new coordinate with the desired length. + coord0 = coords[0] + out = coord0._apply(np.zeros_like, shape=(length,) + coord0.shape[1:]) - # Use __setitem__ machinery to check for consistency of all coords + # Use __setitem__ machinery to check for consistency of all coords. + # We use :0 to ensure we do not break on empty coordinates (with the + # side benefit that we do not actually set anything). for coord in coords[1:]: try: - out[0] = coord[0] + out[:0] = coord[:0] except Exception as err: raise ValueError("Input coords are inconsistent.") from err diff --git a/astropy/coordinates/representation/base.py b/astropy/coordinates/representation/base.py index 0ab48b765ce7..0c58d3912d8b 100644 --- a/astropy/coordinates/representation/base.py +++ b/astropy/coordinates/representation/base.py @@ -50,6 +50,7 @@ class BaseRepresentationOrDifferentialInfo(MixinInfo): attrs_from_parent = {"unit"} # Indicates unit is read-only _supports_indexing = False + mask_val = np.ma.masked @staticmethod def default_format(val): @@ -104,18 +105,18 @@ def new_like(self, reps, length, metadata_conflicts="warn", name=None): attrs = self.merge_cols_attributes( reps, metadata_conflicts, name, ("meta", "description") ) - # Make a new representation or differential with the desired length - # using the _apply / __getitem__ machinery to effectively return - # rep0[[0, 0, ..., 0, 0]]. This will have the right shape, and - # include possible differentials. - indexes = np.zeros(length, dtype=np.int64) - out = reps[0][indexes] + + # Make a new representation or differential with the desired length. + rep0 = reps[0] + out = rep0._apply(np.zeros_like, shape=(length,) + rep0.shape[1:]) # Use __setitem__ machinery to check whether all representations # can represent themselves as this one without loss of information. + # We use :0 to ensure we do not break on empty coordinates (with the + # side benefit that we do not actually set anything). for rep in reps[1:]: try: - out[0] = rep[0] + out[:0] = rep[:0] except Exception as err: raise ValueError("input representations are inconsistent.") from err diff --git a/astropy/coordinates/representation/cylindrical.py b/astropy/coordinates/representation/cylindrical.py index acd9ab936953..013d5d6e2c98 100644 --- a/astropy/coordinates/representation/cylindrical.py +++ b/astropy/coordinates/representation/cylindrical.py @@ -144,7 +144,7 @@ def represent_as(self, other_class, differential_class=None): r = np.hypot(self.rho, self.z) return other_class( r=r, - theta=np.arccos(self.z / r), + theta=np.arctan2(self.rho, self.z), phi=self.phi, differentials=diffs, ) diff --git a/astropy/coordinates/tests/test_arrays.py b/astropy/coordinates/tests/test_arrays.py index c02cc9406df6..bbb0570c54fa 100644 --- a/astropy/coordinates/tests/test_arrays.py +++ b/astropy/coordinates/tests/test_arrays.py @@ -55,6 +55,29 @@ def test_angle_arrays(): Angle(["04:02:02", "03:02:01", "06:02:01"]) +def test_angle_from_pyarrow(): + # Creating Angle instances from some array classes (e.g. pyarrow.array) failed + # even though creating Quantity instances succeeded. + # see https://github.com/astropy/astropy/issues/17255 + pa = pytest.importorskip("pyarrow") + + input_data = [1.1, 2.2] + arr = pa.array(input_data) + angle = Angle(arr, "deg") + npt.assert_array_equal(angle.value, input_data) + + +def test_angle_from_pandas(): + # see https://github.com/astropy/astropy/issues/17357 + pd = pytest.importorskip("pandas") + + input_data = ["10 0 0", "12 0 0"] + df = pd.DataFrame({"angle": input_data}) + angle = Angle(df["angle"], unit=u.hourangle) + expected = Angle(input_data, u.hourangle) + npt.assert_array_equal(angle.value, expected.value) + + def test_dms(): a1 = Angle([0, 45.5, -45.5], unit=u.degree) d, m, s = a1.dms diff --git a/astropy/coordinates/tests/test_iau_fullstack.py b/astropy/coordinates/tests/test_iau_fullstack.py index bb162e5ac3a5..90ab5fe075f3 100644 --- a/astropy/coordinates/tests/test_iau_fullstack.py +++ b/astropy/coordinates/tests/test_iau_fullstack.py @@ -208,5 +208,6 @@ def test_future_altaz(): AstropyWarning, match="Tried to get polar motions for times after IERS data is valid.*", ), + iers.conf.set_temp("auto_max_age", None), ): SkyCoord(1 * u.deg, 2 * u.deg).transform_to(AltAz(location=location, obstime=t)) diff --git a/astropy/coordinates/tests/test_regression.py b/astropy/coordinates/tests/test_regression.py index e4ef4cdd1098..828b8f1ebe94 100644 --- a/astropy/coordinates/tests/test_regression.py +++ b/astropy/coordinates/tests/test_regression.py @@ -262,7 +262,8 @@ def test_regression_futuretimes_4302(): with ctx1, ctx2, ctx3: future_time = Time("2511-5-1") c = CIRS(1 * u.deg, 2 * u.deg, obstime=future_time) - c.transform_to(ITRS(obstime=future_time)) + with iers.conf.set_temp("auto_max_age", None): + c.transform_to(ITRS(obstime=future_time)) def test_regression_4996(): diff --git a/astropy/coordinates/tests/test_representation.py b/astropy/coordinates/tests/test_representation.py index b72ec2899514..09d4723399f0 100644 --- a/astropy/coordinates/tests/test_representation.py +++ b/astropy/coordinates/tests/test_representation.py @@ -1446,6 +1446,14 @@ def test_to_physicsspherical_at_the_origin(self): assert_allclose(sph.theta, 0 * u.deg) assert cyl.phi == 23.5 * u.deg # phi is preserved exactly + def test_to_physicsspherical_small_theta(self): + """Test that the transformation to physicsspherical is accurate for small theta.""" + cyl = CylindricalRepresentation(rho=1 * u.m, phi=10 * u.deg, z=1e8 * u.m) + got = cyl.represent_as(PhysicsSphericalRepresentation) + assert_allclose(got.r, 1e8 * u.m) + assert_allclose(got.phi, 10 * u.deg) + assert_allclose(got.theta, 1e-8 * u.rad) + class TestUnitSphericalCosLatDifferential: @pytest.mark.parametrize("matrix", list(matrices.values())) diff --git a/astropy/coordinates/tests/test_utils.py b/astropy/coordinates/tests/test_utils.py index 7ffd03ae94f3..513abf69f582 100644 --- a/astropy/coordinates/tests/test_utils.py +++ b/astropy/coordinates/tests/test_utils.py @@ -10,6 +10,7 @@ from astropy.coordinates.solar_system import get_body_barycentric_posvel from astropy.tests.helper import PYTEST_LT_8_0, assert_quantity_allclose from astropy.time import Time +from astropy.utils import iers from astropy.utils.exceptions import AstropyWarning @@ -24,7 +25,11 @@ def test_polar_motion_unsupported_dates(): with pytest.warns(AstropyWarning, match=msg.format("before")), ctx: get_polar_motion(Time("1900-01-01")) - with pytest.warns(AstropyWarning, match=msg.format("after")), ctx: + with ( + pytest.warns(AstropyWarning, match=msg.format("after")), + ctx, + iers.conf.set_temp("auto_max_age", None), + ): get_polar_motion(Time("2100-01-01")) diff --git a/astropy/cosmology/flrw/base.py b/astropy/cosmology/flrw/base.py index a640823bbaa6..ff00a0e77e6e 100644 --- a/astropy/cosmology/flrw/base.py +++ b/astropy/cosmology/flrw/base.py @@ -176,7 +176,7 @@ class FLRW(Cosmology, _ScaleFactor): provide three neutrino masses unless you are considering something like a sterile neutrino. - Ob0 : float or None, optional + Ob0 : float, optional Omega baryons: density of baryonic matter in units of the critical density at z=0. @@ -346,9 +346,9 @@ def Otot0(self) -> float: return self.Om0 + self.Ogamma0 + self.Onu0 + self.Ode0 + self.Ok0 @cached_property - def Odm0(self) -> float | None: + def Odm0(self) -> float: """Omega dark matter; dark matter density/critical density at z=0.""" - return None if self.Ob0 is None else (self.Om0 - self.Ob0) + return self.Om0 - self.Ob0 @cached_property def Ok0(self) -> float: @@ -505,11 +505,6 @@ def Ob(self, z): The density of baryonic matter relative to the critical density at each redshift. Returns `float` if the input is scalar. - - Raises - ------ - ValueError - If ``Ob0`` is `None`. """ z = aszarr(z) return self.Ob0 * (z + 1.0) ** 3 * self.inv_efunc(z) ** 2 @@ -533,21 +528,11 @@ def Odm(self, z): critical density at each redshift. Returns `float` if the input is scalar. - Raises - ------ - ValueError - If ``Ob0`` is `None`. - Notes ----- This does not include neutrinos, even if non-relativistic at the redshift of interest. """ - if self.Odm0 is None: - raise ValueError( - "Baryonic density not set for this cosmology, " - "unclear meaning of dark matter density" - ) z = aszarr(z) return self.Odm0 * (z + 1.0) ** 3 * self.inv_efunc(z) ** 2 diff --git a/astropy/cosmology/flrw/tests/test_base.py b/astropy/cosmology/flrw/tests/test_base.py index c5b4bbaa4cf6..39ea72f17762 100644 --- a/astropy/cosmology/flrw/tests/test_base.py +++ b/astropy/cosmology/flrw/tests/test_base.py @@ -125,11 +125,7 @@ def test_Odm0(self, cosmo_cls, cosmo): assert isinstance(cosmo_cls.Odm0, cached_property) # on the instance - assert ( - cosmo.Odm0 is None - if cosmo.Ob0 is None - else np.allclose(cosmo.Odm0, cosmo.Om0 - cosmo.Ob0) - ) + assert np.allclose(cosmo.Odm0, cosmo.Om0 - cosmo.Ob0) def test_Ok0(self, cosmo_cls, cosmo): """Test ``cached_property`` ``Ok0``.""" @@ -354,10 +350,7 @@ def test_clone_change_param(self, cosmo): assert c.H0.value == 100 for n, v in filter_keys_from_items(c.parameters, ("H0",)): v_expect = getattr(cosmo, n) - if v is None: - assert v is v_expect - else: - assert_quantity_allclose(v, v_expect, atol=1e-4 * getattr(v, "unit", 1)) + assert_quantity_allclose(v, v_expect, atol=1e-4 * getattr(v, "unit", 1)) assert not u.allclose(c.Ogamma0, cosmo.Ogamma0) assert not u.allclose(c.Onu0, cosmo.Onu0) @@ -370,10 +363,7 @@ def test_clone_change_param(self, cosmo): assert c.meta == {**cosmo.meta, **dict(zz="tops")} for n, v in filter_keys_from_items(c.parameters, ("H0", "Tcmb0")): v_expect = getattr(cosmo, n) - if v is None: - assert v is v_expect - else: - assert_quantity_allclose(v, v_expect, atol=1e-4 * getattr(v, "unit", 1)) + assert_quantity_allclose(v, v_expect, atol=1e-4 * getattr(v, "unit", 1)) assert not u.allclose(c.Ogamma0, cosmo.Ogamma0) assert not u.allclose(c.Onu0, cosmo.Onu0) assert not u.allclose(c.Tcmb0.value, cosmo.Tcmb0.value) diff --git a/astropy/cosmology/flrw/tests/test_w0cdm.py b/astropy/cosmology/flrw/tests/test_w0cdm.py index c9dae0626a8a..2d5bff18308c 100644 --- a/astropy/cosmology/flrw/tests/test_w0cdm.py +++ b/astropy/cosmology/flrw/tests/test_w0cdm.py @@ -81,10 +81,7 @@ def test_clone_change_param(self, cosmo): assert c.w0 == 0.1 for n, v in filter_keys_from_items(c.parameters, ("w0",)): v_expect = getattr(cosmo, n) - if v is None: - assert v is v_expect - else: - assert_quantity_allclose(v, v_expect, atol=1e-4 * getattr(v, "unit", 1)) + assert_quantity_allclose(v, v_expect, atol=1e-4 * getattr(v, "unit", 1)) @pytest.mark.parametrize("z", valid_zs) def test_w(self, cosmo, z): diff --git a/astropy/cosmology/flrw/tests/test_w0wacdm.py b/astropy/cosmology/flrw/tests/test_w0wacdm.py index fb44ca26ba6e..3ef0b8f68c15 100644 --- a/astropy/cosmology/flrw/tests/test_w0wacdm.py +++ b/astropy/cosmology/flrw/tests/test_w0wacdm.py @@ -82,10 +82,7 @@ def test_clone_change_param(self, cosmo): assert c.wa == 0.2 for n, v in filter_keys_from_items(c.parameters, ("w0", "wa")): v_expect = getattr(cosmo, n) - if v is None: - assert v is v_expect - else: - assert_quantity_allclose(v, v_expect, atol=1e-4 * getattr(v, "unit", 1)) + assert_quantity_allclose(v, v_expect, atol=1e-4 * getattr(v, "unit", 1)) # @pytest.mark.parametrize("z", valid_zs) # TODO! recompute comparisons below def test_w(self, cosmo): diff --git a/astropy/cosmology/flrw/tests/test_w0wzcdm.py b/astropy/cosmology/flrw/tests/test_w0wzcdm.py index 811094a30294..287dc8fb924b 100644 --- a/astropy/cosmology/flrw/tests/test_w0wzcdm.py +++ b/astropy/cosmology/flrw/tests/test_w0wzcdm.py @@ -88,12 +88,7 @@ def test_clone_change_param(self, cosmo): assert c.w0 == 0.1 assert c.wz == 0.2 for n, v in filter_keys_from_items(c.parameters, ("w0", "wz")): - if v is None: - assert v is getattr(cosmo, n) - else: - assert u.allclose( - v, getattr(cosmo, n), atol=1e-4 * getattr(v, "unit", 1) - ) + assert u.allclose(v, getattr(cosmo, n), atol=1e-4 * getattr(v, "unit", 1)) # @pytest.mark.parametrize("z", valid_zs) # TODO! recompute comparisons below def test_w(self, cosmo): diff --git a/astropy/cosmology/flrw/tests/test_wpwazpcdm.py b/astropy/cosmology/flrw/tests/test_wpwazpcdm.py index 3c9c73ee178c..88e56c4765a9 100644 --- a/astropy/cosmology/flrw/tests/test_wpwazpcdm.py +++ b/astropy/cosmology/flrw/tests/test_wpwazpcdm.py @@ -131,10 +131,7 @@ def test_clone_change_param(self, cosmo): assert c.zp == 14 for n, v in filter_keys_from_items(c.parameters, ("wp", "wa", "zp")): v_expect = getattr(cosmo, n) - if v is None: - assert v is v_expect - else: - assert_quantity_allclose(v, v_expect, atol=1e-4 * getattr(v, "unit", 1)) + assert_quantity_allclose(v, v_expect, atol=1e-4 * getattr(v, "unit", 1)) # @pytest.mark.parametrize("z", valid_zs) # TODO! recompute comparisons below def test_w(self, cosmo): diff --git a/astropy/cosmology/funcs/tests/test_funcs.py b/astropy/cosmology/funcs/tests/test_funcs.py index da6c8c824f2e..a9759b77450f 100644 --- a/astropy/cosmology/funcs/tests/test_funcs.py +++ b/astropy/cosmology/funcs/tests/test_funcs.py @@ -24,6 +24,7 @@ ) from astropy.tests.helper import PYTEST_LT_8_0 from astropy.units import allclose +from astropy.utils.compat import NUMPY_LT_2_3 from astropy.utils.compat.optional_deps import HAS_SCIPY from astropy.utils.exceptions import AstropyUserWarning @@ -166,6 +167,9 @@ def test_scalar_input_to_output(self): @pytest.mark.skipif(not HAS_SCIPY, reason="test requires scipy") +@pytest.mark.xfail( + not NUMPY_LT_2_3, reason="TODO fix: https://github.com/astropy/astropy/issues/18045" +) def test_z_at_value_numpyvectorize(): """Test that numpy vectorize fails on Quantities. diff --git a/astropy/extern/jquery/data/css/datatables.css b/astropy/extern/jquery/data/css/datatables.css new file mode 100644 index 000000000000..ca909dfd88ff --- /dev/null +++ b/astropy/extern/jquery/data/css/datatables.css @@ -0,0 +1,795 @@ +/* + * This combined file was created by the DataTables downloader builder: + * https://datatables.net/download + * + * To rebuild or modify this file with the latest versions of the included + * software please visit: + * https://datatables.net/download/#dt/dt-2.1.8 + * + * Included libraries: + * DataTables 2.1.8 + */ + +@charset "UTF-8"; +:root { + --dt-row-selected: 13, 110, 253; + --dt-row-selected-text: 255, 255, 255; + --dt-row-selected-link: 9, 10, 11; + --dt-row-stripe: 0, 0, 0; + --dt-row-hover: 0, 0, 0; + --dt-column-ordering: 0, 0, 0; + --dt-html-background: white; +} +:root.dark { + --dt-html-background: rgb(33, 37, 41); +} + +table.dataTable td.dt-control { + text-align: center; + cursor: pointer; +} +table.dataTable td.dt-control:before { + display: inline-block; + box-sizing: border-box; + content: ""; + border-top: 5px solid transparent; + border-left: 10px solid rgba(0, 0, 0, 0.5); + border-bottom: 5px solid transparent; + border-right: 0px solid transparent; +} +table.dataTable tr.dt-hasChild td.dt-control:before { + border-top: 10px solid rgba(0, 0, 0, 0.5); + border-left: 5px solid transparent; + border-bottom: 0px solid transparent; + border-right: 5px solid transparent; +} + +html.dark table.dataTable td.dt-control:before, +:root[data-bs-theme=dark] table.dataTable td.dt-control:before, +:root[data-theme=dark] table.dataTable td.dt-control:before { + border-left-color: rgba(255, 255, 255, 0.5); +} +html.dark table.dataTable tr.dt-hasChild td.dt-control:before, +:root[data-bs-theme=dark] table.dataTable tr.dt-hasChild td.dt-control:before, +:root[data-theme=dark] table.dataTable tr.dt-hasChild td.dt-control:before { + border-top-color: rgba(255, 255, 255, 0.5); + border-left-color: transparent; +} + +div.dt-scroll { + width: 100%; +} + +div.dt-scroll-body thead tr, +div.dt-scroll-body tfoot tr { + height: 0; +} +div.dt-scroll-body thead tr th, div.dt-scroll-body thead tr td, +div.dt-scroll-body tfoot tr th, +div.dt-scroll-body tfoot tr td { + height: 0 !important; + padding-top: 0px !important; + padding-bottom: 0px !important; + border-top-width: 0px !important; + border-bottom-width: 0px !important; +} +div.dt-scroll-body thead tr th div.dt-scroll-sizing, div.dt-scroll-body thead tr td div.dt-scroll-sizing, +div.dt-scroll-body tfoot tr th div.dt-scroll-sizing, +div.dt-scroll-body tfoot tr td div.dt-scroll-sizing { + height: 0 !important; + overflow: hidden !important; +} + +table.dataTable thead > tr > th:active, +table.dataTable thead > tr > td:active { + outline: none; +} +table.dataTable thead > tr > th.dt-orderable-asc span.dt-column-order:before, table.dataTable thead > tr > th.dt-ordering-asc span.dt-column-order:before, +table.dataTable thead > tr > td.dt-orderable-asc span.dt-column-order:before, +table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order:before { + position: absolute; + display: block; + bottom: 50%; + content: "▲"; + content: "▲"/""; +} +table.dataTable thead > tr > th.dt-orderable-desc span.dt-column-order:after, table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order:after, +table.dataTable thead > tr > td.dt-orderable-desc span.dt-column-order:after, +table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order:after { + position: absolute; + display: block; + top: 50%; + content: "▼"; + content: "▼"/""; +} +table.dataTable thead > tr > th.dt-orderable-asc, table.dataTable thead > tr > th.dt-orderable-desc, table.dataTable thead > tr > th.dt-ordering-asc, table.dataTable thead > tr > th.dt-ordering-desc, +table.dataTable thead > tr > td.dt-orderable-asc, +table.dataTable thead > tr > td.dt-orderable-desc, +table.dataTable thead > tr > td.dt-ordering-asc, +table.dataTable thead > tr > td.dt-ordering-desc { + position: relative; + padding-right: 30px; +} +table.dataTable thead > tr > th.dt-orderable-asc span.dt-column-order, table.dataTable thead > tr > th.dt-orderable-desc span.dt-column-order, table.dataTable thead > tr > th.dt-ordering-asc span.dt-column-order, table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order, +table.dataTable thead > tr > td.dt-orderable-asc span.dt-column-order, +table.dataTable thead > tr > td.dt-orderable-desc span.dt-column-order, +table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order, +table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order { + position: absolute; + right: 12px; + top: 0; + bottom: 0; + width: 12px; +} +table.dataTable thead > tr > th.dt-orderable-asc span.dt-column-order:before, table.dataTable thead > tr > th.dt-orderable-asc span.dt-column-order:after, table.dataTable thead > tr > th.dt-orderable-desc span.dt-column-order:before, table.dataTable thead > tr > th.dt-orderable-desc span.dt-column-order:after, table.dataTable thead > tr > th.dt-ordering-asc span.dt-column-order:before, table.dataTable thead > tr > th.dt-ordering-asc span.dt-column-order:after, table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order:before, table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order:after, +table.dataTable thead > tr > td.dt-orderable-asc span.dt-column-order:before, +table.dataTable thead > tr > td.dt-orderable-asc span.dt-column-order:after, +table.dataTable thead > tr > td.dt-orderable-desc span.dt-column-order:before, +table.dataTable thead > tr > td.dt-orderable-desc span.dt-column-order:after, +table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order:before, +table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order:after, +table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order:before, +table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order:after { + left: 0; + opacity: 0.125; + line-height: 9px; + font-size: 0.8em; +} +table.dataTable thead > tr > th.dt-orderable-asc, table.dataTable thead > tr > th.dt-orderable-desc, +table.dataTable thead > tr > td.dt-orderable-asc, +table.dataTable thead > tr > td.dt-orderable-desc { + cursor: pointer; +} +table.dataTable thead > tr > th.dt-orderable-asc:hover, table.dataTable thead > tr > th.dt-orderable-desc:hover, +table.dataTable thead > tr > td.dt-orderable-asc:hover, +table.dataTable thead > tr > td.dt-orderable-desc:hover { + outline: 2px solid rgba(0, 0, 0, 0.05); + outline-offset: -2px; +} +table.dataTable thead > tr > th.dt-ordering-asc span.dt-column-order:before, table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order:after, +table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order:before, +table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order:after { + opacity: 0.6; +} +table.dataTable thead > tr > th.sorting_desc_disabled span.dt-column-order:after, table.dataTable thead > tr > th.sorting_asc_disabled span.dt-column-order:before, +table.dataTable thead > tr > td.sorting_desc_disabled span.dt-column-order:after, +table.dataTable thead > tr > td.sorting_asc_disabled span.dt-column-order:before { + display: none; +} +table.dataTable thead > tr > th:active, +table.dataTable thead > tr > td:active { + outline: none; +} + +div.dt-scroll-body > table.dataTable > thead > tr > th, +div.dt-scroll-body > table.dataTable > thead > tr > td { + overflow: hidden; +} + +:root.dark table.dataTable thead > tr > th.dt-orderable-asc:hover, :root.dark table.dataTable thead > tr > th.dt-orderable-desc:hover, +:root.dark table.dataTable thead > tr > td.dt-orderable-asc:hover, +:root.dark table.dataTable thead > tr > td.dt-orderable-desc:hover, +:root[data-bs-theme=dark] table.dataTable thead > tr > th.dt-orderable-asc:hover, +:root[data-bs-theme=dark] table.dataTable thead > tr > th.dt-orderable-desc:hover, +:root[data-bs-theme=dark] table.dataTable thead > tr > td.dt-orderable-asc:hover, +:root[data-bs-theme=dark] table.dataTable thead > tr > td.dt-orderable-desc:hover { + outline: 2px solid rgba(255, 255, 255, 0.05); +} + +div.dt-processing { + position: absolute; + top: 50%; + left: 50%; + width: 200px; + margin-left: -100px; + margin-top: -22px; + text-align: center; + padding: 2px; + z-index: 10; +} +div.dt-processing > div:last-child { + position: relative; + width: 80px; + height: 15px; + margin: 1em auto; +} +div.dt-processing > div:last-child > div { + position: absolute; + top: 0; + width: 13px; + height: 13px; + border-radius: 50%; + background: rgb(13, 110, 253); + background: rgb(var(--dt-row-selected)); + animation-timing-function: cubic-bezier(0, 1, 1, 0); +} +div.dt-processing > div:last-child > div:nth-child(1) { + left: 8px; + animation: datatables-loader-1 0.6s infinite; +} +div.dt-processing > div:last-child > div:nth-child(2) { + left: 8px; + animation: datatables-loader-2 0.6s infinite; +} +div.dt-processing > div:last-child > div:nth-child(3) { + left: 32px; + animation: datatables-loader-2 0.6s infinite; +} +div.dt-processing > div:last-child > div:nth-child(4) { + left: 56px; + animation: datatables-loader-3 0.6s infinite; +} + +@keyframes datatables-loader-1 { + 0% { + transform: scale(0); + } + 100% { + transform: scale(1); + } +} +@keyframes datatables-loader-3 { + 0% { + transform: scale(1); + } + 100% { + transform: scale(0); + } +} +@keyframes datatables-loader-2 { + 0% { + transform: translate(0, 0); + } + 100% { + transform: translate(24px, 0); + } +} +table.dataTable.nowrap th, table.dataTable.nowrap td { + white-space: nowrap; +} +table.dataTable th, +table.dataTable td { + box-sizing: border-box; +} +table.dataTable th.dt-left, +table.dataTable td.dt-left { + text-align: left; +} +table.dataTable th.dt-center, +table.dataTable td.dt-center { + text-align: center; +} +table.dataTable th.dt-right, +table.dataTable td.dt-right { + text-align: right; +} +table.dataTable th.dt-justify, +table.dataTable td.dt-justify { + text-align: justify; +} +table.dataTable th.dt-nowrap, +table.dataTable td.dt-nowrap { + white-space: nowrap; +} +table.dataTable th.dt-empty, +table.dataTable td.dt-empty { + text-align: center; + vertical-align: top; +} +table.dataTable th.dt-type-numeric, table.dataTable th.dt-type-date, +table.dataTable td.dt-type-numeric, +table.dataTable td.dt-type-date { + text-align: right; +} +table.dataTable thead th, +table.dataTable thead td, +table.dataTable tfoot th, +table.dataTable tfoot td { + text-align: left; +} +table.dataTable thead th.dt-head-left, +table.dataTable thead td.dt-head-left, +table.dataTable tfoot th.dt-head-left, +table.dataTable tfoot td.dt-head-left { + text-align: left; +} +table.dataTable thead th.dt-head-center, +table.dataTable thead td.dt-head-center, +table.dataTable tfoot th.dt-head-center, +table.dataTable tfoot td.dt-head-center { + text-align: center; +} +table.dataTable thead th.dt-head-right, +table.dataTable thead td.dt-head-right, +table.dataTable tfoot th.dt-head-right, +table.dataTable tfoot td.dt-head-right { + text-align: right; +} +table.dataTable thead th.dt-head-justify, +table.dataTable thead td.dt-head-justify, +table.dataTable tfoot th.dt-head-justify, +table.dataTable tfoot td.dt-head-justify { + text-align: justify; +} +table.dataTable thead th.dt-head-nowrap, +table.dataTable thead td.dt-head-nowrap, +table.dataTable tfoot th.dt-head-nowrap, +table.dataTable tfoot td.dt-head-nowrap { + white-space: nowrap; +} +table.dataTable tbody th.dt-body-left, +table.dataTable tbody td.dt-body-left { + text-align: left; +} +table.dataTable tbody th.dt-body-center, +table.dataTable tbody td.dt-body-center { + text-align: center; +} +table.dataTable tbody th.dt-body-right, +table.dataTable tbody td.dt-body-right { + text-align: right; +} +table.dataTable tbody th.dt-body-justify, +table.dataTable tbody td.dt-body-justify { + text-align: justify; +} +table.dataTable tbody th.dt-body-nowrap, +table.dataTable tbody td.dt-body-nowrap { + white-space: nowrap; +} + +/* + * Table styles + */ +table.dataTable { + width: 100%; + margin: 0 auto; + border-spacing: 0; + /* + * Header and footer styles + */ + /* + * Body styles + */ +} +table.dataTable thead th, +table.dataTable tfoot th { + font-weight: bold; +} +table.dataTable > thead > tr > th, +table.dataTable > thead > tr > td { + padding: 10px; + border-bottom: 1px solid rgba(0, 0, 0, 0.3); +} +table.dataTable > thead > tr > th:active, +table.dataTable > thead > tr > td:active { + outline: none; +} +table.dataTable > tfoot > tr > th, +table.dataTable > tfoot > tr > td { + border-top: 1px solid rgba(0, 0, 0, 0.3); + padding: 10px 10px 6px 10px; +} +table.dataTable > tbody > tr { + background-color: transparent; +} +table.dataTable > tbody > tr:first-child > * { + border-top: none; +} +table.dataTable > tbody > tr:last-child > * { + border-bottom: none; +} +table.dataTable > tbody > tr.selected > * { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.9); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.9); + color: rgb(255, 255, 255); + color: rgb(var(--dt-row-selected-text)); +} +table.dataTable > tbody > tr.selected a { + color: rgb(9, 10, 11); + color: rgb(var(--dt-row-selected-link)); +} +table.dataTable > tbody > tr > th, +table.dataTable > tbody > tr > td { + padding: 8px 10px; +} +table.dataTable.row-border > tbody > tr > *, table.dataTable.display > tbody > tr > * { + border-top: 1px solid rgba(0, 0, 0, 0.15); +} +table.dataTable.row-border > tbody > tr:first-child > *, table.dataTable.display > tbody > tr:first-child > * { + border-top: none; +} +table.dataTable.row-border > tbody > tr.selected + tr.selected > td, table.dataTable.display > tbody > tr.selected + tr.selected > td { + border-top-color: rgba(13, 110, 253, 0.65); + border-top-color: rgba(var(--dt-row-selected), 0.65); +} +table.dataTable.cell-border > tbody > tr > * { + border-top: 1px solid rgba(0, 0, 0, 0.15); + border-right: 1px solid rgba(0, 0, 0, 0.15); +} +table.dataTable.cell-border > tbody > tr > *:first-child { + border-left: 1px solid rgba(0, 0, 0, 0.15); +} +table.dataTable.cell-border > tbody > tr:first-child > * { + border-top: 1px solid rgba(0, 0, 0, 0.3); +} +table.dataTable.stripe > tbody > tr:nth-child(odd) > *, table.dataTable.display > tbody > tr:nth-child(odd) > * { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.023); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-stripe), 0.023); +} +table.dataTable.stripe > tbody > tr:nth-child(odd).selected > *, table.dataTable.display > tbody > tr:nth-child(odd).selected > * { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.923); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.923); +} +table.dataTable.hover > tbody > tr:hover > *, table.dataTable.display > tbody > tr:hover > * { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.035); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-hover), 0.035); +} +table.dataTable.hover > tbody > tr.selected:hover > *, table.dataTable.display > tbody > tr.selected:hover > * { + box-shadow: inset 0 0 0 9999px #0d6efd !important; + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 1) !important; +} +table.dataTable.order-column > tbody tr > .sorting_1, +table.dataTable.order-column > tbody tr > .sorting_2, +table.dataTable.order-column > tbody tr > .sorting_3, table.dataTable.display > tbody tr > .sorting_1, +table.dataTable.display > tbody tr > .sorting_2, +table.dataTable.display > tbody tr > .sorting_3 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.019); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.019); +} +table.dataTable.order-column > tbody tr.selected > .sorting_1, +table.dataTable.order-column > tbody tr.selected > .sorting_2, +table.dataTable.order-column > tbody tr.selected > .sorting_3, table.dataTable.display > tbody tr.selected > .sorting_1, +table.dataTable.display > tbody tr.selected > .sorting_2, +table.dataTable.display > tbody tr.selected > .sorting_3 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.919); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.919); +} +table.dataTable.display > tbody > tr:nth-child(odd) > .sorting_1, table.dataTable.order-column.stripe > tbody > tr:nth-child(odd) > .sorting_1 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.054); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.054); +} +table.dataTable.display > tbody > tr:nth-child(odd) > .sorting_2, table.dataTable.order-column.stripe > tbody > tr:nth-child(odd) > .sorting_2 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.047); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.047); +} +table.dataTable.display > tbody > tr:nth-child(odd) > .sorting_3, table.dataTable.order-column.stripe > tbody > tr:nth-child(odd) > .sorting_3 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.039); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.039); +} +table.dataTable.display > tbody > tr:nth-child(odd).selected > .sorting_1, table.dataTable.order-column.stripe > tbody > tr:nth-child(odd).selected > .sorting_1 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.954); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.954); +} +table.dataTable.display > tbody > tr:nth-child(odd).selected > .sorting_2, table.dataTable.order-column.stripe > tbody > tr:nth-child(odd).selected > .sorting_2 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.947); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.947); +} +table.dataTable.display > tbody > tr:nth-child(odd).selected > .sorting_3, table.dataTable.order-column.stripe > tbody > tr:nth-child(odd).selected > .sorting_3 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.939); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.939); +} +table.dataTable.display > tbody > tr.even > .sorting_1, table.dataTable.order-column.stripe > tbody > tr.even > .sorting_1 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.019); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.019); +} +table.dataTable.display > tbody > tr.even > .sorting_2, table.dataTable.order-column.stripe > tbody > tr.even > .sorting_2 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.011); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.011); +} +table.dataTable.display > tbody > tr.even > .sorting_3, table.dataTable.order-column.stripe > tbody > tr.even > .sorting_3 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.003); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.003); +} +table.dataTable.display > tbody > tr.even.selected > .sorting_1, table.dataTable.order-column.stripe > tbody > tr.even.selected > .sorting_1 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.919); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.919); +} +table.dataTable.display > tbody > tr.even.selected > .sorting_2, table.dataTable.order-column.stripe > tbody > tr.even.selected > .sorting_2 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.911); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.911); +} +table.dataTable.display > tbody > tr.even.selected > .sorting_3, table.dataTable.order-column.stripe > tbody > tr.even.selected > .sorting_3 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.903); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.903); +} +table.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.082); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-hover), 0.082); +} +table.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.074); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-hover), 0.074); +} +table.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.062); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-hover), 0.062); +} +table.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.982); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.982); +} +table.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.974); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.974); +} +table.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.962); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.962); +} +table.dataTable.compact thead th, +table.dataTable.compact thead td, +table.dataTable.compact tfoot th, +table.dataTable.compact tfoot td, +table.dataTable.compact tbody th, +table.dataTable.compact tbody td { + padding: 4px; +} + +div.dt-container div.dt-layout-row { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + margin: 0.75em 0; +} +div.dt-container div.dt-layout-row div.dt-layout-cell { + display: flex; + justify-content: space-between; + align-items: center; +} +div.dt-container div.dt-layout-row div.dt-layout-cell.dt-layout-start { + justify-content: flex-start; + margin-right: auto; +} +div.dt-container div.dt-layout-row div.dt-layout-cell.dt-layout-end { + justify-content: flex-end; + margin-left: auto; +} +div.dt-container div.dt-layout-row div.dt-layout-cell:empty { + display: none; +} + +@media screen and (max-width: 767px) { + div.dt-container div.dt-layout-row:not(.dt-layout-table) { + display: block; + } + div.dt-container div.dt-layout-row:not(.dt-layout-table) div.dt-layout-cell { + display: block; + text-align: center; + } + div.dt-container div.dt-layout-row:not(.dt-layout-table) div.dt-layout-cell > * { + margin: 0.5em 0; + } + div.dt-container div.dt-layout-row:not(.dt-layout-table) div.dt-layout-cell.dt-layout-start { + margin-right: 0; + } + div.dt-container div.dt-layout-row:not(.dt-layout-table) div.dt-layout-cell.dt-layout-end { + margin-left: 0; + } +} +div.dt-container div.dt-layout-start > *:not(:last-child) { + margin-right: 1em; +} +div.dt-container div.dt-layout-end > *:not(:first-child) { + margin-left: 1em; +} +div.dt-container div.dt-layout-full { + width: 100%; +} +div.dt-container div.dt-layout-full > *:only-child { + margin-left: auto; + margin-right: auto; +} +div.dt-container div.dt-layout-table > div { + display: block !important; +} + +@media screen and (max-width: 767px) { + div.dt-container div.dt-layout-start > *:not(:last-child) { + margin-right: 0; + } + div.dt-container div.dt-layout-end > *:not(:first-child) { + margin-left: 0; + } +} +/* + * Control feature layout + */ +div.dt-container { + position: relative; + clear: both; +} +div.dt-container .dt-search input { + border: 1px solid #aaa; + border-radius: 3px; + padding: 5px; + background-color: transparent; + color: inherit; + margin-left: 3px; +} +div.dt-container .dt-input { + border: 1px solid #aaa; + border-radius: 3px; + padding: 5px; + background-color: transparent; + color: inherit; +} +div.dt-container select.dt-input { + padding: 4px; +} +div.dt-container .dt-paging .dt-paging-button { + box-sizing: border-box; + display: inline-block; + min-width: 1.5em; + padding: 0.5em 1em; + margin-left: 2px; + text-align: center; + text-decoration: none !important; + cursor: pointer; + color: inherit !important; + border: 1px solid transparent; + border-radius: 2px; + background: transparent; +} +div.dt-container .dt-paging .dt-paging-button.current, div.dt-container .dt-paging .dt-paging-button.current:hover { + color: inherit !important; + border: 1px solid rgba(0, 0, 0, 0.3); + background-color: rgba(0, 0, 0, 0.05); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(230, 230, 230, 0.05)), color-stop(100%, rgba(0, 0, 0, 0.05))); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, rgba(230, 230, 230, 0.05) 0%, rgba(0, 0, 0, 0.05) 100%); /* Chrome10+,Safari5.1+ */ + background: -moz-linear-gradient(top, rgba(230, 230, 230, 0.05) 0%, rgba(0, 0, 0, 0.05) 100%); /* FF3.6+ */ + background: -ms-linear-gradient(top, rgba(230, 230, 230, 0.05) 0%, rgba(0, 0, 0, 0.05) 100%); /* IE10+ */ + background: -o-linear-gradient(top, rgba(230, 230, 230, 0.05) 0%, rgba(0, 0, 0, 0.05) 100%); /* Opera 11.10+ */ + background: linear-gradient(to bottom, rgba(230, 230, 230, 0.05) 0%, rgba(0, 0, 0, 0.05) 100%); /* W3C */ +} +div.dt-container .dt-paging .dt-paging-button.disabled, div.dt-container .dt-paging .dt-paging-button.disabled:hover, div.dt-container .dt-paging .dt-paging-button.disabled:active { + cursor: default; + color: rgba(0, 0, 0, 0.5) !important; + border: 1px solid transparent; + background: transparent; + box-shadow: none; +} +div.dt-container .dt-paging .dt-paging-button:hover { + color: white !important; + border: 1px solid #111; + background-color: #111; + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #585858 0%, #111 100%); /* Chrome10+,Safari5.1+ */ + background: -moz-linear-gradient(top, #585858 0%, #111 100%); /* FF3.6+ */ + background: -ms-linear-gradient(top, #585858 0%, #111 100%); /* IE10+ */ + background: -o-linear-gradient(top, #585858 0%, #111 100%); /* Opera 11.10+ */ + background: linear-gradient(to bottom, #585858 0%, #111 100%); /* W3C */ +} +div.dt-container .dt-paging .dt-paging-button:active { + outline: none; + background-color: #0c0c0c; + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); /* Chrome10+,Safari5.1+ */ + background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); /* FF3.6+ */ + background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); /* IE10+ */ + background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); /* Opera 11.10+ */ + background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%); /* W3C */ + box-shadow: inset 0 0 3px #111; +} +div.dt-container .dt-paging .ellipsis { + padding: 0 1em; +} +div.dt-container .dt-length, +div.dt-container .dt-search, +div.dt-container .dt-info, +div.dt-container .dt-processing, +div.dt-container .dt-paging { + color: inherit; +} +div.dt-container .dataTables_scroll { + clear: both; +} +div.dt-container .dataTables_scroll div.dt-scroll-body { + -webkit-overflow-scrolling: touch; +} +div.dt-container .dataTables_scroll div.dt-scroll-body > table > thead > tr > th, div.dt-container .dataTables_scroll div.dt-scroll-body > table > thead > tr > td, div.dt-container .dataTables_scroll div.dt-scroll-body > table > tbody > tr > th, div.dt-container .dataTables_scroll div.dt-scroll-body > table > tbody > tr > td { + vertical-align: middle; +} +div.dt-container .dataTables_scroll div.dt-scroll-body > table > thead > tr > th > div.dataTables_sizing, +div.dt-container .dataTables_scroll div.dt-scroll-body > table > thead > tr > td > div.dataTables_sizing, div.dt-container .dataTables_scroll div.dt-scroll-body > table > tbody > tr > th > div.dataTables_sizing, +div.dt-container .dataTables_scroll div.dt-scroll-body > table > tbody > tr > td > div.dataTables_sizing { + height: 0; + overflow: hidden; + margin: 0 !important; + padding: 0 !important; +} +div.dt-container.dt-empty-footer tbody > tr:last-child > * { + border-bottom: 1px solid rgba(0, 0, 0, 0.3); +} +div.dt-container.dt-empty-footer .dt-scroll-body { + border-bottom: 1px solid rgba(0, 0, 0, 0.3); +} +div.dt-container.dt-empty-footer .dt-scroll-body tbody > tr:last-child > * { + border-bottom: none; +} + +html.dark { + --dt-row-hover: 255, 255, 255; + --dt-row-stripe: 255, 255, 255; + --dt-column-ordering: 255, 255, 255; +} +html.dark table.dataTable > thead > tr > th, +html.dark table.dataTable > thead > tr > td { + border-bottom: 1px solid rgb(89, 91, 94); +} +html.dark table.dataTable > thead > tr > th:active, +html.dark table.dataTable > thead > tr > td:active { + outline: none; +} +html.dark table.dataTable > tfoot > tr > th, +html.dark table.dataTable > tfoot > tr > td { + border-top: 1px solid rgb(89, 91, 94); +} +html.dark table.dataTable.row-border > tbody > tr > *, html.dark table.dataTable.display > tbody > tr > * { + border-top: 1px solid rgb(64, 67, 70); +} +html.dark table.dataTable.row-border > tbody > tr:first-child > *, html.dark table.dataTable.display > tbody > tr:first-child > * { + border-top: none; +} +html.dark table.dataTable.row-border > tbody > tr.selected + tr.selected > td, html.dark table.dataTable.display > tbody > tr.selected + tr.selected > td { + border-top-color: rgba(13, 110, 253, 0.65); + border-top-color: rgba(var(--dt-row-selected), 0.65); +} +html.dark table.dataTable.cell-border > tbody > tr > th, +html.dark table.dataTable.cell-border > tbody > tr > td { + border-top: 1px solid rgb(64, 67, 70); + border-right: 1px solid rgb(64, 67, 70); +} +html.dark table.dataTable.cell-border > tbody > tr > th:first-child, +html.dark table.dataTable.cell-border > tbody > tr > td:first-child { + border-left: 1px solid rgb(64, 67, 70); +} +html.dark .dt-container.dt-empty-footer table.dataTable { + border-bottom: 1px solid rgb(89, 91, 94); +} +html.dark .dt-container .dt-search input, +html.dark .dt-container .dt-length select { + border: 1px solid rgba(255, 255, 255, 0.2); + background-color: var(--dt-html-background); +} +html.dark .dt-container .dt-paging .dt-paging-button.current, html.dark .dt-container .dt-paging .dt-paging-button.current:hover { + border: 1px solid rgb(89, 91, 94); + background: rgba(255, 255, 255, 0.15); +} +html.dark .dt-container .dt-paging .dt-paging-button.disabled, html.dark .dt-container .dt-paging .dt-paging-button.disabled:hover, html.dark .dt-container .dt-paging .dt-paging-button.disabled:active { + color: #666 !important; +} +html.dark .dt-container .dt-paging .dt-paging-button:hover { + border: 1px solid rgb(53, 53, 53); + background: rgb(53, 53, 53); +} +html.dark .dt-container .dt-paging .dt-paging-button:active { + background: #3a3a3a; +} + +/* + * Overrides for RTL support + */ +*[dir=rtl] table.dataTable thead th, +*[dir=rtl] table.dataTable thead td, +*[dir=rtl] table.dataTable tfoot th, +*[dir=rtl] table.dataTable tfoot td { + text-align: right; +} +*[dir=rtl] table.dataTable th.dt-type-numeric, *[dir=rtl] table.dataTable th.dt-type-date, +*[dir=rtl] table.dataTable td.dt-type-numeric, +*[dir=rtl] table.dataTable td.dt-type-date { + text-align: left; +} +*[dir=rtl] div.dt-container div.dt-layout-cell.dt-start { + text-align: right; +} +*[dir=rtl] div.dt-container div.dt-layout-cell.dt-end { + text-align: left; +} +*[dir=rtl] div.dt-container div.dt-search input { + margin: 0 3px 0 0; +} + + diff --git a/astropy/extern/jquery/data/css/datatables.min.css b/astropy/extern/jquery/data/css/datatables.min.css new file mode 100644 index 000000000000..f3b17f546a92 --- /dev/null +++ b/astropy/extern/jquery/data/css/datatables.min.css @@ -0,0 +1,15 @@ +/* + * This combined file was created by the DataTables downloader builder: + * https://datatables.net/download + * + * To rebuild or modify this file with the latest versions of the included + * software please visit: + * https://datatables.net/download/#dt/dt-2.1.8 + * + * Included libraries: + * DataTables 2.1.8 + */ + +:root{--dt-row-selected: 13, 110, 253;--dt-row-selected-text: 255, 255, 255;--dt-row-selected-link: 9, 10, 11;--dt-row-stripe: 0, 0, 0;--dt-row-hover: 0, 0, 0;--dt-column-ordering: 0, 0, 0;--dt-html-background: white}:root.dark{--dt-html-background: rgb(33, 37, 41)}table.dataTable td.dt-control{text-align:center;cursor:pointer}table.dataTable td.dt-control:before{display:inline-block;box-sizing:border-box;content:"";border-top:5px solid transparent;border-left:10px solid rgba(0, 0, 0, 0.5);border-bottom:5px solid transparent;border-right:0px solid transparent}table.dataTable tr.dt-hasChild td.dt-control:before{border-top:10px solid rgba(0, 0, 0, 0.5);border-left:5px solid transparent;border-bottom:0px solid transparent;border-right:5px solid transparent}html.dark table.dataTable td.dt-control:before,:root[data-bs-theme=dark] table.dataTable td.dt-control:before,:root[data-theme=dark] table.dataTable td.dt-control:before{border-left-color:rgba(255, 255, 255, 0.5)}html.dark table.dataTable tr.dt-hasChild td.dt-control:before,:root[data-bs-theme=dark] table.dataTable tr.dt-hasChild td.dt-control:before,:root[data-theme=dark] table.dataTable tr.dt-hasChild td.dt-control:before{border-top-color:rgba(255, 255, 255, 0.5);border-left-color:transparent}div.dt-scroll{width:100%}div.dt-scroll-body thead tr,div.dt-scroll-body tfoot tr{height:0}div.dt-scroll-body thead tr th,div.dt-scroll-body thead tr td,div.dt-scroll-body tfoot tr th,div.dt-scroll-body tfoot tr td{height:0 !important;padding-top:0px !important;padding-bottom:0px !important;border-top-width:0px !important;border-bottom-width:0px !important}div.dt-scroll-body thead tr th div.dt-scroll-sizing,div.dt-scroll-body thead tr td div.dt-scroll-sizing,div.dt-scroll-body tfoot tr th div.dt-scroll-sizing,div.dt-scroll-body tfoot tr td div.dt-scroll-sizing{height:0 !important;overflow:hidden !important}table.dataTable thead>tr>th:active,table.dataTable thead>tr>td:active{outline:none}table.dataTable thead>tr>th.dt-orderable-asc span.dt-column-order:before,table.dataTable thead>tr>th.dt-ordering-asc span.dt-column-order:before,table.dataTable thead>tr>td.dt-orderable-asc span.dt-column-order:before,table.dataTable thead>tr>td.dt-ordering-asc span.dt-column-order:before{position:absolute;display:block;bottom:50%;content:"▲";content:"▲"/""}table.dataTable thead>tr>th.dt-orderable-desc span.dt-column-order:after,table.dataTable thead>tr>th.dt-ordering-desc span.dt-column-order:after,table.dataTable thead>tr>td.dt-orderable-desc span.dt-column-order:after,table.dataTable thead>tr>td.dt-ordering-desc span.dt-column-order:after{position:absolute;display:block;top:50%;content:"▼";content:"▼"/""}table.dataTable thead>tr>th.dt-orderable-asc,table.dataTable thead>tr>th.dt-orderable-desc,table.dataTable thead>tr>th.dt-ordering-asc,table.dataTable thead>tr>th.dt-ordering-desc,table.dataTable thead>tr>td.dt-orderable-asc,table.dataTable thead>tr>td.dt-orderable-desc,table.dataTable thead>tr>td.dt-ordering-asc,table.dataTable thead>tr>td.dt-ordering-desc{position:relative;padding-right:30px}table.dataTable thead>tr>th.dt-orderable-asc span.dt-column-order,table.dataTable thead>tr>th.dt-orderable-desc span.dt-column-order,table.dataTable thead>tr>th.dt-ordering-asc span.dt-column-order,table.dataTable thead>tr>th.dt-ordering-desc span.dt-column-order,table.dataTable thead>tr>td.dt-orderable-asc span.dt-column-order,table.dataTable thead>tr>td.dt-orderable-desc span.dt-column-order,table.dataTable thead>tr>td.dt-ordering-asc span.dt-column-order,table.dataTable thead>tr>td.dt-ordering-desc span.dt-column-order{position:absolute;right:12px;top:0;bottom:0;width:12px}table.dataTable thead>tr>th.dt-orderable-asc span.dt-column-order:before,table.dataTable thead>tr>th.dt-orderable-asc span.dt-column-order:after,table.dataTable thead>tr>th.dt-orderable-desc span.dt-column-order:before,table.dataTable thead>tr>th.dt-orderable-desc span.dt-column-order:after,table.dataTable thead>tr>th.dt-ordering-asc span.dt-column-order:before,table.dataTable thead>tr>th.dt-ordering-asc span.dt-column-order:after,table.dataTable thead>tr>th.dt-ordering-desc span.dt-column-order:before,table.dataTable thead>tr>th.dt-ordering-desc span.dt-column-order:after,table.dataTable thead>tr>td.dt-orderable-asc span.dt-column-order:before,table.dataTable thead>tr>td.dt-orderable-asc span.dt-column-order:after,table.dataTable thead>tr>td.dt-orderable-desc span.dt-column-order:before,table.dataTable thead>tr>td.dt-orderable-desc span.dt-column-order:after,table.dataTable thead>tr>td.dt-ordering-asc span.dt-column-order:before,table.dataTable thead>tr>td.dt-ordering-asc span.dt-column-order:after,table.dataTable thead>tr>td.dt-ordering-desc span.dt-column-order:before,table.dataTable thead>tr>td.dt-ordering-desc span.dt-column-order:after{left:0;opacity:.125;line-height:9px;font-size:.8em}table.dataTable thead>tr>th.dt-orderable-asc,table.dataTable thead>tr>th.dt-orderable-desc,table.dataTable thead>tr>td.dt-orderable-asc,table.dataTable thead>tr>td.dt-orderable-desc{cursor:pointer}table.dataTable thead>tr>th.dt-orderable-asc:hover,table.dataTable thead>tr>th.dt-orderable-desc:hover,table.dataTable thead>tr>td.dt-orderable-asc:hover,table.dataTable thead>tr>td.dt-orderable-desc:hover{outline:2px solid rgba(0, 0, 0, 0.05);outline-offset:-2px}table.dataTable thead>tr>th.dt-ordering-asc span.dt-column-order:before,table.dataTable thead>tr>th.dt-ordering-desc span.dt-column-order:after,table.dataTable thead>tr>td.dt-ordering-asc span.dt-column-order:before,table.dataTable thead>tr>td.dt-ordering-desc span.dt-column-order:after{opacity:.6}table.dataTable thead>tr>th.sorting_desc_disabled span.dt-column-order:after,table.dataTable thead>tr>th.sorting_asc_disabled span.dt-column-order:before,table.dataTable thead>tr>td.sorting_desc_disabled span.dt-column-order:after,table.dataTable thead>tr>td.sorting_asc_disabled span.dt-column-order:before{display:none}table.dataTable thead>tr>th:active,table.dataTable thead>tr>td:active{outline:none}div.dt-scroll-body>table.dataTable>thead>tr>th,div.dt-scroll-body>table.dataTable>thead>tr>td{overflow:hidden}:root.dark table.dataTable thead>tr>th.dt-orderable-asc:hover,:root.dark table.dataTable thead>tr>th.dt-orderable-desc:hover,:root.dark table.dataTable thead>tr>td.dt-orderable-asc:hover,:root.dark table.dataTable thead>tr>td.dt-orderable-desc:hover,:root[data-bs-theme=dark] table.dataTable thead>tr>th.dt-orderable-asc:hover,:root[data-bs-theme=dark] table.dataTable thead>tr>th.dt-orderable-desc:hover,:root[data-bs-theme=dark] table.dataTable thead>tr>td.dt-orderable-asc:hover,:root[data-bs-theme=dark] table.dataTable thead>tr>td.dt-orderable-desc:hover{outline:2px solid rgba(255, 255, 255, 0.05)}div.dt-processing{position:absolute;top:50%;left:50%;width:200px;margin-left:-100px;margin-top:-22px;text-align:center;padding:2px;z-index:10}div.dt-processing>div:last-child{position:relative;width:80px;height:15px;margin:1em auto}div.dt-processing>div:last-child>div{position:absolute;top:0;width:13px;height:13px;border-radius:50%;background:rgb(13, 110, 253);background:rgb(var(--dt-row-selected));animation-timing-function:cubic-bezier(0, 1, 1, 0)}div.dt-processing>div:last-child>div:nth-child(1){left:8px;animation:datatables-loader-1 .6s infinite}div.dt-processing>div:last-child>div:nth-child(2){left:8px;animation:datatables-loader-2 .6s infinite}div.dt-processing>div:last-child>div:nth-child(3){left:32px;animation:datatables-loader-2 .6s infinite}div.dt-processing>div:last-child>div:nth-child(4){left:56px;animation:datatables-loader-3 .6s infinite}@keyframes datatables-loader-1{0%{transform:scale(0)}100%{transform:scale(1)}}@keyframes datatables-loader-3{0%{transform:scale(1)}100%{transform:scale(0)}}@keyframes datatables-loader-2{0%{transform:translate(0, 0)}100%{transform:translate(24px, 0)}}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}table.dataTable th,table.dataTable td{box-sizing:border-box}table.dataTable th.dt-left,table.dataTable td.dt-left{text-align:left}table.dataTable th.dt-center,table.dataTable td.dt-center{text-align:center}table.dataTable th.dt-right,table.dataTable td.dt-right{text-align:right}table.dataTable th.dt-justify,table.dataTable td.dt-justify{text-align:justify}table.dataTable th.dt-nowrap,table.dataTable td.dt-nowrap{white-space:nowrap}table.dataTable th.dt-empty,table.dataTable td.dt-empty{text-align:center;vertical-align:top}table.dataTable th.dt-type-numeric,table.dataTable th.dt-type-date,table.dataTable td.dt-type-numeric,table.dataTable td.dt-type-date{text-align:right}table.dataTable thead th,table.dataTable thead td,table.dataTable tfoot th,table.dataTable tfoot td{text-align:left}table.dataTable thead th.dt-head-left,table.dataTable thead td.dt-head-left,table.dataTable tfoot th.dt-head-left,table.dataTable tfoot td.dt-head-left{text-align:left}table.dataTable thead th.dt-head-center,table.dataTable thead td.dt-head-center,table.dataTable tfoot th.dt-head-center,table.dataTable tfoot td.dt-head-center{text-align:center}table.dataTable thead th.dt-head-right,table.dataTable thead td.dt-head-right,table.dataTable tfoot th.dt-head-right,table.dataTable tfoot td.dt-head-right{text-align:right}table.dataTable thead th.dt-head-justify,table.dataTable thead td.dt-head-justify,table.dataTable tfoot th.dt-head-justify,table.dataTable tfoot td.dt-head-justify{text-align:justify}table.dataTable thead th.dt-head-nowrap,table.dataTable thead td.dt-head-nowrap,table.dataTable tfoot th.dt-head-nowrap,table.dataTable tfoot td.dt-head-nowrap{white-space:nowrap}table.dataTable tbody th.dt-body-left,table.dataTable tbody td.dt-body-left{text-align:left}table.dataTable tbody th.dt-body-center,table.dataTable tbody td.dt-body-center{text-align:center}table.dataTable tbody th.dt-body-right,table.dataTable tbody td.dt-body-right{text-align:right}table.dataTable tbody th.dt-body-justify,table.dataTable tbody td.dt-body-justify{text-align:justify}table.dataTable tbody th.dt-body-nowrap,table.dataTable tbody td.dt-body-nowrap{white-space:nowrap}table.dataTable{width:100%;margin:0 auto;border-spacing:0}table.dataTable thead th,table.dataTable tfoot th{font-weight:bold}table.dataTable>thead>tr>th,table.dataTable>thead>tr>td{padding:10px;border-bottom:1px solid rgba(0, 0, 0, 0.3)}table.dataTable>thead>tr>th:active,table.dataTable>thead>tr>td:active{outline:none}table.dataTable>tfoot>tr>th,table.dataTable>tfoot>tr>td{border-top:1px solid rgba(0, 0, 0, 0.3);padding:10px 10px 6px 10px}table.dataTable>tbody>tr{background-color:transparent}table.dataTable>tbody>tr:first-child>*{border-top:none}table.dataTable>tbody>tr:last-child>*{border-bottom:none}table.dataTable>tbody>tr.selected>*{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.9);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.9);color:rgb(255, 255, 255);color:rgb(var(--dt-row-selected-text))}table.dataTable>tbody>tr.selected a{color:rgb(9, 10, 11);color:rgb(var(--dt-row-selected-link))}table.dataTable>tbody>tr>th,table.dataTable>tbody>tr>td{padding:8px 10px}table.dataTable.row-border>tbody>tr>*,table.dataTable.display>tbody>tr>*{border-top:1px solid rgba(0, 0, 0, 0.15)}table.dataTable.row-border>tbody>tr:first-child>*,table.dataTable.display>tbody>tr:first-child>*{border-top:none}table.dataTable.row-border>tbody>tr.selected+tr.selected>td,table.dataTable.display>tbody>tr.selected+tr.selected>td{border-top-color:rgba(13, 110, 253, 0.65);border-top-color:rgba(var(--dt-row-selected), 0.65)}table.dataTable.cell-border>tbody>tr>*{border-top:1px solid rgba(0, 0, 0, 0.15);border-right:1px solid rgba(0, 0, 0, 0.15)}table.dataTable.cell-border>tbody>tr>*:first-child{border-left:1px solid rgba(0, 0, 0, 0.15)}table.dataTable.cell-border>tbody>tr:first-child>*{border-top:1px solid rgba(0, 0, 0, 0.3)}table.dataTable.stripe>tbody>tr:nth-child(odd)>*,table.dataTable.display>tbody>tr:nth-child(odd)>*{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.023);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-stripe), 0.023)}table.dataTable.stripe>tbody>tr:nth-child(odd).selected>*,table.dataTable.display>tbody>tr:nth-child(odd).selected>*{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.923);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.923)}table.dataTable.hover>tbody>tr:hover>*,table.dataTable.display>tbody>tr:hover>*{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.035);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-hover), 0.035)}table.dataTable.hover>tbody>tr.selected:hover>*,table.dataTable.display>tbody>tr.selected:hover>*{box-shadow:inset 0 0 0 9999px #0d6efd !important;box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 1) !important}table.dataTable.order-column>tbody tr>.sorting_1,table.dataTable.order-column>tbody tr>.sorting_2,table.dataTable.order-column>tbody tr>.sorting_3,table.dataTable.display>tbody tr>.sorting_1,table.dataTable.display>tbody tr>.sorting_2,table.dataTable.display>tbody tr>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.019);box-shadow:inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.019)}table.dataTable.order-column>tbody tr.selected>.sorting_1,table.dataTable.order-column>tbody tr.selected>.sorting_2,table.dataTable.order-column>tbody tr.selected>.sorting_3,table.dataTable.display>tbody tr.selected>.sorting_1,table.dataTable.display>tbody tr.selected>.sorting_2,table.dataTable.display>tbody tr.selected>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.919);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.919)}table.dataTable.display>tbody>tr:nth-child(odd)>.sorting_1,table.dataTable.order-column.stripe>tbody>tr:nth-child(odd)>.sorting_1{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.054);box-shadow:inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.054)}table.dataTable.display>tbody>tr:nth-child(odd)>.sorting_2,table.dataTable.order-column.stripe>tbody>tr:nth-child(odd)>.sorting_2{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.047);box-shadow:inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.047)}table.dataTable.display>tbody>tr:nth-child(odd)>.sorting_3,table.dataTable.order-column.stripe>tbody>tr:nth-child(odd)>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.039);box-shadow:inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.039)}table.dataTable.display>tbody>tr:nth-child(odd).selected>.sorting_1,table.dataTable.order-column.stripe>tbody>tr:nth-child(odd).selected>.sorting_1{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.954);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.954)}table.dataTable.display>tbody>tr:nth-child(odd).selected>.sorting_2,table.dataTable.order-column.stripe>tbody>tr:nth-child(odd).selected>.sorting_2{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.947);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.947)}table.dataTable.display>tbody>tr:nth-child(odd).selected>.sorting_3,table.dataTable.order-column.stripe>tbody>tr:nth-child(odd).selected>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.939);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.939)}table.dataTable.display>tbody>tr.even>.sorting_1,table.dataTable.order-column.stripe>tbody>tr.even>.sorting_1{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.019);box-shadow:inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.019)}table.dataTable.display>tbody>tr.even>.sorting_2,table.dataTable.order-column.stripe>tbody>tr.even>.sorting_2{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.011);box-shadow:inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.011)}table.dataTable.display>tbody>tr.even>.sorting_3,table.dataTable.order-column.stripe>tbody>tr.even>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.003);box-shadow:inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.003)}table.dataTable.display>tbody>tr.even.selected>.sorting_1,table.dataTable.order-column.stripe>tbody>tr.even.selected>.sorting_1{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.919);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.919)}table.dataTable.display>tbody>tr.even.selected>.sorting_2,table.dataTable.order-column.stripe>tbody>tr.even.selected>.sorting_2{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.911);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.911)}table.dataTable.display>tbody>tr.even.selected>.sorting_3,table.dataTable.order-column.stripe>tbody>tr.even.selected>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.903);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.903)}table.dataTable.display tbody tr:hover>.sorting_1,table.dataTable.order-column.hover tbody tr:hover>.sorting_1{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.082);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-hover), 0.082)}table.dataTable.display tbody tr:hover>.sorting_2,table.dataTable.order-column.hover tbody tr:hover>.sorting_2{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.074);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-hover), 0.074)}table.dataTable.display tbody tr:hover>.sorting_3,table.dataTable.order-column.hover tbody tr:hover>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.062);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-hover), 0.062)}table.dataTable.display tbody tr:hover.selected>.sorting_1,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.982);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.982)}table.dataTable.display tbody tr:hover.selected>.sorting_2,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.974);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.974)}table.dataTable.display tbody tr:hover.selected>.sorting_3,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.962);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.962)}table.dataTable.compact thead th,table.dataTable.compact thead td,table.dataTable.compact tfoot th,table.dataTable.compact tfoot td,table.dataTable.compact tbody th,table.dataTable.compact tbody td{padding:4px}div.dt-container div.dt-layout-row{display:flex;justify-content:space-between;align-items:center;width:100%;margin:.75em 0}div.dt-container div.dt-layout-row div.dt-layout-cell{display:flex;justify-content:space-between;align-items:center}div.dt-container div.dt-layout-row div.dt-layout-cell.dt-layout-start{justify-content:flex-start;margin-right:auto}div.dt-container div.dt-layout-row div.dt-layout-cell.dt-layout-end{justify-content:flex-end;margin-left:auto}div.dt-container div.dt-layout-row div.dt-layout-cell:empty{display:none}@media screen and (max-width: 767px){div.dt-container div.dt-layout-row:not(.dt-layout-table){display:block}div.dt-container div.dt-layout-row:not(.dt-layout-table) div.dt-layout-cell{display:block;text-align:center}div.dt-container div.dt-layout-row:not(.dt-layout-table) div.dt-layout-cell>*{margin:.5em 0}div.dt-container div.dt-layout-row:not(.dt-layout-table) div.dt-layout-cell.dt-layout-start{margin-right:0}div.dt-container div.dt-layout-row:not(.dt-layout-table) div.dt-layout-cell.dt-layout-end{margin-left:0}}div.dt-container div.dt-layout-start>*:not(:last-child){margin-right:1em}div.dt-container div.dt-layout-end>*:not(:first-child){margin-left:1em}div.dt-container div.dt-layout-full{width:100%}div.dt-container div.dt-layout-full>*:only-child{margin-left:auto;margin-right:auto}div.dt-container div.dt-layout-table>div{display:block !important}@media screen and (max-width: 767px){div.dt-container div.dt-layout-start>*:not(:last-child){margin-right:0}div.dt-container div.dt-layout-end>*:not(:first-child){margin-left:0}}div.dt-container{position:relative;clear:both}div.dt-container .dt-search input{border:1px solid #aaa;border-radius:3px;padding:5px;background-color:transparent;color:inherit;margin-left:3px}div.dt-container .dt-input{border:1px solid #aaa;border-radius:3px;padding:5px;background-color:transparent;color:inherit}div.dt-container select.dt-input{padding:4px}div.dt-container .dt-paging .dt-paging-button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:.5em 1em;margin-left:2px;text-align:center;text-decoration:none !important;cursor:pointer;color:inherit !important;border:1px solid transparent;border-radius:2px;background:transparent}div.dt-container .dt-paging .dt-paging-button.current,div.dt-container .dt-paging .dt-paging-button.current:hover{color:inherit !important;border:1px solid rgba(0, 0, 0, 0.3);background-color:rgba(0, 0, 0, 0.05);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(230, 230, 230, 0.05)), color-stop(100%, rgba(0, 0, 0, 0.05)));background:-webkit-linear-gradient(top, rgba(230, 230, 230, 0.05) 0%, rgba(0, 0, 0, 0.05) 100%);background:-moz-linear-gradient(top, rgba(230, 230, 230, 0.05) 0%, rgba(0, 0, 0, 0.05) 100%);background:-ms-linear-gradient(top, rgba(230, 230, 230, 0.05) 0%, rgba(0, 0, 0, 0.05) 100%);background:-o-linear-gradient(top, rgba(230, 230, 230, 0.05) 0%, rgba(0, 0, 0, 0.05) 100%);background:linear-gradient(to bottom, rgba(230, 230, 230, 0.05) 0%, rgba(0, 0, 0, 0.05) 100%)}div.dt-container .dt-paging .dt-paging-button.disabled,div.dt-container .dt-paging .dt-paging-button.disabled:hover,div.dt-container .dt-paging .dt-paging-button.disabled:active{cursor:default;color:rgba(0, 0, 0, 0.5) !important;border:1px solid transparent;background:transparent;box-shadow:none}div.dt-container .dt-paging .dt-paging-button:hover{color:white !important;border:1px solid #111;background-color:#111;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));background:-webkit-linear-gradient(top, #585858 0%, #111 100%);background:-moz-linear-gradient(top, #585858 0%, #111 100%);background:-ms-linear-gradient(top, #585858 0%, #111 100%);background:-o-linear-gradient(top, #585858 0%, #111 100%);background:linear-gradient(to bottom, #585858 0%, #111 100%)}div.dt-container .dt-paging .dt-paging-button:active{outline:none;background-color:#0c0c0c;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));background:-webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);box-shadow:inset 0 0 3px #111}div.dt-container .dt-paging .ellipsis{padding:0 1em}div.dt-container .dt-length,div.dt-container .dt-search,div.dt-container .dt-info,div.dt-container .dt-processing,div.dt-container .dt-paging{color:inherit}div.dt-container .dataTables_scroll{clear:both}div.dt-container .dataTables_scroll div.dt-scroll-body{-webkit-overflow-scrolling:touch}div.dt-container .dataTables_scroll div.dt-scroll-body>table>thead>tr>th,div.dt-container .dataTables_scroll div.dt-scroll-body>table>thead>tr>td,div.dt-container .dataTables_scroll div.dt-scroll-body>table>tbody>tr>th,div.dt-container .dataTables_scroll div.dt-scroll-body>table>tbody>tr>td{vertical-align:middle}div.dt-container .dataTables_scroll div.dt-scroll-body>table>thead>tr>th>div.dataTables_sizing,div.dt-container .dataTables_scroll div.dt-scroll-body>table>thead>tr>td>div.dataTables_sizing,div.dt-container .dataTables_scroll div.dt-scroll-body>table>tbody>tr>th>div.dataTables_sizing,div.dt-container .dataTables_scroll div.dt-scroll-body>table>tbody>tr>td>div.dataTables_sizing{height:0;overflow:hidden;margin:0 !important;padding:0 !important}div.dt-container.dt-empty-footer tbody>tr:last-child>*{border-bottom:1px solid rgba(0, 0, 0, 0.3)}div.dt-container.dt-empty-footer .dt-scroll-body{border-bottom:1px solid rgba(0, 0, 0, 0.3)}div.dt-container.dt-empty-footer .dt-scroll-body tbody>tr:last-child>*{border-bottom:none}html.dark{--dt-row-hover: 255, 255, 255;--dt-row-stripe: 255, 255, 255;--dt-column-ordering: 255, 255, 255}html.dark table.dataTable>thead>tr>th,html.dark table.dataTable>thead>tr>td{border-bottom:1px solid rgb(89, 91, 94)}html.dark table.dataTable>thead>tr>th:active,html.dark table.dataTable>thead>tr>td:active{outline:none}html.dark table.dataTable>tfoot>tr>th,html.dark table.dataTable>tfoot>tr>td{border-top:1px solid rgb(89, 91, 94)}html.dark table.dataTable.row-border>tbody>tr>*,html.dark table.dataTable.display>tbody>tr>*{border-top:1px solid rgb(64, 67, 70)}html.dark table.dataTable.row-border>tbody>tr:first-child>*,html.dark table.dataTable.display>tbody>tr:first-child>*{border-top:none}html.dark table.dataTable.row-border>tbody>tr.selected+tr.selected>td,html.dark table.dataTable.display>tbody>tr.selected+tr.selected>td{border-top-color:rgba(13, 110, 253, 0.65);border-top-color:rgba(var(--dt-row-selected), 0.65)}html.dark table.dataTable.cell-border>tbody>tr>th,html.dark table.dataTable.cell-border>tbody>tr>td{border-top:1px solid rgb(64, 67, 70);border-right:1px solid rgb(64, 67, 70)}html.dark table.dataTable.cell-border>tbody>tr>th:first-child,html.dark table.dataTable.cell-border>tbody>tr>td:first-child{border-left:1px solid rgb(64, 67, 70)}html.dark .dt-container.dt-empty-footer table.dataTable{border-bottom:1px solid rgb(89, 91, 94)}html.dark .dt-container .dt-search input,html.dark .dt-container .dt-length select{border:1px solid rgba(255, 255, 255, 0.2);background-color:var(--dt-html-background)}html.dark .dt-container .dt-paging .dt-paging-button.current,html.dark .dt-container .dt-paging .dt-paging-button.current:hover{border:1px solid rgb(89, 91, 94);background:rgba(255, 255, 255, 0.15)}html.dark .dt-container .dt-paging .dt-paging-button.disabled,html.dark .dt-container .dt-paging .dt-paging-button.disabled:hover,html.dark .dt-container .dt-paging .dt-paging-button.disabled:active{color:#666 !important}html.dark .dt-container .dt-paging .dt-paging-button:hover{border:1px solid rgb(53, 53, 53);background:rgb(53, 53, 53)}html.dark .dt-container .dt-paging .dt-paging-button:active{background:#3a3a3a}*[dir=rtl] table.dataTable thead th,*[dir=rtl] table.dataTable thead td,*[dir=rtl] table.dataTable tfoot th,*[dir=rtl] table.dataTable tfoot td{text-align:right}*[dir=rtl] table.dataTable th.dt-type-numeric,*[dir=rtl] table.dataTable th.dt-type-date,*[dir=rtl] table.dataTable td.dt-type-numeric,*[dir=rtl] table.dataTable td.dt-type-date{text-align:left}*[dir=rtl] div.dt-container div.dt-layout-cell.dt-start{text-align:right}*[dir=rtl] div.dt-container div.dt-layout-cell.dt-end{text-align:left}*[dir=rtl] div.dt-container div.dt-search input{margin:0 3px 0 0} + + diff --git a/astropy/extern/jquery/data/css/jquery.dataTables.css b/astropy/extern/jquery/data/css/jquery.dataTables.css deleted file mode 100644 index 2d7711f945e1..000000000000 --- a/astropy/extern/jquery/data/css/jquery.dataTables.css +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Table styles - */ - table.dataTable { - width: 100%; - margin: 0 auto; - clear: both; - border-collapse: separate; - border-spacing: 0; - /* - * Header and footer styles - */ - /* - * Body styles - */ -} -table.dataTable thead th, -table.dataTable tfoot th { - font-weight: bold; -} -table.dataTable thead th, -table.dataTable thead td { - padding: 10px 18px; - border-bottom: 1px solid #111; -} -table.dataTable thead th:active, -table.dataTable thead td:active { - outline: none; -} -table.dataTable tfoot th, -table.dataTable tfoot td { - padding: 10px 18px 6px 18px; - border-top: 1px solid #111; -} -table.dataTable thead .sorting, -table.dataTable thead .sorting_asc, -table.dataTable thead .sorting_desc, -table.dataTable thead .sorting_asc_disabled, -table.dataTable thead .sorting_desc_disabled { - cursor: pointer; - *cursor: hand; - background-repeat: no-repeat; - background-position: center right; -} -table.dataTable thead .sorting { - background-image: url("../images/sort_both.png"); -} -table.dataTable thead .sorting_asc { - background-image: url("../images/sort_asc.png") !important; -} -table.dataTable thead .sorting_desc { - background-image: url("../images/sort_desc.png") !important; -} -table.dataTable thead .sorting_asc_disabled { - background-image: url("../images/sort_asc_disabled.png"); -} -table.dataTable thead .sorting_desc_disabled { - background-image: url("../images/sort_desc_disabled.png"); -} -table.dataTable tbody tr { - background-color: #ffffff; -} -table.dataTable tbody tr.selected { - background-color: #B0BED9; -} -table.dataTable tbody th, -table.dataTable tbody td { - padding: 8px 10px; -} -table.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td { - border-top: 1px solid #ddd; -} -table.dataTable.row-border tbody tr:first-child th, -table.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th, -table.dataTable.display tbody tr:first-child td { - border-top: none; -} -table.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td { - border-top: 1px solid #ddd; - border-right: 1px solid #ddd; -} -table.dataTable.cell-border tbody tr th:first-child, -table.dataTable.cell-border tbody tr td:first-child { - border-left: 1px solid #ddd; -} -table.dataTable.cell-border tbody tr:first-child th, -table.dataTable.cell-border tbody tr:first-child td { - border-top: none; -} -table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd { - background-color: #f9f9f9; -} -table.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected { - background-color: #acbad4; -} -table.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover { - background-color: #f6f6f6; -} -table.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected { - background-color: #aab7d1; -} -table.dataTable.order-column tbody tr > .sorting_1, -table.dataTable.order-column tbody tr > .sorting_2, -table.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1, -table.dataTable.display tbody tr > .sorting_2, -table.dataTable.display tbody tr > .sorting_3 { - background-color: #fafafa; -} -table.dataTable.order-column tbody tr.selected > .sorting_1, -table.dataTable.order-column tbody tr.selected > .sorting_2, -table.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1, -table.dataTable.display tbody tr.selected > .sorting_2, -table.dataTable.display tbody tr.selected > .sorting_3 { - background-color: #acbad5; -} -table.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 { - background-color: #f1f1f1; -} -table.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 { - background-color: #f3f3f3; -} -table.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 { - background-color: whitesmoke; -} -table.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 { - background-color: #a6b4cd; -} -table.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 { - background-color: #a8b5cf; -} -table.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 { - background-color: #a9b7d1; -} -table.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 { - background-color: #fafafa; -} -table.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 { - background-color: #fcfcfc; -} -table.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 { - background-color: #fefefe; -} -table.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 { - background-color: #acbad5; -} -table.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 { - background-color: #aebcd6; -} -table.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 { - background-color: #afbdd8; -} -table.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 { - background-color: #eaeaea; -} -table.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 { - background-color: #ececec; -} -table.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 { - background-color: #efefef; -} -table.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 { - background-color: #a2aec7; -} -table.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 { - background-color: #a3b0c9; -} -table.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 { - background-color: #a5b2cb; -} -table.dataTable.no-footer { - border-bottom: 1px solid #111; -} -table.dataTable.nowrap th, table.dataTable.nowrap td { - white-space: nowrap; -} -table.dataTable.compact thead th, -table.dataTable.compact thead td { - padding: 4px 17px; -} -table.dataTable.compact tfoot th, -table.dataTable.compact tfoot td { - padding: 4px; -} -table.dataTable.compact tbody th, -table.dataTable.compact tbody td { - padding: 4px; -} -table.dataTable th.dt-left, -table.dataTable td.dt-left { - text-align: left; -} -table.dataTable th.dt-center, -table.dataTable td.dt-center, -table.dataTable td.dataTables_empty { - text-align: center; -} -table.dataTable th.dt-right, -table.dataTable td.dt-right { - text-align: right; -} -table.dataTable th.dt-justify, -table.dataTable td.dt-justify { - text-align: justify; -} -table.dataTable th.dt-nowrap, -table.dataTable td.dt-nowrap { - white-space: nowrap; -} -table.dataTable thead th.dt-head-left, -table.dataTable thead td.dt-head-left, -table.dataTable tfoot th.dt-head-left, -table.dataTable tfoot td.dt-head-left { - text-align: left; -} -table.dataTable thead th.dt-head-center, -table.dataTable thead td.dt-head-center, -table.dataTable tfoot th.dt-head-center, -table.dataTable tfoot td.dt-head-center { - text-align: center; -} -table.dataTable thead th.dt-head-right, -table.dataTable thead td.dt-head-right, -table.dataTable tfoot th.dt-head-right, -table.dataTable tfoot td.dt-head-right { - text-align: right; -} -table.dataTable thead th.dt-head-justify, -table.dataTable thead td.dt-head-justify, -table.dataTable tfoot th.dt-head-justify, -table.dataTable tfoot td.dt-head-justify { - text-align: justify; -} -table.dataTable thead th.dt-head-nowrap, -table.dataTable thead td.dt-head-nowrap, -table.dataTable tfoot th.dt-head-nowrap, -table.dataTable tfoot td.dt-head-nowrap { - white-space: nowrap; -} -table.dataTable tbody th.dt-body-left, -table.dataTable tbody td.dt-body-left { - text-align: left; -} -table.dataTable tbody th.dt-body-center, -table.dataTable tbody td.dt-body-center { - text-align: center; -} -table.dataTable tbody th.dt-body-right, -table.dataTable tbody td.dt-body-right { - text-align: right; -} -table.dataTable tbody th.dt-body-justify, -table.dataTable tbody td.dt-body-justify { - text-align: justify; -} -table.dataTable tbody th.dt-body-nowrap, -table.dataTable tbody td.dt-body-nowrap { - white-space: nowrap; -} - -table.dataTable, -table.dataTable th, -table.dataTable td { - box-sizing: content-box; -} - -/* - * Control feature layout - */ -.dataTables_wrapper { - position: relative; - clear: both; - *zoom: 1; - zoom: 1; -} -.dataTables_wrapper .dataTables_length { - float: left; -} -.dataTables_wrapper .dataTables_length select { - border: 1px solid #aaa; - border-radius: 3px; - padding: 5px; - background-color: transparent; - padding: 4px; -} -.dataTables_wrapper .dataTables_filter { - float: right; - text-align: right; -} -.dataTables_wrapper .dataTables_filter input { - border: 1px solid #aaa; - border-radius: 3px; - padding: 5px; - background-color: transparent; - margin-left: 3px; -} -.dataTables_wrapper .dataTables_info { - clear: both; - float: left; - padding-top: 0.755em; -} -.dataTables_wrapper .dataTables_paginate { - float: right; - text-align: right; - padding-top: 0.25em; -} -.dataTables_wrapper .dataTables_paginate .paginate_button { - box-sizing: border-box; - display: inline-block; - min-width: 1.5em; - padding: 0.5em 1em; - margin-left: 2px; - text-align: center; - text-decoration: none !important; - cursor: pointer; - *cursor: hand; - color: #333 !important; - border: 1px solid transparent; - border-radius: 2px; -} -.dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover { - color: #333 !important; - border: 1px solid #979797; - background-color: white; - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #dcdcdc)); - /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, white 0%, #dcdcdc 100%); - /* Chrome10+,Safari5.1+ */ - background: -moz-linear-gradient(top, white 0%, #dcdcdc 100%); - /* FF3.6+ */ - background: -ms-linear-gradient(top, white 0%, #dcdcdc 100%); - /* IE10+ */ - background: -o-linear-gradient(top, white 0%, #dcdcdc 100%); - /* Opera 11.10+ */ - background: linear-gradient(to bottom, white 0%, #dcdcdc 100%); - /* W3C */ -} -.dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active { - cursor: default; - color: #666 !important; - border: 1px solid transparent; - background: transparent; - box-shadow: none; -} -.dataTables_wrapper .dataTables_paginate .paginate_button:hover { - color: white !important; - border: 1px solid #111; - background-color: #585858; - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111)); - /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, #585858 0%, #111 100%); - /* Chrome10+,Safari5.1+ */ - background: -moz-linear-gradient(top, #585858 0%, #111 100%); - /* FF3.6+ */ - background: -ms-linear-gradient(top, #585858 0%, #111 100%); - /* IE10+ */ - background: -o-linear-gradient(top, #585858 0%, #111 100%); - /* Opera 11.10+ */ - background: linear-gradient(to bottom, #585858 0%, #111 100%); - /* W3C */ -} -.dataTables_wrapper .dataTables_paginate .paginate_button:active { - outline: none; - background-color: #2b2b2b; - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c)); - /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); - /* Chrome10+,Safari5.1+ */ - background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); - /* FF3.6+ */ - background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); - /* IE10+ */ - background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); - /* Opera 11.10+ */ - background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%); - /* W3C */ - box-shadow: inset 0 0 3px #111; -} -.dataTables_wrapper .dataTables_paginate .ellipsis { - padding: 0 1em; -} -.dataTables_wrapper .dataTables_processing { - position: absolute; - top: 50%; - left: 50%; - width: 100%; - height: 40px; - margin-left: -50%; - margin-top: -25px; - padding-top: 20px; - text-align: center; - font-size: 1.2em; - background-color: white; - background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0))); - background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); - background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); - background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); - background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); - background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); -} -.dataTables_wrapper .dataTables_length, -.dataTables_wrapper .dataTables_filter, -.dataTables_wrapper .dataTables_info, -.dataTables_wrapper .dataTables_processing, -.dataTables_wrapper .dataTables_paginate { - color: #333; -} -.dataTables_wrapper .dataTables_scroll { - clear: both; -} -.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody { - *margin-top: -1px; - -webkit-overflow-scrolling: touch; -} -.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > td, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > td { - vertical-align: middle; -} -.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > th > div.dataTables_sizing, -.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > td > div.dataTables_sizing, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > th > div.dataTables_sizing, -.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > td > div.dataTables_sizing { - height: 0; - overflow: hidden; - margin: 0 !important; - padding: 0 !important; -} -.dataTables_wrapper.no-footer .dataTables_scrollBody { - border-bottom: 1px solid #111; -} -.dataTables_wrapper.no-footer div.dataTables_scrollHead table.dataTable, -.dataTables_wrapper.no-footer div.dataTables_scrollBody > table { - border-bottom: none; -} -.dataTables_wrapper:after { - visibility: hidden; - display: block; - content: ""; - clear: both; - height: 0; -} - -@media screen and (max-width: 767px) { - .dataTables_wrapper .dataTables_info, -.dataTables_wrapper .dataTables_paginate { - float: none; - text-align: center; - } - .dataTables_wrapper .dataTables_paginate { - margin-top: 0.5em; - } -} -@media screen and (max-width: 640px) { - .dataTables_wrapper .dataTables_length, -.dataTables_wrapper .dataTables_filter { - float: none; - text-align: center; - } - .dataTables_wrapper .dataTables_filter { - margin-top: 0.5em; - } -} \ No newline at end of file diff --git a/astropy/extern/jquery/data/js/jquery.dataTables.js b/astropy/extern/jquery/data/js/datatables.js similarity index 53% rename from astropy/extern/jquery/data/js/jquery.dataTables.js rename to astropy/extern/jquery/data/js/datatables.js index a7e3d30fe2c1..624c38eee6d9 100644 --- a/astropy/extern/jquery/data/js/jquery.dataTables.js +++ b/astropy/extern/jquery/data/js/datatables.js @@ -1,29 +1,37 @@ -/*! DataTables 1.10.25 - * ©2008-2021 SpryMedia Ltd - datatables.net/license +/* + * This combined file was created by the DataTables downloader builder: + * https://datatables.net/download + * + * To rebuild or modify this file with the latest versions of the included + * software please visit: + * https://datatables.net/download/#dt/dt-2.1.8 + * + * Included libraries: + * DataTables 2.1.8 + */ + +/*! DataTables 2.1.8 + * © SpryMedia Ltd - datatables.net/license */ /** * @summary DataTables * @description Paginate, search and order HTML tables - * @version 1.10.25 - * @file jquery.dataTables.js + * @version 2.1.8 * @author SpryMedia Ltd * @contact www.datatables.net - * @copyright Copyright 2008-2021 SpryMedia Ltd. + * @copyright SpryMedia Ltd. * * This source file is free software, available under the following license: - * MIT license - http://datatables.net/license + * MIT license - https://datatables.net/license * * This source file is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. * - * For details please refer to: http://www.datatables.net + * For details please refer to: https://www.datatables.net */ -/*jslint evil: true, undef: true, browser: true */ -/*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/ - (function( factory ) { "use strict"; @@ -35,1287 +43,1034 @@ } else if ( typeof exports === 'object' ) { // CommonJS - module.exports = function (root, $) { - if ( ! root ) { - // CommonJS environments without a window global must pass a - // root. This will give an error otherwise - root = window; - } + // jQuery's factory checks for a global window - if it isn't present then it + // returns a factory function that expects the window object + var jq = require('jquery'); - if ( ! $ ) { - $ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window - require('jquery') : - require('jquery')( root ); - } + if (typeof window === 'undefined') { + module.exports = function (root, $) { + if ( ! root ) { + // CommonJS environments without a window global must pass a + // root. This will give an error otherwise + root = window; + } - return factory( $, root, root.document ); - }; + if ( ! $ ) { + $ = jq( root ); + } + + return factory( $, root, root.document ); + }; + } + else { + module.exports = factory( jq, window, window.document ); + } } else { // Browser - factory( jQuery, window, document ); + window.DataTable = factory( jQuery, window, document ); } -} -(function( $, window, document, undefined ) { +}(function( $, window, document ) { "use strict"; - /** - * DataTables is a plug-in for the jQuery Javascript library. It is a highly - * flexible tool, based upon the foundations of progressive enhancement, - * which will add advanced interaction controls to any HTML table. For a - * full list of features please refer to - * [DataTables.net](href="http://datatables.net). - * - * Note that the `DataTable` object is not a global variable but is aliased - * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may - * be accessed. - * - * @class - * @param {object} [init={}] Configuration object for DataTables. Options - * are defined by {@link DataTable.defaults} - * @requires jQuery 1.7+ - * - * @example - * // Basic initialisation - * $(document).ready( function { - * $('#example').dataTable(); - * } ); - * - * @example - * // Initialisation with configuration options - in this case, disable - * // pagination and sorting. - * $(document).ready( function { - * $('#example').dataTable( { - * "paginate": false, - * "sort": false - * } ); - * } ); - */ - var DataTable = function ( options ) + + var DataTable = function ( selector, options ) { - /** - * Perform a jQuery selector action on the table's TR elements (from the tbody) and - * return the resulting jQuery object. - * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on - * @param {object} [oOpts] Optional parameters for modifying the rows to be included - * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter - * criterion ("applied") or all TR elements (i.e. no filter). - * @param {string} [oOpts.order=current] Order of the TR elements in the processed array. - * Can be either 'current', whereby the current sorting of the table is used, or - * 'original' whereby the original order the data was read into the table is used. - * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page - * ("current") or not ("all"). If 'current' is given, then order is assumed to be - * 'current' and filter is 'applied', regardless of what they might be given as. - * @returns {object} jQuery object, filtered by the given selector. - * @dtopt API - * @deprecated Since v1.10 - * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); - * - * // Highlight every second row - * oTable.$('tr:odd').css('backgroundColor', 'blue'); - * } ); - * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); - * - * // Filter to rows with 'Webkit' in them, add a background colour and then - * // remove the filter, thus highlighting the 'Webkit' rows only. - * oTable.fnFilter('Webkit'); - * oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue'); - * oTable.fnFilter(''); - * } ); - */ - this.$ = function ( sSelector, oOpts ) - { - return this.api(true).$( sSelector, oOpts ); - }; - - - /** - * Almost identical to $ in operation, but in this case returns the data for the matched - * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes - * rather than any descendants, so the data can be obtained for the row/cell. If matching - * rows are found, the data returned is the original data array/object that was used to - * create the row (or a generated array if from a DOM source). - * - * This method is often useful in-combination with $ where both functions are given the - * same parameters and the array indexes will match identically. - * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on - * @param {object} [oOpts] Optional parameters for modifying the rows to be included - * @param {string} [oOpts.filter=none] Select elements that meet the current filter - * criterion ("applied") or all elements (i.e. no filter). - * @param {string} [oOpts.order=current] Order of the data in the processed array. - * Can be either 'current', whereby the current sorting of the table is used, or - * 'original' whereby the original order the data was read into the table is used. - * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page - * ("current") or not ("all"). If 'current' is given, then order is assumed to be - * 'current' and filter is 'applied', regardless of what they might be given as. - * @returns {array} Data for the matched elements. If any elements, as a result of the - * selector, were not TR, TD or TH elements in the DataTable, they will have a null - * entry in the array. - * @dtopt API - * @deprecated Since v1.10 - * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); - * - * // Get the data from the first row in the table - * var data = oTable._('tr:first'); - * - * // Do something useful with the data - * alert( "First cell is: "+data[0] ); - * } ); - * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); - * - * // Filter to 'Webkit' and get all data for - * oTable.fnFilter('Webkit'); - * var data = oTable._('tr', {"search": "applied"}); - * - * // Do something with the data - * alert( data.length+" rows matched the search" ); - * } ); - */ - this._ = function ( sSelector, oOpts ) - { - return this.api(true).rows( sSelector, oOpts ).data(); - }; - - - /** - * Create a DataTables Api instance, with the currently selected tables for - * the Api's context. - * @param {boolean} [traditional=false] Set the API instance's context to be - * only the table referred to by the `DataTable.ext.iApiIndex` option, as was - * used in the API presented by DataTables 1.9- (i.e. the traditional mode), - * or if all tables captured in the jQuery object should be used. - * @return {DataTables.Api} - */ - this.api = function ( traditional ) - { - return traditional ? - new _Api( - _fnSettingsFromNode( this[ _ext.iApiIndex ] ) - ) : - new _Api( this ); - }; - - - /** - * Add a single new row or multiple rows of data to the table. Please note - * that this is suitable for client-side processing only - if you are using - * server-side processing (i.e. "bServerSide": true), then to add data, you - * must add it to the data source, i.e. the server-side, through an Ajax call. - * @param {array|object} data The data to be added to the table. This can be: - *
    - *
  • 1D array of data - add a single row with the data provided
  • - *
  • 2D array of arrays - add multiple rows in a single call
  • - *
  • object - data object when using mData
  • - *
  • array of objects - multiple data objects when using mData
  • - *
- * @param {bool} [redraw=true] redraw the table or not - * @returns {array} An array of integers, representing the list of indexes in - * aoData ({@link DataTable.models.oSettings}) that have been added to - * the table. - * @dtopt API - * @deprecated Since v1.10 - * - * @example - * // Global var for counter - * var giCount = 2; - * - * $(document).ready(function() { - * $('#example').dataTable(); - * } ); - * - * function fnClickAddRow() { - * $('#example').dataTable().fnAddData( [ - * giCount+".1", - * giCount+".2", - * giCount+".3", - * giCount+".4" ] - * ); - * - * giCount++; - * } - */ - this.fnAddData = function( data, redraw ) + // Check if called with a window or jQuery object for DOM less applications + // This is for backwards compatibility + if (DataTable.factory(selector, options)) { + return DataTable; + } + + // When creating with `new`, create a new DataTable, returning the API instance + if (this instanceof DataTable) { + return $(selector).DataTable(options); + } + else { + // Argument switching + options = selector; + } + + var _that = this; + var emptyInit = options === undefined; + var len = this.length; + + if ( emptyInit ) { + options = {}; + } + + // Method to get DT API instance from jQuery object + this.api = function () { - var api = this.api( true ); - - /* Check if we want to add multiple rows or not */ - var rows = Array.isArray(data) && ( Array.isArray(data[0]) || $.isPlainObject(data[0]) ) ? - api.rows.add( data ) : - api.row.add( data ); - - if ( redraw === undefined || redraw ) { - api.draw(); - } - - return rows.flatten().toArray(); + return new _Api( this ); }; - - - /** - * This function will make DataTables recalculate the column sizes, based on the data - * contained in the table and the sizes applied to the columns (in the DOM, CSS or - * through the sWidth parameter). This can be useful when the width of the table's - * parent element changes (for example a window resize). - * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to - * @dtopt API - * @deprecated Since v1.10 - * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable( { - * "sScrollY": "200px", - * "bPaginate": false - * } ); - * - * $(window).on('resize', function () { - * oTable.fnAdjustColumnSizing(); - * } ); - * } ); - */ - this.fnAdjustColumnSizing = function ( bRedraw ) - { - var api = this.api( true ).columns.adjust(); - var settings = api.settings()[0]; - var scroll = settings.oScroll; - - if ( bRedraw === undefined || bRedraw ) { - api.draw( false ); - } - else if ( scroll.sX !== "" || scroll.sY !== "" ) { - /* If not redrawing, but scrolling, we want to apply the new column sizes anyway */ - _fnScrollDraw( settings ); + + this.each(function() { + // For each initialisation we want to give it a clean initialisation + // object that can be bashed around + var o = {}; + var oInit = len > 1 ? // optimisation for single table case + _fnExtend( o, options, true ) : + options; + + + var i=0, iLen; + var sId = this.getAttribute( 'id' ); + var defaults = DataTable.defaults; + var $this = $(this); + + + /* Sanity check */ + if ( this.nodeName.toLowerCase() != 'table' ) + { + _fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 ); + return; } - }; - - - /** - * Quickly and simply clear a table - * @param {bool} [bRedraw=true] redraw the table or not - * @dtopt API - * @deprecated Since v1.10 - * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); - * - * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...) - * oTable.fnClearTable(); - * } ); - */ - this.fnClearTable = function( bRedraw ) - { - var api = this.api( true ).clear(); - - if ( bRedraw === undefined || bRedraw ) { - api.draw(); + + $(this).trigger( 'options.dt', oInit ); + + /* Backwards compatibility for the defaults */ + _fnCompatOpts( defaults ); + _fnCompatCols( defaults.column ); + + /* Convert the camel-case defaults to Hungarian */ + _fnCamelToHungarian( defaults, defaults, true ); + _fnCamelToHungarian( defaults.column, defaults.column, true ); + + /* Setting up the initialisation object */ + _fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ), true ); + + + + /* Check to see if we are re-initialising a table */ + var allSettings = DataTable.settings; + for ( i=0, iLen=allSettings.length ; i').prependTo(this), + fastData: function (row, column, type) { + return _fnGetCellData(oSettings, row, column, type); + } + } ); + oSettings.nTable = this; + oSettings.oInit = oInit; + + allSettings.push( oSettings ); + + // Make a single API instance available for internal handling + oSettings.api = new _Api( oSettings ); + + // Need to add the instance after the instance after the settings object has been added + // to the settings array, so we can self reference the table instance if more than one + oSettings.oInstance = (_that.length===1) ? _that : $this.dataTable(); + + // Backwards compatibility, before we apply all the defaults + _fnCompatOpts( oInit ); + + // If the length menu is given, but the init display length is not, use the length menu + if ( oInit.aLengthMenu && ! oInit.iDisplayLength ) + { + oInit.iDisplayLength = Array.isArray(oInit.aLengthMenu[0]) + ? oInit.aLengthMenu[0][0] + : $.isPlainObject( oInit.aLengthMenu[0] ) + ? oInit.aLengthMenu[0].value + : oInit.aLengthMenu[0]; } - - return data; - }; - - - /** - * Restore the table to it's original state in the DOM by removing all of DataTables - * enhancements, alterations to the DOM structure of the table and event listeners. - * @param {boolean} [remove=false] Completely remove the table from the DOM - * @dtopt API - * @deprecated Since v1.10 - * - * @example - * $(document).ready(function() { - * // This example is fairly pointless in reality, but shows how fnDestroy can be used - * var oTable = $('#example').dataTable(); - * oTable.fnDestroy(); - * } ); - */ - this.fnDestroy = function ( remove ) - { - this.api( true ).destroy( remove ); - }; - - + + // Apply the defaults and init options to make a single init object will all + // options defined from defaults and instance options. + oInit = _fnExtend( $.extend( true, {}, defaults ), oInit ); + + + // Map the initialisation options onto the settings object + _fnMap( oSettings.oFeatures, oInit, [ + "bPaginate", + "bLengthChange", + "bFilter", + "bSort", + "bSortMulti", + "bInfo", + "bProcessing", + "bAutoWidth", + "bSortClasses", + "bServerSide", + "bDeferRender" + ] ); + _fnMap( oSettings, oInit, [ + "ajax", + "fnFormatNumber", + "sServerMethod", + "aaSorting", + "aaSortingFixed", + "aLengthMenu", + "sPaginationType", + "iStateDuration", + "bSortCellsTop", + "iTabIndex", + "sDom", + "fnStateLoadCallback", + "fnStateSaveCallback", + "renderer", + "searchDelay", + "rowId", + "caption", + "layout", + "orderDescReverse", + "typeDetect", + [ "iCookieDuration", "iStateDuration" ], // backwards compat + [ "oSearch", "oPreviousSearch" ], + [ "aoSearchCols", "aoPreSearchCols" ], + [ "iDisplayLength", "_iDisplayLength" ] + ] ); + _fnMap( oSettings.oScroll, oInit, [ + [ "sScrollX", "sX" ], + [ "sScrollXInner", "sXInner" ], + [ "sScrollY", "sY" ], + [ "bScrollCollapse", "bCollapse" ] + ] ); + _fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" ); + + /* Callback functions which are array driven */ + _fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback ); + _fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams ); + _fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams ); + _fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded ); + _fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback ); + _fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow ); + _fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback ); + _fnCallbackReg( oSettings, 'aoFooterCallback', oInit.fnFooterCallback ); + _fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete ); + _fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback ); + + oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId ); + + /* Browser support detection */ + _fnBrowserDetect( oSettings ); + + var oClasses = oSettings.oClasses; + + $.extend( oClasses, DataTable.ext.classes, oInit.oClasses ); + $this.addClass( oClasses.table ); + + if (! oSettings.oFeatures.bPaginate) { + oInit.iDisplayStart = 0; + } + + if ( oSettings.iInitDisplayStart === undefined ) + { + /* Display start point, taking into account the save saving */ + oSettings.iInitDisplayStart = oInit.iDisplayStart; + oSettings._iDisplayStart = oInit.iDisplayStart; + } + + var defer = oInit.iDeferLoading; + if ( defer !== null ) + { + oSettings.deferLoading = true; + + var tmp = Array.isArray(defer); + oSettings._iRecordsDisplay = tmp ? defer[0] : defer; + oSettings._iRecordsTotal = tmp ? defer[1] : defer; + } + + /* + * Columns + * See if we should load columns automatically or use defined ones + */ + var columnsInit = []; + var thead = this.getElementsByTagName('thead'); + var initHeaderLayout = _fnDetectHeader( oSettings, thead[0] ); + + // If we don't have a columns array, then generate one with nulls + if ( oInit.aoColumns ) { + columnsInit = oInit.aoColumns; + } + else if ( initHeaderLayout.length ) { + for ( i=0, iLen=initHeaderLayout[0].length ; i').appendTo( $this ); + } + + caption.html( oSettings.caption ); + } + + // Store the caption side, so we can remove the element from the document + // when creating the element + if (caption.length) { + caption[0]._captionSide = caption.css('caption-side'); + oSettings.captionNode = caption[0]; + } + + if ( thead.length === 0 ) { + thead = $('').appendTo($this); + } + oSettings.nTHead = thead[0]; + $('tr', thead).addClass(oClasses.thead.row); + + var tbody = $this.children('tbody'); + if ( tbody.length === 0 ) { + tbody = $('').insertAfter(thead); + } + oSettings.nTBody = tbody[0]; + + var tfoot = $this.children('tfoot'); + if ( tfoot.length === 0 ) { + // If we are a scrolling table, and no footer has been given, then we need to create + // a tfoot element for the caption element to be appended to + tfoot = $('').appendTo($this); + } + oSettings.nTFoot = tfoot[0]; + $('tr', tfoot).addClass(oClasses.tfoot.row); + + // Copy the data index array + oSettings.aiDisplay = oSettings.aiDisplayMaster.slice(); + + // Initialisation complete - table can be drawn + oSettings.bInitialised = true; + + // Language definitions + var oLanguage = oSettings.oLanguage; + $.extend( true, oLanguage, oInit.oLanguage ); + + if ( oLanguage.sUrl ) { + // Get the language definitions from a file + $.ajax( { + dataType: 'json', + url: oLanguage.sUrl, + success: function ( json ) { + _fnCamelToHungarian( defaults.oLanguage, json ); + $.extend( true, oLanguage, json, oSettings.oInit.oLanguage ); + + _fnCallbackFire( oSettings, null, 'i18n', [oSettings], true); + _fnInitialise( oSettings ); + }, + error: function () { + // Error occurred loading language file + _fnLog( oSettings, 0, 'i18n file loading error', 21 ); + + // Continue on as best we can + _fnInitialise( oSettings ); + } + } ); + } + else { + _fnCallbackFire( oSettings, null, 'i18n', [oSettings], true); + _fnInitialise( oSettings ); + } + } ); + _that = null; + return this; + }; + + + + /** + * DataTables extensions + * + * This namespace acts as a collection area for plug-ins that can be used to + * extend DataTables capabilities. Indeed many of the build in methods + * use this method to provide their own capabilities (sorting methods for + * example). + * + * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy + * reasons + * + * @namespace + */ + DataTable.ext = _ext = { /** - * Redraw the table - * @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw. - * @dtopt API - * @deprecated Since v1.10 - * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); + * Buttons. For use with the Buttons extension for DataTables. This is + * defined here so other extensions can define buttons regardless of load + * order. It is _not_ used by DataTables core. * - * // Re-draw the table - you wouldn't want to do it here, but it's an example :-) - * oTable.fnDraw(); - * } ); + * @type object + * @default {} */ - this.fnDraw = function( complete ) - { - // Note that this isn't an exact match to the old call to _fnDraw - it takes - // into account the new data, but can hold position. - this.api( true ).draw( complete ); - }; - - + buttons: {}, + + /** - * Filter the input based on data - * @param {string} sInput String to filter the table on - * @param {int|null} [iColumn] Column to limit filtering to - * @param {bool} [bRegex=false] Treat as regular expression or not - * @param {bool} [bSmart=true] Perform smart filtering or not - * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es) - * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false) - * @dtopt API - * @deprecated Since v1.10 - * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); + * Element class names * - * // Sometime later - filter... - * oTable.fnFilter( 'test string' ); - * } ); + * @type object + * @default {} */ - this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive ) - { - var api = this.api( true ); - - if ( iColumn === null || iColumn === undefined ) { - api.search( sInput, bRegex, bSmart, bCaseInsensitive ); - } - else { - api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive ); - } - - api.draw(); - }; - - + classes: {}, + + /** - * Get the data for the whole table, an individual row or an individual cell based on the - * provided parameters. - * @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as - * a TR node then the data source for the whole row will be returned. If given as a - * TD/TH cell node then iCol will be automatically calculated and the data for the - * cell returned. If given as an integer, then this is treated as the aoData internal - * data index for the row (see fnGetPosition) and the data for that row used. - * @param {int} [col] Optional column index that you want the data of. - * @returns {array|object|string} If mRow is undefined, then the data for all rows is - * returned. If mRow is defined, just data for that row, and is iCol is - * defined, only data for the designated cell is returned. - * @dtopt API - * @deprecated Since v1.10 - * - * @example - * // Row data - * $(document).ready(function() { - * oTable = $('#example').dataTable(); - * - * oTable.$('tr').click( function () { - * var data = oTable.fnGetData( this ); - * // ... do something with the array / object of data for the row - * } ); - * } ); - * - * @example - * // Individual cell data - * $(document).ready(function() { - * oTable = $('#example').dataTable(); + * DataTables build type (expanded by the download builder) * - * oTable.$('td').click( function () { - * var sData = oTable.fnGetData( this ); - * alert( 'The cell clicked on had the value of '+sData ); - * } ); - * } ); + * @type string */ - this.fnGetData = function( src, col ) - { - var api = this.api( true ); - - if ( src !== undefined ) { - var type = src.nodeName ? src.nodeName.toLowerCase() : ''; - - return col !== undefined || type == 'td' || type == 'th' ? - api.cell( src, col ).data() : - api.row( src ).data() || null; - } - - return api.data().toArray(); - }; - - + builder: "dt/dt-2.1.8", + + /** - * Get an array of the TR nodes that are used in the table's body. Note that you will - * typically want to use the '$' API method in preference to this as it is more - * flexible. - * @param {int} [iRow] Optional row index for the TR element you want - * @returns {array|node} If iRow is undefined, returns an array of all TR elements - * in the table's body, or iRow is defined, just the TR element requested. - * @dtopt API - * @deprecated Since v1.10 - * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); + * Error reporting. + * + * How should DataTables report an error. Can take the value 'alert', + * 'throw', 'none' or a function. * - * // Get the nodes from the table - * var nNodes = oTable.fnGetNodes( ); - * } ); + * @type string|function + * @default alert */ - this.fnGetNodes = function( iRow ) - { - var api = this.api( true ); - - return iRow !== undefined ? - api.row( iRow ).node() : - api.rows().nodes().flatten().toArray(); - }; - - + errMode: "alert", + + /** - * Get the array indexes of a particular cell from it's DOM element - * and column index including hidden columns - * @param {node} node this can either be a TR, TD or TH in the table's body - * @returns {int} If nNode is given as a TR, then a single index is returned, or - * if given as a cell, an array of [row index, column index (visible), - * column index (all)] is given. - * @dtopt API - * @deprecated Since v1.10 + * Legacy so v1 plug-ins don't throw js errors on load + */ + feature: [], + + /** + * Feature plug-ins. + * + * This is an object of callbacks which provide the features for DataTables + * to be initialised via the `layout` option. + */ + features: {}, + + + /** + * Row searching. + * + * This method of searching is complimentary to the default type based + * searching, and a lot more comprehensive as it allows you complete control + * over the searching logic. Each element in this array is a function + * (parameters described below) that is called for every row in the table, + * and your logic decides if it should be included in the searching data set + * or not. * - * @example - * $(document).ready(function() { - * $('#example tbody td').click( function () { - * // Get the position of the current data from the node - * var aPos = oTable.fnGetPosition( this ); + * Searching functions have the following input parameters: + * + * 1. `{object}` DataTables settings object: see + * {@link DataTable.models.oSettings} + * 2. `{array|object}` Data for the row to be processed (same as the + * original format that was passed in as the data source, or an array + * from a DOM data source + * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which + * can be useful to retrieve the `TR` element if you need DOM interaction. * - * // Get the data array for this row - * var aData = oTable.fnGetData( aPos[0] ); + * And the following return is expected: * - * // Update the data array and return the value - * aData[ aPos[1] ] = 'clicked'; - * this.innerHTML = 'clicked'; - * } ); + * * {boolean} Include the row in the searched result set (true) or not + * (false) * - * // Init DataTables - * oTable = $('#example').dataTable(); - * } ); - */ - this.fnGetPosition = function( node ) - { - var api = this.api( true ); - var nodeName = node.nodeName.toUpperCase(); - - if ( nodeName == 'TR' ) { - return api.row( node ).index(); - } - else if ( nodeName == 'TD' || nodeName == 'TH' ) { - var cell = api.cell( node ).index(); - - return [ - cell.row, - cell.columnVisible, - cell.column - ]; - } - return null; - }; - - - /** - * Check to see if a row is 'open' or not. - * @param {node} nTr the table row to check - * @returns {boolean} true if the row is currently open, false otherwise - * @dtopt API - * @deprecated Since v1.10 + * Note that as with the main search ability in DataTables, technically this + * is "filtering", since it is subtractive. However, for consistency in + * naming we call it searching here. + * + * @type array + * @default [] * * @example - * $(document).ready(function() { - * var oTable; + * // The following example shows custom search being applied to the + * // fourth column (i.e. the data[3] index) based on two input values + * // from the end-user, matching the data in a certain range. + * $.fn.dataTable.ext.search.push( + * function( settings, data, dataIndex ) { + * var min = document.getElementById('min').value * 1; + * var max = document.getElementById('max').value * 1; + * var version = data[3] == "-" ? 0 : data[3]*1; * - * // 'open' an information row when a row is clicked on - * $('#example tbody tr').click( function () { - * if ( oTable.fnIsOpen(this) ) { - * oTable.fnClose( this ); - * } else { - * oTable.fnOpen( this, "Temporary row opened", "info_row" ); + * if ( min == "" && max == "" ) { + * return true; * } - * } ); - * - * oTable = $('#example').dataTable(); - * } ); + * else if ( min == "" && version < max ) { + * return true; + * } + * else if ( min < version && "" == max ) { + * return true; + * } + * else if ( min < version && version < max ) { + * return true; + * } + * return false; + * } + * ); */ - this.fnIsOpen = function( nTr ) - { - return this.api( true ).row( nTr ).child.isShown(); - }; - - + search: [], + + /** - * This function will place a new row directly after a row which is currently - * on display on the page, with the HTML contents that is passed into the - * function. This can be used, for example, to ask for confirmation that a - * particular record should be deleted. - * @param {node} nTr The table row to 'open' - * @param {string|node|jQuery} mHtml The HTML to put into the row - * @param {string} sClass Class to give the new TD cell - * @returns {node} The row opened. Note that if the table row passed in as the - * first parameter, is not found in the table, this method will silently - * return. - * @dtopt API - * @deprecated Since v1.10 + * Selector extensions * - * @example - * $(document).ready(function() { - * var oTable; + * The `selector` option can be used to extend the options available for the + * selector modifier options (`selector-modifier` object data type) that + * each of the three built in selector types offer (row, column and cell + + * their plural counterparts). For example the Select extension uses this + * mechanism to provide an option to select only rows, columns and cells + * that have been marked as selected by the end user (`{selected: true}`), + * which can be used in conjunction with the existing built in selector + * options. * - * // 'open' an information row when a row is clicked on - * $('#example tbody tr').click( function () { - * if ( oTable.fnIsOpen(this) ) { - * oTable.fnClose( this ); - * } else { - * oTable.fnOpen( this, "Temporary row opened", "info_row" ); - * } - * } ); + * Each property is an array to which functions can be pushed. The functions + * take three attributes: * - * oTable = $('#example').dataTable(); - * } ); + * * Settings object for the host table + * * Options object (`selector-modifier` object type) + * * Array of selected item indexes + * + * The return is an array of the resulting item indexes after the custom + * selector has been applied. + * + * @type object */ - this.fnOpen = function( nTr, mHtml, sClass ) - { - return this.api( true ) - .row( nTr ) - .child( mHtml, sClass ) - .show() - .child()[0]; - }; - - + selector: { + cell: [], + column: [], + row: [] + }, + + /** - * Change the pagination - provides the internal logic for pagination in a simple API - * function. With this function you can have a DataTables table go to the next, - * previous, first or last pages. - * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last" - * or page number to jump to (integer), note that page 0 is the first page. - * @param {bool} [bRedraw=true] Redraw the table or not - * @dtopt API - * @deprecated Since v1.10 + * Legacy configuration options. Enable and disable legacy options that + * are available in DataTables. * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); - * oTable.fnPageChange( 'next' ); - * } ); + * @type object */ - this.fnPageChange = function ( mAction, bRedraw ) - { - var api = this.api( true ).page( mAction ); - - if ( bRedraw === undefined || bRedraw ) { - api.draw(false); - } - }; - - + legacy: { + /** + * Enable / disable DataTables 1.9 compatible server-side processing + * requests + * + * @type boolean + * @default null + */ + ajax: null + }, + + /** - * Show a particular column - * @param {int} iCol The column whose display should be changed - * @param {bool} bShow Show (true) or hide (false) the column - * @param {bool} [bRedraw=true] Redraw the table or not - * @dtopt API - * @deprecated Since v1.10 + * Pagination plug-in methods. + * + * Each entry in this object is a function and defines which buttons should + * be shown by the pagination rendering method that is used for the table: + * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the + * buttons are displayed in the document, while the functions here tell it + * what buttons to display. This is done by returning an array of button + * descriptions (what each button will do). * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); + * Pagination types (the four built in options and any additional plug-in + * options defined here) can be used through the `paginationType` + * initialisation parameter. * - * // Hide the second column after initialisation - * oTable.fnSetColumnVis( 1, false ); - * } ); - */ - this.fnSetColumnVis = function ( iCol, bShow, bRedraw ) - { - var api = this.api( true ).column( iCol ).visible( bShow ); - - if ( bRedraw === undefined || bRedraw ) { - api.columns.adjust().draw(); - } - }; - - - /** - * Get the settings for a particular table for external manipulation - * @returns {object} DataTables settings object. See - * {@link DataTable.models.oSettings} - * @dtopt API - * @deprecated Since v1.10 + * The functions defined take two parameters: * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); - * var oSettings = oTable.fnSettings(); + * 1. `{int} page` The current page index + * 2. `{int} pages` The number of pages in the table * - * // Show an example parameter from the settings - * alert( oSettings._iDisplayStart ); - * } ); - */ - this.fnSettings = function() - { - return _fnSettingsFromNode( this[_ext.iApiIndex] ); - }; - - - /** - * Sort the table by a particular column - * @param {int} iCol the data index to sort on. Note that this will not match the - * 'display index' if you have hidden data entries - * @dtopt API - * @deprecated Since v1.10 + * Each function is expected to return an array where each element of the + * array can be one of: * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); + * * `first` - Jump to first page when activated + * * `last` - Jump to last page when activated + * * `previous` - Show previous page when activated + * * `next` - Show next page when activated + * * `{int}` - Show page of the index given + * * `{array}` - A nested array containing the above elements to add a + * containing 'DIV' element (might be useful for styling). * - * // Sort immediately with columns 0 and 1 - * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] ); - * } ); - */ - this.fnSort = function( aaSort ) - { - this.api( true ).order( aaSort ).draw(); - }; - - - /** - * Attach a sort listener to an element for a given column - * @param {node} nNode the element to attach the sort listener to - * @param {int} iColumn the column that a click on this node will sort on - * @param {function} [fnCallback] callback function when sort is run - * @dtopt API - * @deprecated Since v1.10 + * Note that DataTables v1.9- used this object slightly differently whereby + * an object with two functions would be defined for each plug-in. That + * ability is still supported by DataTables 1.10+ to provide backwards + * compatibility, but this option of use is now decremented and no longer + * documented in DataTables 1.10+. * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); + * @type object + * @default {} * - * // Sort on column 1, when 'sorter' is clicked on - * oTable.fnSortListener( document.getElementById('sorter'), 1 ); - * } ); + * @example + * // Show previous, next and current page buttons only + * $.fn.dataTableExt.oPagination.current = function ( page, pages ) { + * return [ 'previous', page, 'next' ]; + * }; */ - this.fnSortListener = function( nNode, iColumn, fnCallback ) - { - this.api( true ).order.listener( nNode, iColumn, fnCallback ); - }; - - + pager: {}, + + + renderer: { + pageButton: {}, + header: {} + }, + + /** - * Update a table cell or row - this method will accept either a single value to - * update the cell with, an array of values with one element for each column or - * an object in the same format as the original data source. The function is - * self-referencing in order to make the multi column updates easier. - * @param {object|array|string} mData Data to update the cell/row with - * @param {node|int} mRow TR element you want to update or the aoData index - * @param {int} [iColumn] The column to update, give as null or undefined to - * update a whole row. - * @param {bool} [bRedraw=true] Redraw the table or not - * @param {bool} [bAction=true] Perform pre-draw actions or not - * @returns {int} 0 on success, 1 on error - * @dtopt API - * @deprecated Since v1.10 + * Ordering plug-ins - custom data source + * + * The extension options for ordering of data available here is complimentary + * to the default type based ordering that DataTables typically uses. It + * allows much greater control over the the data that is being used to + * order a column, but is necessarily therefore more complex. + * + * This type of ordering is useful if you want to do ordering based on data + * live from the DOM (for example the contents of an 'input' element) rather + * than just the static string that DataTables knows of. + * + * The way these plug-ins work is that you create an array of the values you + * wish to be ordering for the column in question and then return that + * array. The data in the array much be in the index order of the rows in + * the table (not the currently ordering order!). Which order data gathering + * function is run here depends on the `dt-init columns.orderDataType` + * parameter that is used for the column (if any). + * + * The functions defined take two parameters: + * + * 1. `{object}` DataTables settings object: see + * {@link DataTable.models.oSettings} + * 2. `{int}` Target column index + * + * Each function is expected to return an array: + * + * * `{array}` Data for the column to be ordering upon + * + * @type array * * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); - * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell - * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row - * } ); - */ - this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction ) - { - var api = this.api( true ); - - if ( iColumn === undefined || iColumn === null ) { - api.row( mRow ).data( mData ); - } - else { - api.cell( mRow, iColumn ).data( mData ); - } - - if ( bAction === undefined || bAction ) { - api.columns.adjust(); - } - - if ( bRedraw === undefined || bRedraw ) { - api.draw(); - } - return 0; - }; - - + * // Ordering using `input` node values + * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col ) + * { + * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) { + * return $('input', td).val(); + * } ); + * } + */ + order: {}, + + /** - * Provide a common method for plug-ins to check the version of DataTables being used, in order - * to ensure compatibility. - * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the - * formats "X" and "X.Y" are also acceptable. - * @returns {boolean} true if this version of DataTables is greater or equal to the required - * version, or false if this version of DataTales is not suitable - * @method - * @dtopt API - * @deprecated Since v1.10 + * Type based plug-ins. * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); - * alert( oTable.fnVersionCheck( '1.9.0' ) ); - * } ); + * Each column in DataTables has a type assigned to it, either by automatic + * detection or by direct assignment using the `type` option for the column. + * The type of a column will effect how it is ordering and search (plug-ins + * can also make use of the column type if required). + * + * @namespace */ - this.fnVersionCheck = _ext.fnVersionCheck; - - - var _that = this; - var emptyInit = options === undefined; - var len = this.length; - - if ( emptyInit ) { - options = {}; - } - - this.oApi = this.internal = _ext.internal; - - // Extend with old style plug-in API methods - for ( var fn in DataTable.ext.internal ) { - if ( fn ) { - this[fn] = _fnExternApiFunc(fn); - } - } - - this.each(function() { - // For each initialisation we want to give it a clean initialisation - // object that can be bashed around - var o = {}; - var oInit = len > 1 ? // optimisation for single table case - _fnExtend( o, options, true ) : - options; - - /*global oInit,_that,emptyInit*/ - var i=0, iLen, j, jLen, k, kLen; - var sId = this.getAttribute( 'id' ); - var bInitHandedOff = false; - var defaults = DataTable.defaults; - var $this = $(this); - - - /* Sanity check */ - if ( this.nodeName.toLowerCase() != 'table' ) - { - _fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 ); - return; - } - - /* Backwards compatibility for the defaults */ - _fnCompatOpts( defaults ); - _fnCompatCols( defaults.column ); - - /* Convert the camel-case defaults to Hungarian */ - _fnCamelToHungarian( defaults, defaults, true ); - _fnCamelToHungarian( defaults.column, defaults.column, true ); - - /* Setting up the initialisation object */ - _fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ), true ); - - - - /* Check to see if we are re-initialising a table */ - var allSettings = DataTable.settings; - for ( i=0, iLen=allSettings.length ; iafnSortData + * for searching data. + * + * The functions defined take a single parameter: + * + * 1. `{*}` Data from the column cell to be prepared for searching + * + * Each function is expected to return: + * + * * `{string|null}` Formatted string that will be used for the searching. + * + * @type object + * @default {} + * + * @example + * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) { + * return d.replace(/\n/g," ").replace( /<.*?>/g, "" ); + * } */ - var anThs = []; - var aoColumnsInit; - var nThead = this.getElementsByTagName('thead'); - if ( nThead.length !== 0 ) - { - _fnDetectHeader( oSettings.aoHeader, nThead[0] ); - anThs = _fnGetUniqueThs( oSettings ); - } - - /* If not given a column array, generate one with nulls */ - if ( oInit.aoColumns === null ) - { - aoColumnsInit = []; - for ( i=0, iLen=anThs.length ; i0 if the first parameter should be sorted height than the second + * parameter. + * + * @type object + * @default {} + * + * @example + * // Numeric ordering of formatted numbers with a pre-formatter + * $.extend( $.fn.dataTable.ext.type.order, { + * "string-pre": function(x) { + * a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" ); + * return parseFloat( a ); + * } + * } ); + * + * @example + * // Case-sensitive string ordering, with no pre-formatting method + * $.extend( $.fn.dataTable.ext.order, { + * "string-case-asc": function(x,y) { + * return ((x < y) ? -1 : ((x > y) ? 1 : 0)); + * }, + * "string-case-desc": function(x,y) { + * return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + * } + * } ); */ - if ( rowOne.length ) { - var a = function ( cell, name ) { - return cell.getAttribute( 'data-'+name ) !== null ? name : null; - }; - - $( rowOne[0] ).children('th, td').each( function (i, cell) { - var col = oSettings.aoColumns[i]; - - if ( col.mData === i ) { - var sort = a( cell, 'sort' ) || a( cell, 'order' ); - var filter = a( cell, 'filter' ) || a( cell, 'search' ); - - if ( sort !== null || filter !== null ) { - col.mData = { - _: i+'.display', - sort: sort !== null ? i+'.@data-'+sort : undefined, - type: sort !== null ? i+'.@data-'+sort : undefined, - filter: filter !== null ? i+'.@data-'+filter : undefined - }; - - _fnColumnOptions( oSettings, i ); - } - } - } ); - } - - var features = oSettings.oFeatures; - var loadedInit = function () { - /* - * Sorting - * @todo For modularisation (1.11) this needs to do into a sort start up handler - */ - - // If aaSorting is not defined, then we use the first indicator in asSorting - // in case that has been altered, so the default sort reflects that option - if ( oInit.aaSorting === undefined ) { - var sorting = oSettings.aaSorting; - for ( i=0, iLen=sorting.length ; i').appendTo($this); - } - oSettings.nTHead = thead[0]; - - var tbody = $this.children('tbody'); - if ( tbody.length === 0 ) { - tbody = $('').insertAfter(thead); - } - oSettings.nTBody = tbody[0]; - - var tfoot = $this.children('tfoot'); - if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") ) { - // If we are a scrolling table, and no footer has been given, then we need to create - // a tfoot element for the caption element to be appended to - tfoot = $('').appendTo($this); - } - - if ( tfoot.length === 0 || tfoot.children().length === 0 ) { - $this.addClass( oClasses.sNoFooter ); - } - else if ( tfoot.length > 0 ) { - oSettings.nTFoot = tfoot[0]; - _fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot ); - } - - /* Check if there is data passing into the constructor */ - if ( oInit.aaData ) { - for ( i=0 ; i/g; + var _re_html = /<([^>]*>)/g; + var _max_str_len = Math.pow(2, 28); // This is not strict ISO8601 - Date.parse() is quite lax, although // implementations differ between browsers. - var _re_date = /^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/; + var _re_date = /^\d{2,4}[./-]\d{1,2}[./-]\d{1,2}([T ]{1}\d{1,2}[:.]\d{2}([.:]\d{2})?)?$/; // Escape regular expression special characters var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' ); - // http://en.wikipedia.org/wiki/Foreign_exchange_market + // https://en.wikipedia.org/wiki/Foreign_exchange_market // - \u20BD - Russian ruble. // - \u20a9 - South Korean Won // - \u20BA - Turkish Lira @@ -1387,13 +1142,18 @@ }; - var _isNumber = function ( d, decimalPoint, formatted ) { - var strType = typeof d === 'string'; + var _isNumber = function ( d, decimalPoint, formatted, allowEmpty ) { + var type = typeof d; + var strType = type === 'string'; + + if ( type === 'number' || type === 'bigint') { + return true; + } // If empty return immediately so there must be a number if it is a // formatted string (this stops the string "k", or "kr", etc being detected // as a formatted number for currency - if ( _empty( d ) ) { + if ( allowEmpty && _empty( d ) ) { return true; } @@ -1414,16 +1174,21 @@ return _empty( d ) || typeof d === 'string'; }; - - var _htmlNumeric = function ( d, decimalPoint, formatted ) { - if ( _empty( d ) ) { + // Is a string a number surrounded by HTML? + var _htmlNumeric = function ( d, decimalPoint, formatted, allowEmpty ) { + if ( allowEmpty && _empty( d ) ) { return true; } + // input and select strings mean that this isn't just a number + if (typeof d === 'string' && d.match(/<(input|select)/i)) { + return null; + } + var html = _isHtml( d ); return ! html ? null : - _isNumber( _stripHtml( d ), decimalPoint, formatted ) ? + _isNumber( _stripHtml( d ), decimalPoint, formatted, allowEmpty ) ? true : null; }; @@ -1465,14 +1230,16 @@ // is essential here if ( prop2 !== undefined ) { for ( ; i _max_str_len) { + throw new Error('Exceeded max str len'); + } + + var previous; + + input = input.replace(_re_html, ''); // Complete tags + + // Safety for incomplete script tag - use do / while to ensure that + // we get all instances + do { + previous = input; + input = input.replace(/