diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 8901ea41..3e7818ec 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,6 +1,10 @@
name: Build
permissions: {}
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+ cancel-in-progress: true
+
on:
push:
paths:
@@ -30,6 +34,10 @@ on:
- "docker/DockerSettings.yaml"
- "macros/**"
+defaults:
+ run:
+ shell: bash
+
jobs:
build:
name: Build and Test ${{ matrix.channel }}
@@ -63,7 +71,6 @@ jobs:
# Determine rust-toolchain version
- name: Init Variables
id: toolchain
- shell: bash
env:
CHANNEL: ${{ matrix.channel }}
run: |
diff --git a/.github/workflows/check-templates.yml b/.github/workflows/check-templates.yml
index 2e02f574..a8415dde 100644
--- a/.github/workflows/check-templates.yml
+++ b/.github/workflows/check-templates.yml
@@ -1,8 +1,16 @@
name: Check templates
permissions: {}
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+ cancel-in-progress: true
+
on: [ push, pull_request ]
+defaults:
+ run:
+ shell: bash
+
jobs:
docker-templates:
name: Validate docker templates
diff --git a/.github/workflows/hadolint.yml b/.github/workflows/hadolint.yml
index 8a6d1218..1e0fa48c 100644
--- a/.github/workflows/hadolint.yml
+++ b/.github/workflows/hadolint.yml
@@ -1,8 +1,15 @@
name: Hadolint
+permissions: {}
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+ cancel-in-progress: true
on: [ push, pull_request ]
-permissions: {}
+defaults:
+ run:
+ shell: bash
jobs:
hadolint:
@@ -25,7 +32,6 @@ jobs:
# Download hadolint - https://github.com/hadolint/hadolint/releases
- name: Download hadolint
- shell: bash
run: |
sudo curl -L https://github.com/hadolint/hadolint/releases/download/v${HADOLINT_VERSION}/hadolint-$(uname -s)-$(uname -m) -o /usr/local/bin/hadolint && \
sudo chmod +x /usr/local/bin/hadolint
@@ -41,13 +47,11 @@ jobs:
# Test Dockerfiles with hadolint
- name: Run hadolint
- shell: bash
run: hadolint docker/Dockerfile.{debian,alpine}
# End Test Dockerfiles with hadolint
# Test Dockerfiles with docker build checks
- name: Run docker build check
- shell: bash
run: |
echo "Checking docker/Dockerfile.debian"
docker build --check . -f docker/Dockerfile.debian
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 378682d3..48cca0bb 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,6 +1,12 @@
name: Release
permissions: {}
+concurrency:
+ # Apply concurrency control only on the upstream repo
+ group: ${{ github.repository == 'dani-garcia/vaultwarden' && format('{0}-{1}', github.workflow, github.ref) || github.run_id }}
+ # Don't cancel other runs when creating a tag
+ cancel-in-progress: ${{ github.ref_type == 'branch' }}
+
on:
push:
branches:
@@ -10,12 +16,6 @@ on:
# https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet
- '[1-2].[0-9]+.[0-9]+'
-concurrency:
- # Apply concurrency control only on the upstream repo
- group: ${{ github.repository == 'dani-garcia/vaultwarden' && format('{0}-{1}', github.workflow, github.ref) || github.run_id }}
- # Don't cancel other runs when creating a tag
- cancel-in-progress: ${{ github.ref_type == 'branch' }}
-
defaults:
run:
shell: bash
diff --git a/.github/workflows/releasecache-cleanup.yml b/.github/workflows/releasecache-cleanup.yml
index 22d98fa2..66bdf228 100644
--- a/.github/workflows/releasecache-cleanup.yml
+++ b/.github/workflows/releasecache-cleanup.yml
@@ -1,6 +1,10 @@
name: Cleanup
permissions: {}
+concurrency:
+ group: ${{ github.workflow }}
+ cancel-in-progress: false
+
on:
workflow_dispatch:
inputs:
diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml
index bd1043a0..4aeb43b1 100644
--- a/.github/workflows/trivy.yml
+++ b/.github/workflows/trivy.yml
@@ -1,6 +1,10 @@
name: Trivy
permissions: {}
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+ cancel-in-progress: true
+
on:
push:
branches:
@@ -46,6 +50,6 @@ jobs:
severity: CRITICAL,HIGH
- name: Upload Trivy scan results to GitHub Security tab
- uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
+ uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
with:
sarif_file: 'trivy-results.sarif'
diff --git a/.github/workflows/typos.yml b/.github/workflows/typos.yml
index b3dae9b7..45a596ce 100644
--- a/.github/workflows/typos.yml
+++ b/.github/workflows/typos.yml
@@ -1,7 +1,11 @@
name: Code Spell Checking
+permissions: {}
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+ cancel-in-progress: true
on: [ push, pull_request ]
-permissions: {}
jobs:
typos:
@@ -19,4 +23,4 @@ jobs:
# When this version is updated, do not forget to update this in `.pre-commit-config.yaml` too
- name: Spell Check Repo
- uses: crate-ci/typos@1a319b54cc9e3b333fed6a5c88ba1a90324da514 # v1.40.1
+ uses: crate-ci/typos@65120634e79d8374d1aa2f27e54baa0c364fff5a # v1.42.1
diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml
index 8ea25a4a..6083ef95 100644
--- a/.github/workflows/zizmor.yml
+++ b/.github/workflows/zizmor.yml
@@ -1,4 +1,9 @@
name: Security Analysis with zizmor
+permissions: {}
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+ cancel-in-progress: true
on:
push:
@@ -6,8 +11,6 @@ on:
pull_request:
branches: ["**"]
-permissions: {}
-
jobs:
zizmor:
name: Run zizmor
@@ -21,7 +24,7 @@ jobs:
persist-credentials: false
- name: Run zizmor
- uses: zizmorcore/zizmor-action@e639db99335bc9038abc0e066dfcd72e23d26fb4 # v0.3.0
+ uses: zizmorcore/zizmor-action@135698455da5c3b3e55f73f4419e481ab68cdd95 # v0.4.1
with:
# intentionally not scanning the entire repository,
# since it contains integration tests.
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 448ccbeb..6da57526 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -53,6 +53,6 @@ repos:
- "cd docker && make"
# When this version is updated, do not forget to update this in `.github/workflows/typos.yaml` too
- repo: https://github.com/crate-ci/typos
- rev: 1a319b54cc9e3b333fed6a5c88ba1a90324da514 # v1.40.1
+ rev: 65120634e79d8374d1aa2f27e54baa0c364fff5a # v1.42.1
hooks:
- id: typos
diff --git a/Cargo.lock b/Cargo.lock
index 07f5a49b..a4697493 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -161,13 +161,12 @@ dependencies = [
[[package]]
name = "async-compression"
-version = "0.4.36"
+version = "0.4.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98ec5f6c2f8bc326c994cb9e241cc257ddaba9afa8555a43cffbb5dd86efaa37"
+checksum = "d10e4f991a553474232bc0a31799f6d24b034a84c0971d80d2e2f78b2e576e40"
dependencies = [
"compression-codecs",
"compression-core",
- "futures-core",
"pin-project-lite",
"tokio",
]
@@ -403,9 +402,9 @@ dependencies = [
[[package]]
name = "aws-runtime"
-version = "1.5.17"
+version = "1.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d81b5b2898f6798ad58f484856768bca817e3cd9de0974c24ae0f1113fe88f1b"
+checksum = "959dab27ce613e6c9658eb3621064d0e2027e5f2acb65bc526a43577facea557"
dependencies = [
"aws-credential-types",
"aws-sigv4",
@@ -427,15 +426,16 @@ dependencies = [
[[package]]
name = "aws-sdk-sso"
-version = "1.91.0"
+version = "1.92.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ee6402a36f27b52fe67661c6732d684b2635152b676aa2babbfb5204f99115d"
+checksum = "b7d63bd2bdeeb49aa3f9b00c15e18583503b778b2e792fc06284d54e7d5b6566"
dependencies = [
"aws-credential-types",
"aws-runtime",
"aws-smithy-async",
"aws-smithy-http",
"aws-smithy-json",
+ "aws-smithy-observability",
"aws-smithy-runtime",
"aws-smithy-runtime-api",
"aws-smithy-types",
@@ -449,15 +449,16 @@ dependencies = [
[[package]]
name = "aws-sdk-ssooidc"
-version = "1.93.0"
+version = "1.94.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a45a7f750bbd170ee3677671ad782d90b894548f4e4ae168302c57ec9de5cb3e"
+checksum = "532d93574bf731f311bafb761366f9ece345a0416dbcc273d81d6d1a1205239b"
dependencies = [
"aws-credential-types",
"aws-runtime",
"aws-smithy-async",
"aws-smithy-http",
"aws-smithy-json",
+ "aws-smithy-observability",
"aws-smithy-runtime",
"aws-smithy-runtime-api",
"aws-smithy-types",
@@ -471,15 +472,16 @@ dependencies = [
[[package]]
name = "aws-sdk-sts"
-version = "1.95.0"
+version = "1.96.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55542378e419558e6b1f398ca70adb0b2088077e79ad9f14eb09441f2f7b2164"
+checksum = "357e9a029c7524db6a0099cd77fbd5da165540339e7296cca603531bc783b56c"
dependencies = [
"aws-credential-types",
"aws-runtime",
"aws-smithy-async",
"aws-smithy-http",
"aws-smithy-json",
+ "aws-smithy-observability",
"aws-smithy-query",
"aws-smithy-runtime",
"aws-smithy-runtime-api",
@@ -557,9 +559,9 @@ dependencies = [
[[package]]
name = "aws-smithy-observability"
-version = "0.1.5"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17f616c3f2260612fe44cede278bafa18e73e6479c4e393e2c4518cf2a9a228a"
+checksum = "ef1fcbefc7ece1d70dcce29e490f269695dfca2d2bacdeaf9e5c3f799e4e6a42"
dependencies = [
"aws-smithy-runtime-api",
]
@@ -576,9 +578,9 @@ dependencies = [
[[package]]
name = "aws-smithy-runtime"
-version = "1.9.5"
+version = "1.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a392db6c583ea4a912538afb86b7be7c5d8887d91604f50eb55c262ee1b4a5f5"
+checksum = "bb5b6167fcdf47399024e81ac08e795180c576a20e4d4ce67949f9a88ae37dc1"
dependencies = [
"aws-smithy-async",
"aws-smithy-http",
@@ -599,9 +601,9 @@ dependencies = [
[[package]]
name = "aws-smithy-runtime-api"
-version = "1.9.3"
+version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab0d43d899f9e508300e587bf582ba54c27a452dd0a9ea294690669138ae14a2"
+checksum = "efce7aaaf59ad53c5412f14fc19b2d5c6ab2c3ec688d272fd31f76ec12f44fb0"
dependencies = [
"aws-smithy-async",
"aws-smithy-types",
@@ -616,9 +618,9 @@ dependencies = [
[[package]]
name = "aws-smithy-types"
-version = "1.3.5"
+version = "1.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "905cb13a9895626d49cf2ced759b062d913834c7482c38e49557eac4e6193f01"
+checksum = "65f172bcb02424eb94425db8aed1b6d583b5104d4d5ddddf22402c661a320048"
dependencies = [
"base64-simd",
"bytes",
@@ -701,9 +703,9 @@ dependencies = [
[[package]]
name = "base64ct"
-version = "1.8.1"
+version = "1.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a"
+checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
[[package]]
name = "base64urlsafedata"
@@ -855,7 +857,7 @@ dependencies = [
"futures",
"hashbrown 0.15.5",
"once_cell",
- "thiserror 2.0.17",
+ "thiserror 2.0.18",
"tokio",
"web-time",
]
@@ -920,9 +922,9 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.2.51"
+version = "1.2.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203"
+checksum = "755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932"
dependencies = [
"find-msvc-tools",
"jobserver",
@@ -944,9 +946,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "chrono"
-version = "0.4.42"
+version = "0.4.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
+checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118"
dependencies = [
"iana-time-zone",
"js-sys",
@@ -994,9 +996,9 @@ checksum = "b9e769b5c8c8283982a987c6e948e540254f1058d5a74b8794914d4ef5fc2a24"
[[package]]
name = "compression-codecs"
-version = "0.4.35"
+version = "0.4.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0f7ac3e5b97fdce45e8922fb05cae2c37f7bbd63d30dd94821dacfd8f3f2bf2"
+checksum = "00828ba6fd27b45a448e57dbfe84f1029d4c9f26b368157e9a448a5f49a2ec2a"
dependencies = [
"brotli",
"compression-core",
@@ -1042,7 +1044,7 @@ version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
dependencies = [
- "getrandom 0.2.16",
+ "getrandom 0.2.17",
"once_cell",
"tiny-keccak",
]
@@ -1333,9 +1335,9 @@ dependencies = [
[[package]]
name = "data-encoding"
-version = "2.9.0"
+version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
+checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea"
[[package]]
name = "data-url"
@@ -1821,15 +1823,15 @@ dependencies = [
[[package]]
name = "find-msvc-tools"
-version = "0.1.6"
+version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff"
+checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db"
[[package]]
name = "flate2"
-version = "1.1.5"
+version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb"
+checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369"
dependencies = [
"crc32fast",
"miniz_oxide",
@@ -2011,9 +2013,9 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.16"
+version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
+checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
dependencies = [
"cfg-if",
"js-sys",
@@ -2084,7 +2086,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d9e3df7f0222ce5184154973d247c591d9aadc28ce7a73c6cd31100c9facff6"
dependencies = [
"codemap",
- "indexmap 2.12.1",
+ "indexmap 2.13.0",
"lasso",
"once_cell",
"phf 0.11.3",
@@ -2103,9 +2105,9 @@ dependencies = [
[[package]]
name = "h2"
-version = "0.4.12"
+version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386"
+checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54"
dependencies = [
"atomic-waker",
"bytes",
@@ -2113,7 +2115,7 @@ dependencies = [
"futures-core",
"futures-sink",
"http 1.4.0",
- "indexmap 2.12.1",
+ "indexmap 2.13.0",
"slab",
"tokio",
"tokio-util",
@@ -2133,9 +2135,9 @@ dependencies = [
[[package]]
name = "handlebars"
-version = "6.3.2"
+version = "6.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "759e2d5aea3287cb1190c8ec394f42866cb5bf74fcbf213f354e3c856ea26098"
+checksum = "9b3f9296c208515b87bd915a2f5d1163d4b3f863ba83337d7713cf478055948e"
dependencies = [
"derive_builder",
"log",
@@ -2144,7 +2146,7 @@ dependencies = [
"pest_derive",
"serde",
"serde_json",
- "thiserror 2.0.17",
+ "thiserror 2.0.18",
"walkdir",
]
@@ -2222,7 +2224,7 @@ dependencies = [
"once_cell",
"rand 0.9.2",
"ring",
- "thiserror 2.0.17",
+ "thiserror 2.0.18",
"tinyvec",
"tokio",
"tracing",
@@ -2245,7 +2247,7 @@ dependencies = [
"rand 0.9.2",
"resolv-conf",
"smallvec",
- "thiserror 2.0.17",
+ "thiserror 2.0.18",
"tokio",
"tracing",
]
@@ -2418,7 +2420,7 @@ dependencies = [
"http 1.4.0",
"hyper 1.8.1",
"hyper-util",
- "rustls 0.23.35",
+ "rustls 0.23.36",
"rustls-native-certs",
"rustls-pki-types",
"tokio",
@@ -2614,9 +2616,9 @@ dependencies = [
[[package]]
name = "indexmap"
-version = "2.12.1"
+version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2"
+checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
dependencies = [
"equivalent",
"hashbrown 0.16.1",
@@ -2702,9 +2704,9 @@ checksum = "47f142fe24a9c9944451e8349de0a56af5f3e7226dc46f3ed4d4ecc0b85af75e"
[[package]]
name = "jiff"
-version = "0.2.17"
+version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a87d9b8105c23642f50cbbae03d1f75d8422c5cb98ce7ee9271f7ff7505be6b8"
+checksum = "e67e8da4c49d6d9909fe03361f9b620f58898859f5c7aded68351e85e71ecf50"
dependencies = [
"jiff-static",
"jiff-tzdb-platform",
@@ -2717,9 +2719,9 @@ dependencies = [
[[package]]
name = "jiff-static"
-version = "0.2.17"
+version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b787bebb543f8969132630c51fd0afab173a86c6abae56ff3b9e5e3e3f9f6e58"
+checksum = "e0c84ee7f197eca9a86c6fd6cb771e55eb991632f15f2bc3ca6ec838929e6e78"
dependencies = [
"proc-macro2",
"quote",
@@ -2764,9 +2766,9 @@ dependencies = [
[[package]]
name = "js-sys"
-version = "0.3.83"
+version = "0.3.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8"
+checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3"
dependencies = [
"once_cell",
"wasm-bindgen",
@@ -2795,7 +2797,7 @@ checksum = "c76e1c7d7df3e34443b3621b459b066a7b79644f059fc8b2db7070c825fd417e"
dependencies = [
"base64 0.22.1",
"ed25519-dalek",
- "getrandom 0.2.16",
+ "getrandom 0.2.17",
"hmac",
"js-sys",
"p256",
@@ -2859,7 +2861,7 @@ dependencies = [
"nom 8.0.0",
"percent-encoding",
"quoted_printable",
- "rustls 0.23.35",
+ "rustls 0.23.36",
"rustls-native-certs",
"serde",
"socket2 0.6.1",
@@ -2871,9 +2873,9 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.178"
+version = "0.2.180"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
+checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
[[package]]
name = "libm"
@@ -2999,7 +3001,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36c791ecdf977c99f45f23280405d7723727470f6689a5e6dbf513ac547ae10d"
dependencies = [
"serde",
- "toml 0.9.10+spec-1.1.0",
+ "toml 0.9.11+spec-1.1.0",
]
[[package]]
@@ -3283,7 +3285,7 @@ checksum = "51e219e79014df21a225b1860a479e2dcd7cbd9130f4defd4bd0e191ea31d67d"
dependencies = [
"base64 0.22.1",
"chrono",
- "getrandom 0.2.16",
+ "getrandom 0.2.17",
"http 1.4.0",
"rand 0.8.5",
"reqwest",
@@ -3335,7 +3337,7 @@ dependencies = [
"bytes",
"crc32c",
"futures",
- "getrandom 0.2.16",
+ "getrandom 0.2.17",
"http 1.4.0",
"http-body 1.0.1",
"jiff",
@@ -3417,9 +3419,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
[[package]]
name = "openssl-probe"
-version = "0.2.0"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391"
+checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
[[package]]
name = "openssl-src"
@@ -3604,9 +3606,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]]
name = "pest"
-version = "2.8.4"
+version = "2.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cbcfd20a6d4eeba40179f05735784ad32bdaef05ce8e8af05f180d45bb3e7e22"
+checksum = "2c9eb05c21a464ea704b53158d358a31e6425db2f63a1a7312268b05fe2b75f7"
dependencies = [
"memchr",
"ucd-trie",
@@ -3614,9 +3616,9 @@ dependencies = [
[[package]]
name = "pest_derive"
-version = "2.8.4"
+version = "2.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51f72981ade67b1ca6adc26ec221be9f463f2b5839c7508998daa17c23d94d7f"
+checksum = "68f9dbced329c441fa79d80472764b1a2c7e57123553b8519b36663a2fb234ed"
dependencies = [
"pest",
"pest_generator",
@@ -3624,9 +3626,9 @@ dependencies = [
[[package]]
name = "pest_generator"
-version = "2.8.4"
+version = "2.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dee9efd8cdb50d719a80088b76f81aec7c41ed6d522ee750178f83883d271625"
+checksum = "3bb96d5051a78f44f43c8f712d8e810adb0ebf923fc9ed2655a7f66f63ba8ee5"
dependencies = [
"pest",
"pest_meta",
@@ -3637,9 +3639,9 @@ dependencies = [
[[package]]
name = "pest_meta"
-version = "2.8.4"
+version = "2.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf1d70880e76bdc13ba52eafa6239ce793d85c8e43896507e43dd8984ff05b82"
+checksum = "602113b5b5e8621770cfd490cfd90b9f84ab29bd2b0e49ad83eb6d186cef2365"
dependencies = [
"pest",
"sha2",
@@ -3853,9 +3855,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.104"
+version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0"
+checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
@@ -3963,9 +3965,9 @@ dependencies = [
"quinn-proto",
"quinn-udp",
"rustc-hash",
- "rustls 0.23.35",
+ "rustls 0.23.36",
"socket2 0.6.1",
- "thiserror 2.0.17",
+ "thiserror 2.0.18",
"tokio",
"tracing",
"web-time",
@@ -3983,10 +3985,10 @@ dependencies = [
"rand 0.9.2",
"ring",
"rustc-hash",
- "rustls 0.23.35",
+ "rustls 0.23.36",
"rustls-pki-types",
"slab",
- "thiserror 2.0.17",
+ "thiserror 2.0.18",
"tinyvec",
"tracing",
"web-time",
@@ -4008,9 +4010,9 @@ dependencies = [
[[package]]
name = "quote"
-version = "1.0.42"
+version = "1.0.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
+checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a"
dependencies = [
"proc-macro2",
]
@@ -4056,7 +4058,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
dependencies = [
"rand_chacha 0.9.0",
- "rand_core 0.9.3",
+ "rand_core 0.9.5",
]
[[package]]
@@ -4076,7 +4078,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
- "rand_core 0.9.3",
+ "rand_core 0.9.5",
]
[[package]]
@@ -4085,14 +4087,14 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
- "getrandom 0.2.16",
+ "getrandom 0.2.17",
]
[[package]]
name = "rand_core"
-version = "0.9.3"
+version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
+checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
dependencies = [
"getrandom 0.3.4",
]
@@ -4192,7 +4194,7 @@ dependencies = [
"base64 0.22.1",
"chrono",
"form_urlencoded",
- "getrandom 0.2.16",
+ "getrandom 0.2.17",
"hex",
"hmac",
"home",
@@ -4243,7 +4245,7 @@ dependencies = [
"percent-encoding",
"pin-project-lite",
"quinn",
- "rustls 0.23.35",
+ "rustls 0.23.36",
"rustls-native-certs",
"rustls-pki-types",
"serde",
@@ -4289,7 +4291,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
dependencies = [
"cc",
"cfg-if",
- "getrandom 0.2.16",
+ "getrandom 0.2.17",
"libc",
"untrusted",
"windows-sys 0.52.0",
@@ -4327,7 +4329,7 @@ dependencies = [
"either",
"figment",
"futures",
- "indexmap 2.12.1",
+ "indexmap 2.13.0",
"log",
"memchr",
"multer",
@@ -4359,7 +4361,7 @@ checksum = "575d32d7ec1a9770108c879fc7c47815a80073f96ca07ff9525a94fcede1dd46"
dependencies = [
"devise",
"glob",
- "indexmap 2.12.1",
+ "indexmap 2.13.0",
"proc-macro2",
"quote",
"rocket_http",
@@ -4379,7 +4381,7 @@ dependencies = [
"futures",
"http 0.2.12",
"hyper 0.14.32",
- "indexmap 2.12.1",
+ "indexmap 2.13.0",
"log",
"memchr",
"pear",
@@ -4421,9 +4423,9 @@ dependencies = [
[[package]]
name = "rsa"
-version = "0.9.9"
+version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40a0376c50d0358279d9d643e4bf7b7be212f1f4ff1da9070a7b54d22ef75c88"
+checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d"
dependencies = [
"const-oid",
"digest",
@@ -4440,6 +4442,16 @@ dependencies = [
"zeroize",
]
+[[package]]
+name = "rsqlite-vfs"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8a1f2315036ef6b1fbacd1972e8ee7688030b0a2121edfc2a6550febd41574d"
+dependencies = [
+ "hashbrown 0.16.1",
+ "thiserror 2.0.18",
+]
+
[[package]]
name = "rtoolbox"
version = "0.0.3"
@@ -4511,15 +4523,15 @@ dependencies = [
[[package]]
name = "rustls"
-version = "0.23.35"
+version = "0.23.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f"
+checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b"
dependencies = [
"log",
"once_cell",
"ring",
"rustls-pki-types",
- "rustls-webpki 0.103.8",
+ "rustls-webpki 0.103.9",
"subtle",
"zeroize",
]
@@ -4530,7 +4542,7 @@ version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63"
dependencies = [
- "openssl-probe 0.2.0",
+ "openssl-probe 0.2.1",
"rustls-pki-types",
"schannel",
"security-framework 3.5.1",
@@ -4547,9 +4559,9 @@ dependencies = [
[[package]]
name = "rustls-pki-types"
-version = "1.13.2"
+version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282"
+checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
dependencies = [
"web-time",
"zeroize",
@@ -4567,9 +4579,9 @@ dependencies = [
[[package]]
name = "rustls-webpki"
-version = "0.103.8"
+version = "0.103.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52"
+checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53"
dependencies = [
"ring",
"rustls-pki-types",
@@ -4793,9 +4805,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.148"
+version = "1.0.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da"
+checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
dependencies = [
"itoa",
"memchr",
@@ -4864,7 +4876,7 @@ dependencies = [
"chrono",
"hex",
"indexmap 1.9.3",
- "indexmap 2.12.1",
+ "indexmap 2.13.0",
"schemars 0.9.0",
"schemars 1.2.0",
"serde_core",
@@ -4966,7 +4978,7 @@ checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb"
dependencies = [
"num-bigint",
"num-traits",
- "thiserror 2.0.17",
+ "thiserror 2.0.18",
"time",
]
@@ -5050,14 +5062,13 @@ dependencies = [
[[package]]
name = "sqlite-wasm-rs"
-version = "0.5.1"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05e98301bf8b0540c7de45ecd760539b9c62f5772aed172f08efba597c11cd5d"
+checksum = "2f4206ed3a67690b9c29b77d728f6acc3ce78f16bf846d83c94f76400320181b"
dependencies = [
"cc",
- "hashbrown 0.16.1",
"js-sys",
- "thiserror 2.0.17",
+ "rsqlite-vfs",
"wasm-bindgen",
]
@@ -5126,9 +5137,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "2.0.111"
+version = "2.0.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87"
+checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
dependencies = [
"proc-macro2",
"quote",
@@ -5218,11 +5229,11 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "2.0.17"
+version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
+checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
dependencies = [
- "thiserror-impl 2.0.17",
+ "thiserror-impl 2.0.18",
]
[[package]]
@@ -5238,9 +5249,9 @@ dependencies = [
[[package]]
name = "thiserror-impl"
-version = "2.0.17"
+version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
+checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
dependencies = [
"proc-macro2",
"quote",
@@ -5267,9 +5278,9 @@ dependencies = [
[[package]]
name = "time"
-version = "0.3.44"
+version = "0.3.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
+checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd"
dependencies = [
"deranged",
"itoa",
@@ -5277,22 +5288,22 @@ dependencies = [
"num-conv",
"num_threads",
"powerfmt",
- "serde",
+ "serde_core",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
-version = "0.1.6"
+version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b"
+checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca"
[[package]]
name = "time-macros"
-version = "0.2.24"
+version = "0.2.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3"
+checksum = "71e552d1249bf61ac2a52db88179fd0673def1e1ad8243a00d9ec9ed71fee3dd"
dependencies = [
"num-conv",
"time-core",
@@ -5334,9 +5345,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.48.0"
+version = "1.49.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
+checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86"
dependencies = [
"bytes",
"libc",
@@ -5386,15 +5397,15 @@ version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
dependencies = [
- "rustls 0.23.35",
+ "rustls 0.23.36",
"tokio",
]
[[package]]
name = "tokio-stream"
-version = "0.1.17"
+version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047"
+checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70"
dependencies = [
"futures-core",
"pin-project-lite",
@@ -5415,9 +5426,9 @@ dependencies = [
[[package]]
name = "tokio-util"
-version = "0.7.17"
+version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594"
+checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098"
dependencies = [
"bytes",
"futures-core",
@@ -5441,9 +5452,9 @@ dependencies = [
[[package]]
name = "toml"
-version = "0.9.10+spec-1.1.0"
+version = "0.9.11+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0825052159284a1a8b4d6c0c86cbc801f2da5afd2b225fa548c72f2e74002f48"
+checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46"
dependencies = [
"serde_core",
"serde_spanned 1.0.4",
@@ -5476,7 +5487,7 @@ version = "0.22.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
dependencies = [
- "indexmap 2.12.1",
+ "indexmap 2.13.0",
"serde",
"serde_spanned 0.6.9",
"toml_datetime 0.6.11",
@@ -5513,9 +5524,9 @@ dependencies = [
[[package]]
name = "tower"
-version = "0.5.2"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
+checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4"
dependencies = [
"futures-core",
"futures-util",
@@ -5687,9 +5698,9 @@ dependencies = [
[[package]]
name = "unicase"
-version = "2.8.1"
+version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
+checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
[[package]]
name = "unicode-ident"
@@ -5717,14 +5728,15 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
-version = "2.5.7"
+version = "2.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b"
+checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed"
dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
"serde",
+ "serde_derive",
]
[[package]]
@@ -5892,18 +5904,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "wasip2"
-version = "1.0.1+wasi-0.2.4"
+version = "1.0.2+wasi-0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
+checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
dependencies = [
"wit-bindgen",
]
[[package]]
name = "wasm-bindgen"
-version = "0.2.106"
+version = "0.2.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd"
+checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566"
dependencies = [
"cfg-if",
"once_cell",
@@ -5914,11 +5926,12 @@ dependencies = [
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.56"
+version = "0.4.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c"
+checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f"
dependencies = [
"cfg-if",
+ "futures-util",
"js-sys",
"once_cell",
"wasm-bindgen",
@@ -5927,9 +5940,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.106"
+version = "0.2.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3"
+checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -5937,9 +5950,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.106"
+version = "0.2.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40"
+checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55"
dependencies = [
"bumpalo",
"proc-macro2",
@@ -5950,9 +5963,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.106"
+version = "0.2.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4"
+checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12"
dependencies = [
"unicode-ident",
]
@@ -5972,9 +5985,9 @@ dependencies = [
[[package]]
name = "web-sys"
-version = "0.3.83"
+version = "0.3.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac"
+checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -6060,9 +6073,9 @@ dependencies = [
[[package]]
name = "webpki-roots"
-version = "1.0.4"
+version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e"
+checksum = "12bed680863276c63889429bfd6cab3b99943659923822de1c8a39c49e4d722c"
dependencies = [
"rustls-pki-types",
]
@@ -6461,9 +6474,9 @@ checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904"
[[package]]
name = "wit-bindgen"
-version = "0.46.0"
+version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
+checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
[[package]]
name = "writeable"
@@ -6550,18 +6563,18 @@ dependencies = [
[[package]]
name = "zerocopy"
-version = "0.8.31"
+version = "0.8.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3"
+checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
-version = "0.8.31"
+version = "0.8.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a"
+checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1"
dependencies = [
"proc-macro2",
"quote",
@@ -6630,9 +6643,9 @@ dependencies = [
[[package]]
name = "zmij"
-version = "1.0.2"
+version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f4a4e8e9dc5c62d159f04fcdbe07f4c3fb710415aab4754bf11505501e3251d"
+checksum = "dfcd145825aace48cff44a8844de64bf75feec3080e0aa5cdbde72961ae51a65"
[[package]]
name = "zstd"
diff --git a/Cargo.toml b/Cargo.toml
index ea2d5ecb..9d54590e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -79,12 +79,12 @@ dashmap = "6.1.0"
# Async futures
futures = "0.3.31"
-tokio = { version = "1.48.0", features = ["rt-multi-thread", "fs", "io-util", "parking_lot", "time", "signal", "net"] }
-tokio-util = { version = "0.7.17", features = ["compat"]}
+tokio = { version = "1.49.0", features = ["rt-multi-thread", "fs", "io-util", "parking_lot", "time", "signal", "net"] }
+tokio-util = { version = "0.7.18", features = ["compat"]}
# A generic serialization/deserialization framework
serde = { version = "1.0.228", features = ["derive"] }
-serde_json = "1.0.148"
+serde_json = "1.0.149"
# A safe, extensible ORM and Query builder
# Currently pinned diesel to v2.3.3 as newer version break MySQL/MariaDB compatibility
@@ -106,15 +106,15 @@ subtle = "2.6.1"
uuid = { version = "1.19.0", features = ["v4"] }
# Date and time libraries
-chrono = { version = "0.4.42", features = ["clock", "serde"], default-features = false }
+chrono = { version = "0.4.43", features = ["clock", "serde"], default-features = false }
chrono-tz = "0.10.4"
-time = "0.3.44"
+time = "0.3.45"
# Job scheduler
job_scheduler_ng = "2.4.0"
# Data encoding library Hex/Base32/Base64
-data-encoding = "2.9.0"
+data-encoding = "2.10.0"
# JWT library
jsonwebtoken = { version = "10.2.0", features = ["use_pem", "rust_crypto"], default-features = false }
@@ -133,7 +133,7 @@ webauthn-rs-proto = "0.5.4"
webauthn-rs-core = "0.5.4"
# Handling of URL's for WebAuthn and favicons
-url = "2.5.7"
+url = "2.5.8"
# Email libraries
lettre = { version = "0.11.19", features = ["smtp-transport", "sendmail-transport", "builder", "serde", "hostname", "tracing", "tokio1-rustls", "ring", "rustls-native-certs"], default-features = false }
@@ -141,7 +141,7 @@ percent-encoding = "2.3.2" # URL encoding library used for URL's in the emails
email_address = "0.2.9"
# HTML Template library
-handlebars = { version = "6.3.2", features = ["dir_source"] }
+handlebars = { version = "6.4.0", features = ["dir_source"] }
# HTTP client (Used for favicons, version check, DUO and HIBP API)
reqwest = { version = "0.12.28", features = ["rustls-tls", "rustls-tls-native-roots", "stream", "json", "deflate", "gzip", "brotli", "zstd", "socks", "cookies", "charset", "http2", "system-proxy"], default-features = false}
@@ -200,7 +200,7 @@ opendal = { version = "0.55.0", features = ["services-fs"], default-features = f
anyhow = { version = "1.0.100", optional = true }
aws-config = { version = "1.8.12", features = ["behavior-version-latest", "rt-tokio", "credentials-process", "sso"], default-features = false, optional = true }
aws-credential-types = { version = "1.2.11", optional = true }
-aws-smithy-runtime-api = { version = "1.9.3", optional = true }
+aws-smithy-runtime-api = { version = "1.10.0", optional = true }
http = { version = "1.4.0", optional = true }
reqsign = { version = "0.16.5", optional = true }
diff --git a/docker/DockerSettings.yaml b/docker/DockerSettings.yaml
index dd87a9e3..02cd166b 100644
--- a/docker/DockerSettings.yaml
+++ b/docker/DockerSettings.yaml
@@ -1,6 +1,6 @@
---
-vault_version: "v2025.12.1+build.3"
-vault_image_digest: "sha256:bf5aa55dc7bcb99f85d2a88ff44d32cdc832e934a0603fe28e5c3f92904bad42"
+vault_version: "v2025.12.2"
+vault_image_digest: "sha256:3c9aec4924c4f529af5e48888cfddd559e553ee62ce3e81372b50103bbaf20f7"
# Cross Compile Docker Helper Scripts v1.9.0
# We use the linux/amd64 platform shell scripts since there is no difference between the different platform scripts
# https://github.com/tonistiigi/xx | https://hub.docker.com/r/tonistiigi/xx/tags
diff --git a/docker/Dockerfile.alpine b/docker/Dockerfile.alpine
index 2a6cf9f2..95aae642 100644
--- a/docker/Dockerfile.alpine
+++ b/docker/Dockerfile.alpine
@@ -19,15 +19,15 @@
# - From https://hub.docker.com/r/vaultwarden/web-vault/tags,
# click the tag name to view the digest of the image it currently points to.
# - From the command line:
-# $ docker pull docker.io/vaultwarden/web-vault:v2025.12.1_build.3
-# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2025.12.1_build.3
-# [docker.io/vaultwarden/web-vault@sha256:bf5aa55dc7bcb99f85d2a88ff44d32cdc832e934a0603fe28e5c3f92904bad42]
+# $ docker pull docker.io/vaultwarden/web-vault:v2025.12.2
+# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2025.12.2
+# [docker.io/vaultwarden/web-vault@sha256:3c9aec4924c4f529af5e48888cfddd559e553ee62ce3e81372b50103bbaf20f7]
#
# - Conversely, to get the tag name from the digest:
-# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:bf5aa55dc7bcb99f85d2a88ff44d32cdc832e934a0603fe28e5c3f92904bad42
-# [docker.io/vaultwarden/web-vault:v2025.12.1_build.3]
+# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:3c9aec4924c4f529af5e48888cfddd559e553ee62ce3e81372b50103bbaf20f7
+# [docker.io/vaultwarden/web-vault:v2025.12.2]
#
-FROM --platform=linux/amd64 docker.io/vaultwarden/web-vault@sha256:bf5aa55dc7bcb99f85d2a88ff44d32cdc832e934a0603fe28e5c3f92904bad42 AS vault
+FROM --platform=linux/amd64 docker.io/vaultwarden/web-vault@sha256:3c9aec4924c4f529af5e48888cfddd559e553ee62ce3e81372b50103bbaf20f7 AS vault
########################## ALPINE BUILD IMAGES ##########################
## NOTE: The Alpine Base Images do not support other platforms then linux/amd64 and linux/arm64
diff --git a/docker/Dockerfile.debian b/docker/Dockerfile.debian
index 03c0faba..113304b8 100644
--- a/docker/Dockerfile.debian
+++ b/docker/Dockerfile.debian
@@ -19,15 +19,15 @@
# - From https://hub.docker.com/r/vaultwarden/web-vault/tags,
# click the tag name to view the digest of the image it currently points to.
# - From the command line:
-# $ docker pull docker.io/vaultwarden/web-vault:v2025.12.1_build.3
-# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2025.12.1_build.3
-# [docker.io/vaultwarden/web-vault@sha256:bf5aa55dc7bcb99f85d2a88ff44d32cdc832e934a0603fe28e5c3f92904bad42]
+# $ docker pull docker.io/vaultwarden/web-vault:v2025.12.2
+# $ docker image inspect --format "{{.RepoDigests}}" docker.io/vaultwarden/web-vault:v2025.12.2
+# [docker.io/vaultwarden/web-vault@sha256:3c9aec4924c4f529af5e48888cfddd559e553ee62ce3e81372b50103bbaf20f7]
#
# - Conversely, to get the tag name from the digest:
-# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:bf5aa55dc7bcb99f85d2a88ff44d32cdc832e934a0603fe28e5c3f92904bad42
-# [docker.io/vaultwarden/web-vault:v2025.12.1_build.3]
+# $ docker image inspect --format "{{.RepoTags}}" docker.io/vaultwarden/web-vault@sha256:3c9aec4924c4f529af5e48888cfddd559e553ee62ce3e81372b50103bbaf20f7
+# [docker.io/vaultwarden/web-vault:v2025.12.2]
#
-FROM --platform=linux/amd64 docker.io/vaultwarden/web-vault@sha256:bf5aa55dc7bcb99f85d2a88ff44d32cdc832e934a0603fe28e5c3f92904bad42 AS vault
+FROM --platform=linux/amd64 docker.io/vaultwarden/web-vault@sha256:3c9aec4924c4f529af5e48888cfddd559e553ee62ce3e81372b50103bbaf20f7 AS vault
########################## Cross Compile Docker Helper Scripts ##########################
## We use the linux/amd64 no matter which Build Platform, since these are all bash scripts
diff --git a/macros/Cargo.toml b/macros/Cargo.toml
index 9855c56e..933d46d3 100644
--- a/macros/Cargo.toml
+++ b/macros/Cargo.toml
@@ -13,8 +13,8 @@ path = "src/lib.rs"
proc-macro = true
[dependencies]
-quote = "1.0.42"
-syn = "2.0.111"
+quote = "1.0.43"
+syn = "2.0.114"
[lints]
workspace = true
diff --git a/src/api/web.rs b/src/api/web.rs
index 91191968..d1ca0db4 100644
--- a/src/api/web.rs
+++ b/src/api/web.rs
@@ -239,8 +239,8 @@ pub fn static_files(filename: &str) -> Result<(ContentType, &'static [u8]), Erro
"jdenticon-3.3.0.js" => Ok((ContentType::JavaScript, include_bytes!("../static/scripts/jdenticon-3.3.0.js"))),
"datatables.js" => Ok((ContentType::JavaScript, include_bytes!("../static/scripts/datatables.js"))),
"datatables.css" => Ok((ContentType::CSS, include_bytes!("../static/scripts/datatables.css"))),
- "jquery-3.7.1.slim.js" => {
- Ok((ContentType::JavaScript, include_bytes!("../static/scripts/jquery-3.7.1.slim.js")))
+ "jquery-4.0.0.slim.js" => {
+ Ok((ContentType::JavaScript, include_bytes!("../static/scripts/jquery-4.0.0.slim.js")))
}
_ => err!(format!("Static file not found: {filename}")),
}
diff --git a/src/static/scripts/datatables.css b/src/static/scripts/datatables.css
index af6a9b1e..fe087655 100644
--- a/src/static/scripts/datatables.css
+++ b/src/static/scripts/datatables.css
@@ -4,10 +4,10 @@
*
* To rebuild or modify this file with the latest versions of the included
* software please visit:
- * https://datatables.net/download/#bs5/dt-2.3.5
+ * https://datatables.net/download/#bs5/dt-2.3.6
*
* Included libraries:
- * DataTables 2.3.5
+ * DataTables 2.3.6
*/
:root {
@@ -88,42 +88,42 @@ 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 {
+table.dataTable thead > tr > th.dt-orderable-asc .dt-column-order:before, table.dataTable thead > tr > th.dt-ordering-asc .dt-column-order:before,
+table.dataTable thead > tr > td.dt-orderable-asc .dt-column-order:before,
+table.dataTable thead > tr > td.dt-ordering-asc .dt-column-order:before {
position: absolute;
display: block;
bottom: 50%;
content: "\25B2";
content: "\25B2"/"";
}
-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 {
+table.dataTable thead > tr > th.dt-orderable-desc .dt-column-order:after, table.dataTable thead > tr > th.dt-ordering-desc .dt-column-order:after,
+table.dataTable thead > tr > td.dt-orderable-desc .dt-column-order:after,
+table.dataTable thead > tr > td.dt-ordering-desc .dt-column-order:after {
position: absolute;
display: block;
top: 50%;
content: "\25BC";
content: "\25BC"/"";
}
-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 {
+table.dataTable thead > tr > th.dt-orderable-asc .dt-column-order, table.dataTable thead > tr > th.dt-orderable-desc .dt-column-order, table.dataTable thead > tr > th.dt-ordering-asc .dt-column-order, table.dataTable thead > tr > th.dt-ordering-desc .dt-column-order,
+table.dataTable thead > tr > td.dt-orderable-asc .dt-column-order,
+table.dataTable thead > tr > td.dt-orderable-desc .dt-column-order,
+table.dataTable thead > tr > td.dt-ordering-asc .dt-column-order,
+table.dataTable thead > tr > td.dt-ordering-desc .dt-column-order {
position: relative;
width: 12px;
- height: 24px;
-}
-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 {
+ height: 20px;
+}
+table.dataTable thead > tr > th.dt-orderable-asc .dt-column-order:before, table.dataTable thead > tr > th.dt-orderable-asc .dt-column-order:after, table.dataTable thead > tr > th.dt-orderable-desc .dt-column-order:before, table.dataTable thead > tr > th.dt-orderable-desc .dt-column-order:after, table.dataTable thead > tr > th.dt-ordering-asc .dt-column-order:before, table.dataTable thead > tr > th.dt-ordering-asc .dt-column-order:after, table.dataTable thead > tr > th.dt-ordering-desc .dt-column-order:before, table.dataTable thead > tr > th.dt-ordering-desc .dt-column-order:after,
+table.dataTable thead > tr > td.dt-orderable-asc .dt-column-order:before,
+table.dataTable thead > tr > td.dt-orderable-asc .dt-column-order:after,
+table.dataTable thead > tr > td.dt-orderable-desc .dt-column-order:before,
+table.dataTable thead > tr > td.dt-orderable-desc .dt-column-order:after,
+table.dataTable thead > tr > td.dt-ordering-asc .dt-column-order:before,
+table.dataTable thead > tr > td.dt-ordering-asc .dt-column-order:after,
+table.dataTable thead > tr > td.dt-ordering-desc .dt-column-order:before,
+table.dataTable thead > tr > td.dt-ordering-desc .dt-column-order:after {
left: 0;
opacity: 0.125;
line-height: 9px;
@@ -140,15 +140,15 @@ 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 {
+table.dataTable thead > tr > th.dt-ordering-asc .dt-column-order:before, table.dataTable thead > tr > th.dt-ordering-desc .dt-column-order:after,
+table.dataTable thead > tr > td.dt-ordering-asc .dt-column-order:before,
+table.dataTable thead > tr > td.dt-ordering-desc .dt-column-order:after {
opacity: 0.6;
}
-table.dataTable thead > tr > th.dt-orderable-none:not(.dt-ordering-asc, .dt-ordering-desc) span.dt-column-order:empty, 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.dt-orderable-none:not(.dt-ordering-asc, .dt-ordering-desc) span.dt-column-order:empty,
-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 {
+table.dataTable thead > tr > th.dt-orderable-none:not(.dt-ordering-asc, .dt-ordering-desc) .dt-column-order:empty, table.dataTable thead > tr > th.sorting_desc_disabled .dt-column-order:after, table.dataTable thead > tr > th.sorting_asc_disabled .dt-column-order:before,
+table.dataTable thead > tr > td.dt-orderable-none:not(.dt-ordering-asc, .dt-ordering-desc) .dt-column-order:empty,
+table.dataTable thead > tr > td.sorting_desc_disabled .dt-column-order:after,
+table.dataTable thead > tr > td.sorting_asc_disabled .dt-column-order:before {
display: none;
}
table.dataTable thead > tr > th:active,
@@ -169,24 +169,24 @@ table.dataTable tfoot > tr > td div.dt-column-footer {
align-items: var(--dt-header-align-items);
gap: 4px;
}
-table.dataTable thead > tr > th div.dt-column-header span.dt-column-title,
-table.dataTable thead > tr > th div.dt-column-footer span.dt-column-title,
-table.dataTable thead > tr > td div.dt-column-header span.dt-column-title,
-table.dataTable thead > tr > td div.dt-column-footer span.dt-column-title,
-table.dataTable tfoot > tr > th div.dt-column-header span.dt-column-title,
-table.dataTable tfoot > tr > th div.dt-column-footer span.dt-column-title,
-table.dataTable tfoot > tr > td div.dt-column-header span.dt-column-title,
-table.dataTable tfoot > tr > td div.dt-column-footer span.dt-column-title {
+table.dataTable thead > tr > th div.dt-column-header .dt-column-title,
+table.dataTable thead > tr > th div.dt-column-footer .dt-column-title,
+table.dataTable thead > tr > td div.dt-column-header .dt-column-title,
+table.dataTable thead > tr > td div.dt-column-footer .dt-column-title,
+table.dataTable tfoot > tr > th div.dt-column-header .dt-column-title,
+table.dataTable tfoot > tr > th div.dt-column-footer .dt-column-title,
+table.dataTable tfoot > tr > td div.dt-column-header .dt-column-title,
+table.dataTable tfoot > tr > td div.dt-column-footer .dt-column-title {
flex-grow: 1;
}
-table.dataTable thead > tr > th div.dt-column-header span.dt-column-title:empty,
-table.dataTable thead > tr > th div.dt-column-footer span.dt-column-title:empty,
-table.dataTable thead > tr > td div.dt-column-header span.dt-column-title:empty,
-table.dataTable thead > tr > td div.dt-column-footer span.dt-column-title:empty,
-table.dataTable tfoot > tr > th div.dt-column-header span.dt-column-title:empty,
-table.dataTable tfoot > tr > th div.dt-column-footer span.dt-column-title:empty,
-table.dataTable tfoot > tr > td div.dt-column-header span.dt-column-title:empty,
-table.dataTable tfoot > tr > td div.dt-column-footer span.dt-column-title:empty {
+table.dataTable thead > tr > th div.dt-column-header .dt-column-title:empty,
+table.dataTable thead > tr > th div.dt-column-footer .dt-column-title:empty,
+table.dataTable thead > tr > td div.dt-column-header .dt-column-title:empty,
+table.dataTable thead > tr > td div.dt-column-footer .dt-column-title:empty,
+table.dataTable tfoot > tr > th div.dt-column-header .dt-column-title:empty,
+table.dataTable tfoot > tr > th div.dt-column-footer .dt-column-title:empty,
+table.dataTable tfoot > tr > td div.dt-column-header .dt-column-title:empty,
+table.dataTable tfoot > tr > td div.dt-column-footer .dt-column-title:empty {
display: none;
}
@@ -588,16 +588,16 @@ table.dataTable.table-sm > thead > tr td.dt-ordering-asc,
table.dataTable.table-sm > thead > tr td.dt-ordering-desc {
padding-right: 0.25rem;
}
-table.dataTable.table-sm > thead > tr th.dt-orderable-asc span.dt-column-order, table.dataTable.table-sm > thead > tr th.dt-orderable-desc span.dt-column-order, table.dataTable.table-sm > thead > tr th.dt-ordering-asc span.dt-column-order, table.dataTable.table-sm > thead > tr th.dt-ordering-desc span.dt-column-order,
-table.dataTable.table-sm > thead > tr td.dt-orderable-asc span.dt-column-order,
-table.dataTable.table-sm > thead > tr td.dt-orderable-desc span.dt-column-order,
-table.dataTable.table-sm > thead > tr td.dt-ordering-asc span.dt-column-order,
-table.dataTable.table-sm > thead > tr td.dt-ordering-desc span.dt-column-order {
+table.dataTable.table-sm > thead > tr th.dt-orderable-asc .dt-column-order, table.dataTable.table-sm > thead > tr th.dt-orderable-desc .dt-column-order, table.dataTable.table-sm > thead > tr th.dt-ordering-asc .dt-column-order, table.dataTable.table-sm > thead > tr th.dt-ordering-desc .dt-column-order,
+table.dataTable.table-sm > thead > tr td.dt-orderable-asc .dt-column-order,
+table.dataTable.table-sm > thead > tr td.dt-orderable-desc .dt-column-order,
+table.dataTable.table-sm > thead > tr td.dt-ordering-asc .dt-column-order,
+table.dataTable.table-sm > thead > tr td.dt-ordering-desc .dt-column-order {
right: 0.25rem;
}
-table.dataTable.table-sm > thead > tr th.dt-type-date span.dt-column-order, table.dataTable.table-sm > thead > tr th.dt-type-numeric span.dt-column-order,
-table.dataTable.table-sm > thead > tr td.dt-type-date span.dt-column-order,
-table.dataTable.table-sm > thead > tr td.dt-type-numeric span.dt-column-order {
+table.dataTable.table-sm > thead > tr th.dt-type-date .dt-column-order, table.dataTable.table-sm > thead > tr th.dt-type-numeric .dt-column-order,
+table.dataTable.table-sm > thead > tr td.dt-type-date .dt-column-order,
+table.dataTable.table-sm > thead > tr td.dt-type-numeric .dt-column-order {
left: 0.25rem;
}
@@ -606,7 +606,8 @@ div.dt-scroll-head table.table-bordered {
}
div.table-responsive > div.dt-container > div.row {
- margin: 0;
+ margin-left: 0;
+ margin-right: 0;
}
div.table-responsive > div.dt-container > div.row > div[class^=col-]:first-child {
padding-left: 0;
diff --git a/src/static/scripts/datatables.js b/src/static/scripts/datatables.js
index 961af0b4..75f7965e 100644
--- a/src/static/scripts/datatables.js
+++ b/src/static/scripts/datatables.js
@@ -4,13 +4,13 @@
*
* To rebuild or modify this file with the latest versions of the included
* software please visit:
- * https://datatables.net/download/#bs5/dt-2.3.5
+ * https://datatables.net/download/#bs5/dt-2.3.6
*
* Included libraries:
- * DataTables 2.3.5
+ * DataTables 2.3.6
*/
-/*! DataTables 2.3.5
+/*! DataTables 2.3.6
* © SpryMedia Ltd - datatables.net/license
*/
@@ -186,7 +186,7 @@
"sDestroyWidth": $this[0].style.width,
"sInstance": sId,
"sTableId": sId,
- colgroup: $('
').prependTo(this),
+ colgroup: $(' '),
fastData: function (row, column, type) {
return _fnGetCellData(oSettings, row, column, type);
}
@@ -259,6 +259,7 @@
"orderHandler",
"titleRow",
"typeDetect",
+ "columnTitleTag",
[ "iCookieDuration", "iStateDuration" ], // backwards compat
[ "oSearch", "oPreviousSearch" ],
[ "aoSearchCols", "aoPreSearchCols" ],
@@ -423,7 +424,7 @@
if ( oSettings.caption ) {
if ( caption.length === 0 ) {
- caption = $(' ').appendTo( $this );
+ caption = $(' ').prependTo( $this );
}
caption.html( oSettings.caption );
@@ -436,6 +437,14 @@
oSettings.captionNode = caption[0];
}
+ // Place the colgroup element in the correct location for the HTML structure
+ if (caption.length) {
+ oSettings.colgroup.insertAfter(caption);
+ }
+ else {
+ oSettings.colgroup.prependTo(oSettings.nTable);
+ }
+
if ( thead.length === 0 ) {
thead = $(' ').appendTo($this);
}
@@ -451,7 +460,7 @@
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);
+ tfoot = $(' ').insertAfter(thead);
}
oSettings.nTFoot = tfoot[0];
@@ -516,7 +525,7 @@
*
* @type string
*/
- builder: "bs5/dt-2.3.5",
+ builder: "bs5/dt-2.3.6",
/**
* Buttons. For use with the Buttons extension for DataTables. This is
@@ -1292,7 +1301,7 @@
};
// Replaceable function in api.util
- var _stripHtml = function (input) {
+ var _stripHtml = function (input, replacement) {
if (! input || typeof input !== 'string') {
return input;
}
@@ -1304,7 +1313,7 @@
var previous;
- input = input.replace(_re_html, ''); // Complete tags
+ input = input.replace(_re_html, replacement || ''); // Complete tags
// Safety for incomplete script tag - use do / while to ensure that
// we get all instances
@@ -1769,7 +1778,7 @@
}
},
- stripHtml: function (mixed) {
+ stripHtml: function (mixed, replacement) {
var type = typeof mixed;
if (type === 'function') {
@@ -1777,7 +1786,7 @@
return;
}
else if (type === 'string') {
- return _stripHtml(mixed);
+ return _stripHtml(mixed, replacement);
}
return mixed;
},
@@ -3379,7 +3388,7 @@
colspan++;
}
- var titleSpan = $('span.dt-column-title', cell);
+ var titleSpan = $('.dt-column-title', cell);
structure[row][column] = {
cell: cell,
@@ -4093,8 +4102,8 @@
}
// Wrap the column title so we can write to it in future
- if ( $('span.dt-column-title', cell).length === 0) {
- $('')
+ if ( $('.dt-column-title', cell).length === 0) {
+ $(document.createElement(settings.columnTitleTag))
.addClass('dt-column-title')
.append(cell.childNodes)
.appendTo(cell);
@@ -4105,9 +4114,9 @@
isHeader &&
jqCell.filter(':not([data-dt-order=disable])').length !== 0 &&
jqCell.parent(':not([data-dt-order=disable])').length !== 0 &&
- $('span.dt-column-order', cell).length === 0
+ $('.dt-column-order', cell).length === 0
) {
- $('')
+ $(document.createElement(settings.columnTitleTag))
.addClass('dt-column-order')
.appendTo(cell);
}
@@ -4116,7 +4125,7 @@
// layout for those elements
var headerFooter = isHeader ? 'header' : 'footer';
- if ( $('span.dt-column-' + headerFooter, cell).length === 0) {
+ if ( $('div.dt-column-' + headerFooter, cell).length === 0) {
$('')
.addClass('dt-column-' + headerFooter)
.append(cell.childNodes)
@@ -4273,6 +4282,10 @@
// Custom Ajax option to submit the parameters as a JSON string
if (baseAjax.submitAs === 'json' && typeof data === 'object') {
baseAjax.data = JSON.stringify(data);
+
+ if (!baseAjax.contentType) {
+ baseAjax.contentType = 'application/json; charset=utf-8';
+ }
}
if (typeof ajax === 'function') {
@@ -5531,7 +5544,7 @@
var autoClass = _ext.type.className[column.sType];
var padding = column.sContentPadding || (scrollX ? '-' : '');
var text = longest + padding;
- var insert = longest.indexOf('<') === -1
+ var insert = longest.indexOf('<') === -1 && longest.indexOf('&') === -1
? document.createTextNode(text)
: text
@@ -5719,15 +5732,20 @@
.replace(/id=".*?"/g, '')
.replace(/name=".*?"/g, '');
- var s = _stripHtml(cellString)
+ // Don't want Javascript at all in these calculation cells.
+ cellString = cellString.replace(/
/gi, ' ');
+
+ var noHtml = _stripHtml(cellString, ' ')
.replace( / /g, ' ' );
+ // The length is calculated on the text only, but we keep the HTML
+ // in the string so it can be used in the calculation table
collection.push({
- str: s,
- len: s.length
+ str: cellString,
+ len: noHtml.length
});
- allStrings.push(s);
+ allStrings.push(noHtml);
}
// Order and then cut down to the size we need
@@ -8782,7 +8800,7 @@
// Automatic - find the _last_ unique cell from the top that is not empty (last for
// backwards compatibility)
for (var i=0 ; i 6 ? h - 6 : h;
+ return decToHex(255 * (
+ h < 1 ? m1 + (m2 - m1) * h :
+ h < 3 ? m2 :
+ h < 4 ? m1 + (m2 - m1) * (4 - h) :
+ m1));
+}
+
+/**
+ * @param {string} color Color value to parse. Currently hexadecimal strings on the format #rgb[a] and #rrggbb[aa] are supported.
+ * @returns {string}
+ */
+function parseColor(color) {
+ if (/^#[0-9a-f]{3,8}$/i.test(color)) {
+ var result;
+ var colorLength = color.length;
+
+ if (colorLength < 6) {
+ var r = color[1],
+ g = color[2],
+ b = color[3],
+ a = color[4] || "";
+ result = "#" + r + r + g + g + b + b + a + a;
+ }
+ if (colorLength == 7 || colorLength > 8) {
+ result = color;
+ }
+
+ return result;
+ }
+}
+
+/**
+ * Converts a hexadecimal color to a CSS3 compatible color.
+ * @param {string} hexColor Color on the format "#RRGGBB" or "#RRGGBBAA"
+ * @returns {string}
+ */
+function toCss3Color(hexColor) {
+ var a = parseHex(hexColor, 7, 2);
+ var result;
+
+ if (isNaN(a)) {
+ result = hexColor;
+ } else {
+ var r = parseHex(hexColor, 1, 2),
+ g = parseHex(hexColor, 3, 2),
+ b = parseHex(hexColor, 5, 2);
+ result = "rgba(" + r + "," + g + "," + b + "," + (a / 255).toFixed(2) + ")";
+ }
+
+ return result;
+}
+
+/**
+ * Converts an HSL color to a hexadecimal RGB color.
+ * @param {number} hue Hue in range [0, 1]
+ * @param {number} saturation Saturation in range [0, 1]
+ * @param {number} lightness Lightness in range [0, 1]
+ * @returns {string}
+ */
+function hsl(hue, saturation, lightness) {
+ // Based on http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color
+ var result;
+
+ if (saturation == 0) {
+ var partialHex = decToHex(lightness * 255);
+ result = partialHex + partialHex + partialHex;
+ }
+ else {
+ var m2 = lightness <= 0.5 ? lightness * (saturation + 1) : lightness + saturation - lightness * saturation,
+ m1 = lightness * 2 - m2;
+ result =
+ hueToRgb(m1, m2, hue * 6 + 2) +
+ hueToRgb(m1, m2, hue * 6) +
+ hueToRgb(m1, m2, hue * 6 - 2);
+ }
+
+ return "#" + result;
}
-function decToHex(v) {
- v |= 0; // Ensure integer value
- return v < 0 ? "00" :
- v < 16 ? "0" + v.toString(16) :
- v < 256 ? v.toString(16) :
- "ff";
-}
-
-function hueToRgb(m1, m2, h) {
- h = h < 0 ? h + 6 : h > 6 ? h - 6 : h;
- return decToHex(255 * (
- h < 1 ? m1 + (m2 - m1) * h :
- h < 3 ? m2 :
- h < 4 ? m1 + (m2 - m1) * (4 - h) :
- m1));
-}
-
-/**
- * @param {string} color Color value to parse. Currently hexadecimal strings on the format #rgb[a] and #rrggbb[aa] are supported.
- * @returns {string}
- */
-function parseColor(color) {
- if (/^#[0-9a-f]{3,8}$/i.test(color)) {
- var result;
- var colorLength = color.length;
-
- if (colorLength < 6) {
- var r = color[1],
- g = color[2],
- b = color[3],
- a = color[4] || "";
- result = "#" + r + r + g + g + b + b + a + a;
- }
- if (colorLength == 7 || colorLength > 8) {
- result = color;
- }
-
- return result;
- }
-}
-
-/**
- * Converts a hexadecimal color to a CSS3 compatible color.
- * @param {string} hexColor Color on the format "#RRGGBB" or "#RRGGBBAA"
- * @returns {string}
- */
-function toCss3Color(hexColor) {
- var a = parseHex(hexColor, 7, 2);
- var result;
-
- if (isNaN(a)) {
- result = hexColor;
- } else {
- var r = parseHex(hexColor, 1, 2),
- g = parseHex(hexColor, 3, 2),
- b = parseHex(hexColor, 5, 2);
- result = "rgba(" + r + "," + g + "," + b + "," + (a / 255).toFixed(2) + ")";
- }
-
- return result;
-}
-
-/**
- * Converts an HSL color to a hexadecimal RGB color.
- * @param {number} hue Hue in range [0, 1]
- * @param {number} saturation Saturation in range [0, 1]
- * @param {number} lightness Lightness in range [0, 1]
- * @returns {string}
- */
-function hsl(hue, saturation, lightness) {
- // Based on http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color
- var result;
-
- if (saturation == 0) {
- var partialHex = decToHex(lightness * 255);
- result = partialHex + partialHex + partialHex;
- }
- else {
- var m2 = lightness <= 0.5 ? lightness * (saturation + 1) : lightness + saturation - lightness * saturation,
- m1 = lightness * 2 - m2;
- result =
- hueToRgb(m1, m2, hue * 6 + 2) +
- hueToRgb(m1, m2, hue * 6) +
- hueToRgb(m1, m2, hue * 6 - 2);
- }
-
- return "#" + result;
-}
-
-/**
- * Converts an HSL color to a hexadecimal RGB color. This function will correct the lightness for the "dark" hues
- * @param {number} hue Hue in range [0, 1]
- * @param {number} saturation Saturation in range [0, 1]
- * @param {number} lightness Lightness in range [0, 1]
- * @returns {string}
- */
-function correctedHsl(hue, saturation, lightness) {
- // The corrector specifies the perceived middle lightness for each hue
- var correctors = [ 0.55, 0.5, 0.5, 0.46, 0.6, 0.55, 0.55 ],
- corrector = correctors[(hue * 6 + 0.5) | 0];
-
- // Adjust the input lightness relative to the corrector
- lightness = lightness < 0.5 ? lightness * corrector * 2 : corrector + (lightness - 0.5) * (1 - corrector) * 2;
-
- return hsl(hue, saturation, lightness);
+/**
+ * Converts an HSL color to a hexadecimal RGB color. This function will correct the lightness for the "dark" hues
+ * @param {number} hue Hue in range [0, 1]
+ * @param {number} saturation Saturation in range [0, 1]
+ * @param {number} lightness Lightness in range [0, 1]
+ * @returns {string}
+ */
+function correctedHsl(hue, saturation, lightness) {
+ // The corrector specifies the perceived middle lightness for each hue
+ var correctors = [ 0.55, 0.5, 0.5, 0.46, 0.6, 0.55, 0.55 ],
+ corrector = correctors[(hue * 6 + 0.5) | 0];
+
+ // Adjust the input lightness relative to the corrector
+ lightness = lightness < 0.5 ? lightness * corrector * 2 : corrector + (lightness - 0.5) * (1 - corrector) * 2;
+
+ return hsl(hue, saturation, lightness);
}
-/* global umdGlobal */
-
-// In the future we can replace `GLOBAL` with `globalThis`, but for now use the old school global detection for
-// backward compatibility.
+/* global umdGlobal */
+
+// In the future we can replace `GLOBAL` with `globalThis`, but for now use the old school global detection for
+// backward compatibility.
var GLOBAL = umdGlobal;
-/**
- * @typedef {Object} ParsedConfiguration
- * @property {number} colorSaturation
- * @property {number} grayscaleSaturation
- * @property {string} backColor
- * @property {number} iconPadding
- * @property {function(number):number} hue
- * @property {function(number):number} colorLightness
- * @property {function(number):number} grayscaleLightness
- */
-
-var CONFIG_PROPERTIES = {
- G/*GLOBAL*/: "jdenticon_config",
- n/*MODULE*/: "config",
-};
-
-var rootConfigurationHolder = {};
-
-/**
- * Defines the deprecated `config` property on the root Jdenticon object without printing a warning in the console
- * when it is being used.
- * @param {!Object} rootObject
- */
-function defineConfigProperty(rootObject) {
- rootConfigurationHolder = rootObject;
-}
-
-/**
- * Sets a new icon style configuration. The new configuration is not merged with the previous one. *
- * @param {Object} newConfiguration - New configuration object.
- */
-function configure(newConfiguration) {
- if (arguments.length) {
- rootConfigurationHolder[CONFIG_PROPERTIES.n/*MODULE*/] = newConfiguration;
- }
- return rootConfigurationHolder[CONFIG_PROPERTIES.n/*MODULE*/];
-}
-
-/**
- * Gets the normalized current Jdenticon color configuration. Missing fields have default values.
- * @param {Object|number|undefined} paddingOrLocalConfig - Configuration passed to the called API method. A
- * local configuration overrides the global configuration in it entirety. This parameter can for backward
- * compatibility also contain a padding value. A padding value only overrides the global padding, not the
- * entire global configuration.
- * @param {number} defaultPadding - Padding used if no padding is specified in neither the configuration nor
- * explicitly to the API method.
- * @returns {ParsedConfiguration}
- */
-function getConfiguration(paddingOrLocalConfig, defaultPadding) {
- var configObject =
- typeof paddingOrLocalConfig == "object" && paddingOrLocalConfig ||
- rootConfigurationHolder[CONFIG_PROPERTIES.n/*MODULE*/] ||
- GLOBAL[CONFIG_PROPERTIES.G/*GLOBAL*/] ||
- { },
-
- lightnessConfig = configObject["lightness"] || { },
-
- // In versions < 2.1.0 there was no grayscale saturation -
- // saturation was the color saturation.
- saturation = configObject["saturation"] || { },
- colorSaturation = "color" in saturation ? saturation["color"] : saturation,
- grayscaleSaturation = saturation["grayscale"],
-
- backColor = configObject["backColor"],
- padding = configObject["padding"];
-
- /**
- * Creates a lightness range.
- */
- function lightness(configName, defaultRange) {
- var range = lightnessConfig[configName];
-
- // Check if the lightness range is an array-like object. This way we ensure the
- // array contain two values at the same time.
- if (!(range && range.length > 1)) {
- range = defaultRange;
- }
-
- /**
- * Gets a lightness relative the specified value in the specified lightness range.
- */
- return function (value) {
- value = range[0] + value * (range[1] - range[0]);
- return value < 0 ? 0 : value > 1 ? 1 : value;
- };
- }
-
- /**
- * Gets a hue allowed by the configured hue restriction,
- * provided the originally computed hue.
- */
- function hueFunction(originalHue) {
- var hueConfig = configObject["hues"];
- var hue;
-
- // Check if 'hues' is an array-like object. This way we also ensure that
- // the array is not empty, which would mean no hue restriction.
- if (hueConfig && hueConfig.length > 0) {
- // originalHue is in the range [0, 1]
- // Multiply with 0.999 to change the range to [0, 1) and then truncate the index.
- hue = hueConfig[0 | (0.999 * originalHue * hueConfig.length)];
- }
-
- return typeof hue == "number" ?
-
- // A hue was specified. We need to convert the hue from
- // degrees on any turn - e.g. 746° is a perfectly valid hue -
- // to turns in the range [0, 1).
- ((((hue / 360) % 1) + 1) % 1) :
-
- // No hue configured => use original hue
- originalHue;
- }
-
- return {
- X/*hue*/: hueFunction,
- p/*colorSaturation*/: typeof colorSaturation == "number" ? colorSaturation : 0.5,
- H/*grayscaleSaturation*/: typeof grayscaleSaturation == "number" ? grayscaleSaturation : 0,
- q/*colorLightness*/: lightness("color", [0.4, 0.8]),
- I/*grayscaleLightness*/: lightness("grayscale", [0.3, 0.9]),
- J/*backColor*/: parseColor(backColor),
- Y/*iconPadding*/:
- typeof paddingOrLocalConfig == "number" ? paddingOrLocalConfig :
- typeof padding == "number" ? padding :
- defaultPadding
- }
+/**
+ * @typedef {Object} ParsedConfiguration
+ * @property {number} colorSaturation
+ * @property {number} grayscaleSaturation
+ * @property {string} backColor
+ * @property {number} iconPadding
+ * @property {function(number):number} hue
+ * @property {function(number):number} colorLightness
+ * @property {function(number):number} grayscaleLightness
+ */
+
+var CONFIG_PROPERTIES = {
+ G/*GLOBAL*/: "jdenticon_config",
+ n/*MODULE*/: "config",
+};
+
+var rootConfigurationHolder = {};
+
+/**
+ * Defines the deprecated `config` property on the root Jdenticon object without printing a warning in the console
+ * when it is being used.
+ * @param {!Object} rootObject
+ */
+function defineConfigProperty(rootObject) {
+ rootConfigurationHolder = rootObject;
+}
+
+/**
+ * Sets a new icon style configuration. The new configuration is not merged with the previous one. *
+ * @param {Object} newConfiguration - New configuration object.
+ */
+function configure(newConfiguration) {
+ if (arguments.length) {
+ rootConfigurationHolder[CONFIG_PROPERTIES.n/*MODULE*/] = newConfiguration;
+ }
+ return rootConfigurationHolder[CONFIG_PROPERTIES.n/*MODULE*/];
+}
+
+/**
+ * Gets the normalized current Jdenticon color configuration. Missing fields have default values.
+ * @param {Object|number|undefined} paddingOrLocalConfig - Configuration passed to the called API method. A
+ * local configuration overrides the global configuration in it entirety. This parameter can for backward
+ * compatibility also contain a padding value. A padding value only overrides the global padding, not the
+ * entire global configuration.
+ * @param {number} defaultPadding - Padding used if no padding is specified in neither the configuration nor
+ * explicitly to the API method.
+ * @returns {ParsedConfiguration}
+ */
+function getConfiguration(paddingOrLocalConfig, defaultPadding) {
+ var configObject =
+ typeof paddingOrLocalConfig == "object" && paddingOrLocalConfig ||
+ rootConfigurationHolder[CONFIG_PROPERTIES.n/*MODULE*/] ||
+ GLOBAL[CONFIG_PROPERTIES.G/*GLOBAL*/] ||
+ { },
+
+ lightnessConfig = configObject["lightness"] || { },
+
+ // In versions < 2.1.0 there was no grayscale saturation -
+ // saturation was the color saturation.
+ saturation = configObject["saturation"] || { },
+ colorSaturation = "color" in saturation ? saturation["color"] : saturation,
+ grayscaleSaturation = saturation["grayscale"],
+
+ backColor = configObject["backColor"],
+ padding = configObject["padding"];
+
+ /**
+ * Creates a lightness range.
+ */
+ function lightness(configName, defaultRange) {
+ var range = lightnessConfig[configName];
+
+ // Check if the lightness range is an array-like object. This way we ensure the
+ // array contain two values at the same time.
+ if (!(range && range.length > 1)) {
+ range = defaultRange;
+ }
+
+ /**
+ * Gets a lightness relative the specified value in the specified lightness range.
+ */
+ return function (value) {
+ value = range[0] + value * (range[1] - range[0]);
+ return value < 0 ? 0 : value > 1 ? 1 : value;
+ };
+ }
+
+ /**
+ * Gets a hue allowed by the configured hue restriction,
+ * provided the originally computed hue.
+ */
+ function hueFunction(originalHue) {
+ var hueConfig = configObject["hues"];
+ var hue;
+
+ // Check if 'hues' is an array-like object. This way we also ensure that
+ // the array is not empty, which would mean no hue restriction.
+ if (hueConfig && hueConfig.length > 0) {
+ // originalHue is in the range [0, 1]
+ // Multiply with 0.999 to change the range to [0, 1) and then truncate the index.
+ hue = hueConfig[0 | (0.999 * originalHue * hueConfig.length)];
+ }
+
+ return typeof hue == "number" ?
+
+ // A hue was specified. We need to convert the hue from
+ // degrees on any turn - e.g. 746° is a perfectly valid hue -
+ // to turns in the range [0, 1).
+ ((((hue / 360) % 1) + 1) % 1) :
+
+ // No hue configured => use original hue
+ originalHue;
+ }
+
+ return {
+ X/*hue*/: hueFunction,
+ p/*colorSaturation*/: typeof colorSaturation == "number" ? colorSaturation : 0.5,
+ H/*grayscaleSaturation*/: typeof grayscaleSaturation == "number" ? grayscaleSaturation : 0,
+ q/*colorLightness*/: lightness("color", [0.4, 0.8]),
+ I/*grayscaleLightness*/: lightness("grayscale", [0.3, 0.9]),
+ J/*backColor*/: parseColor(backColor),
+ Y/*iconPadding*/:
+ typeof paddingOrLocalConfig == "number" ? paddingOrLocalConfig :
+ typeof padding == "number" ? padding :
+ defaultPadding
+ }
+}
+
+var ICON_TYPE_SVG = 1;
+
+var ICON_TYPE_CANVAS = 2;
+
+var ATTRIBUTES = {
+ t/*HASH*/: "data-jdenticon-hash",
+ o/*VALUE*/: "data-jdenticon-value"
+};
+
+var IS_RENDERED_PROPERTY = "jdenticonRendered";
+
+var ICON_SELECTOR = "[" + ATTRIBUTES.t/*HASH*/ +"],[" + ATTRIBUTES.o/*VALUE*/ +"]";
+
+var documentQuerySelectorAll = /** @type {!Function} */ (
+ typeof document !== "undefined" && document.querySelectorAll.bind(document));
+
+function getIdenticonType(el) {
+ if (el) {
+ var tagName = el["tagName"];
+
+ if (/^svg$/i.test(tagName)) {
+ return ICON_TYPE_SVG;
+ }
+
+ if (/^canvas$/i.test(tagName) && "getContext" in el) {
+ return ICON_TYPE_CANVAS;
+ }
+ }
}
-var ICON_TYPE_SVG = 1;
-
-var ICON_TYPE_CANVAS = 2;
-
-var ATTRIBUTES = {
- t/*HASH*/: "data-jdenticon-hash",
- o/*VALUE*/: "data-jdenticon-value"
-};
-
-var IS_RENDERED_PROPERTY = "jdenticonRendered";
-
-var ICON_SELECTOR = "[" + ATTRIBUTES.t/*HASH*/ +"],[" + ATTRIBUTES.o/*VALUE*/ +"]";
-
-var documentQuerySelectorAll = /** @type {!Function} */ (
- typeof document !== "undefined" && document.querySelectorAll.bind(document));
-
-function getIdenticonType(el) {
- if (el) {
- var tagName = el["tagName"];
-
- if (/^svg$/i.test(tagName)) {
- return ICON_TYPE_SVG;
- }
-
- if (/^canvas$/i.test(tagName) && "getContext" in el) {
- return ICON_TYPE_CANVAS;
- }
- }
-}
-
-function whenDocumentIsReady(/** @type {Function} */ callback) {
- function loadedHandler() {
- document.removeEventListener("DOMContentLoaded", loadedHandler);
- window.removeEventListener("load", loadedHandler);
- setTimeout(callback, 0); // Give scripts a chance to run
- }
-
- if (typeof document !== "undefined" &&
- typeof window !== "undefined" &&
- typeof setTimeout !== "undefined"
- ) {
- if (document.readyState === "loading") {
- document.addEventListener("DOMContentLoaded", loadedHandler);
- window.addEventListener("load", loadedHandler);
- } else {
- // Document already loaded. The load events above likely won't be raised
- setTimeout(callback, 0);
- }
- }
+function whenDocumentIsReady(/** @type {Function} */ callback) {
+ function loadedHandler() {
+ document.removeEventListener("DOMContentLoaded", loadedHandler);
+ window.removeEventListener("load", loadedHandler);
+ setTimeout(callback, 0); // Give scripts a chance to run
+ }
+
+ if (typeof document !== "undefined" &&
+ typeof window !== "undefined" &&
+ typeof setTimeout !== "undefined"
+ ) {
+ if (document.readyState === "loading") {
+ document.addEventListener("DOMContentLoaded", loadedHandler);
+ window.addEventListener("load", loadedHandler);
+ } else {
+ // Document already loaded. The load events above likely won't be raised
+ setTimeout(callback, 0);
+ }
+ }
}
-function observer(updateCallback) {
- if (typeof MutationObserver != "undefined") {
- var mutationObserver = new MutationObserver(function onmutation(mutations) {
- for (var mutationIndex = 0; mutationIndex < mutations.length; mutationIndex++) {
- var mutation = mutations[mutationIndex];
- var addedNodes = mutation.addedNodes;
-
- for (var addedNodeIndex = 0; addedNodes && addedNodeIndex < addedNodes.length; addedNodeIndex++) {
- var addedNode = addedNodes[addedNodeIndex];
-
- // Skip other types of nodes than element nodes, since they might not support
- // the querySelectorAll method => runtime error.
- if (addedNode.nodeType == 1) {
- if (getIdenticonType(addedNode)) {
- updateCallback(addedNode);
- }
- else {
- var icons = /** @type {Element} */(addedNode).querySelectorAll(ICON_SELECTOR);
- for (var iconIndex = 0; iconIndex < icons.length; iconIndex++) {
- updateCallback(icons[iconIndex]);
- }
- }
- }
- }
-
- if (mutation.type == "attributes" && getIdenticonType(mutation.target)) {
- updateCallback(mutation.target);
- }
- }
- });
-
- mutationObserver.observe(document.body, {
- "childList": true,
- "attributes": true,
- "attributeFilter": [ATTRIBUTES.o/*VALUE*/, ATTRIBUTES.t/*HASH*/, "width", "height"],
- "subtree": true,
- });
- }
+function observer(updateCallback) {
+ if (typeof MutationObserver != "undefined") {
+ var mutationObserver = new MutationObserver(function onmutation(mutations) {
+ for (var mutationIndex = 0; mutationIndex < mutations.length; mutationIndex++) {
+ var mutation = mutations[mutationIndex];
+ var addedNodes = mutation.addedNodes;
+
+ for (var addedNodeIndex = 0; addedNodes && addedNodeIndex < addedNodes.length; addedNodeIndex++) {
+ var addedNode = addedNodes[addedNodeIndex];
+
+ // Skip other types of nodes than element nodes, since they might not support
+ // the querySelectorAll method => runtime error.
+ if (addedNode.nodeType == 1) {
+ if (getIdenticonType(addedNode)) {
+ updateCallback(addedNode);
+ }
+ else {
+ var icons = /** @type {Element} */(addedNode).querySelectorAll(ICON_SELECTOR);
+ for (var iconIndex = 0; iconIndex < icons.length; iconIndex++) {
+ updateCallback(icons[iconIndex]);
+ }
+ }
+ }
+ }
+
+ if (mutation.type == "attributes" && getIdenticonType(mutation.target)) {
+ updateCallback(mutation.target);
+ }
+ }
+ });
+
+ mutationObserver.observe(document.body, {
+ "childList": true,
+ "attributes": true,
+ "attributeFilter": [ATTRIBUTES.o/*VALUE*/, ATTRIBUTES.t/*HASH*/, "width", "height"],
+ "subtree": true,
+ });
+ }
}
-/**
- * Represents a point.
- */
-function Point(x, y) {
- this.x = x;
- this.y = y;
+/**
+ * Represents a point.
+ */
+function Point(x, y) {
+ this.x = x;
+ this.y = y;
}
-/**
- * Translates and rotates a point before being passed on to the canvas context. This was previously done by the canvas context itself,
- * but this caused a rendering issue in Chrome on sizes > 256 where the rotation transformation of inverted paths was not done properly.
- */
-function Transform(x, y, size, rotation) {
- this.u/*_x*/ = x;
- this.v/*_y*/ = y;
- this.K/*_size*/ = size;
- this.Z/*_rotation*/ = rotation;
-}
-
-/**
- * Transforms the specified point based on the translation and rotation specification for this Transform.
- * @param {number} x x-coordinate
- * @param {number} y y-coordinate
- * @param {number=} w The width of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle.
- * @param {number=} h The height of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle.
- */
-Transform.prototype.L/*transformIconPoint*/ = function transformIconPoint (x, y, w, h) {
- var right = this.u/*_x*/ + this.K/*_size*/,
- bottom = this.v/*_y*/ + this.K/*_size*/,
- rotation = this.Z/*_rotation*/;
- return rotation === 1 ? new Point(right - y - (h || 0), this.v/*_y*/ + x) :
- rotation === 2 ? new Point(right - x - (w || 0), bottom - y - (h || 0)) :
- rotation === 3 ? new Point(this.u/*_x*/ + y, bottom - x - (w || 0)) :
- new Point(this.u/*_x*/ + x, this.v/*_y*/ + y);
-};
-
+/**
+ * Translates and rotates a point before being passed on to the canvas context. This was previously done by the canvas context itself,
+ * but this caused a rendering issue in Chrome on sizes > 256 where the rotation transformation of inverted paths was not done properly.
+ */
+function Transform(x, y, size, rotation) {
+ this.u/*_x*/ = x;
+ this.v/*_y*/ = y;
+ this.K/*_size*/ = size;
+ this.Z/*_rotation*/ = rotation;
+}
+
+/**
+ * Transforms the specified point based on the translation and rotation specification for this Transform.
+ * @param {number} x x-coordinate
+ * @param {number} y y-coordinate
+ * @param {number=} w The width of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle.
+ * @param {number=} h The height of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle.
+ */
+Transform.prototype.L/*transformIconPoint*/ = function transformIconPoint (x, y, w, h) {
+ var right = this.u/*_x*/ + this.K/*_size*/,
+ bottom = this.v/*_y*/ + this.K/*_size*/,
+ rotation = this.Z/*_rotation*/;
+ return rotation === 1 ? new Point(right - y - (h || 0), this.v/*_y*/ + x) :
+ rotation === 2 ? new Point(right - x - (w || 0), bottom - y - (h || 0)) :
+ rotation === 3 ? new Point(this.u/*_x*/ + y, bottom - x - (w || 0)) :
+ new Point(this.u/*_x*/ + x, this.v/*_y*/ + y);
+};
+
var NO_TRANSFORM = new Transform(0, 0, 0, 0);
-
-
-/**
- * Provides helper functions for rendering common basic shapes.
- */
-function Graphics(renderer) {
- /**
- * @type {Renderer}
- * @private
- */
- this.M/*_renderer*/ = renderer;
-
- /**
- * @type {Transform}
- */
- this.A/*currentTransform*/ = NO_TRANSFORM;
-}
-var Graphics__prototype = Graphics.prototype;
-
-/**
- * Adds a polygon to the underlying renderer.
- * @param {Array} points The points of the polygon clockwise on the format [ x0, y0, x1, y1, ..., xn, yn ]
- * @param {boolean=} invert Specifies if the polygon will be inverted.
- */
+
+
+/**
+ * Provides helper functions for rendering common basic shapes.
+ */
+function Graphics(renderer) {
+ /**
+ * @type {Renderer}
+ * @private
+ */
+ this.M/*_renderer*/ = renderer;
+
+ /**
+ * @type {Transform}
+ */
+ this.A/*currentTransform*/ = NO_TRANSFORM;
+}
+var Graphics__prototype = Graphics.prototype;
+
+/**
+ * Adds a polygon to the underlying renderer.
+ * @param {Array} points The points of the polygon clockwise on the format [ x0, y0, x1, y1, ..., xn, yn ]
+ * @param {boolean=} invert Specifies if the polygon will be inverted.
+ */
Graphics__prototype.g/*addPolygon*/ = function addPolygon (points, invert) {
var this$1 = this;
-
- var di = invert ? -2 : 2,
- transformedPoints = [];
-
- for (var i = invert ? points.length - 2 : 0; i < points.length && i >= 0; i += di) {
- transformedPoints.push(this$1.A/*currentTransform*/.L/*transformIconPoint*/(points[i], points[i + 1]));
- }
-
- this.M/*_renderer*/.g/*addPolygon*/(transformedPoints);
-};
-
-/**
- * Adds a polygon to the underlying renderer.
- * Source: http://stackoverflow.com/a/2173084
- * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the entire ellipse.
- * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the entire ellipse.
- * @param {number} size The size of the ellipse.
- * @param {boolean=} invert Specifies if the ellipse will be inverted.
- */
-Graphics__prototype.h/*addCircle*/ = function addCircle (x, y, size, invert) {
- var p = this.A/*currentTransform*/.L/*transformIconPoint*/(x, y, size, size);
- this.M/*_renderer*/.h/*addCircle*/(p, size, invert);
-};
-
-/**
- * Adds a rectangle to the underlying renderer.
- * @param {number} x The x-coordinate of the upper left corner of the rectangle.
- * @param {number} y The y-coordinate of the upper left corner of the rectangle.
- * @param {number} w The width of the rectangle.
- * @param {number} h The height of the rectangle.
- * @param {boolean=} invert Specifies if the rectangle will be inverted.
- */
-Graphics__prototype.i/*addRectangle*/ = function addRectangle (x, y, w, h, invert) {
- this.g/*addPolygon*/([
- x, y,
- x + w, y,
- x + w, y + h,
- x, y + h
- ], invert);
-};
-
-/**
- * Adds a right triangle to the underlying renderer.
- * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the triangle.
- * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the triangle.
- * @param {number} w The width of the triangle.
- * @param {number} h The height of the triangle.
- * @param {number} r The rotation of the triangle (clockwise). 0 = right corner of the triangle in the lower left corner of the bounding rectangle.
- * @param {boolean=} invert Specifies if the triangle will be inverted.
- */
-Graphics__prototype.j/*addTriangle*/ = function addTriangle (x, y, w, h, r, invert) {
- var points = [
- x + w, y,
- x + w, y + h,
- x, y + h,
- x, y
- ];
- points.splice(((r || 0) % 4) * 2, 2);
- this.g/*addPolygon*/(points, invert);
-};
-
-/**
- * Adds a rhombus to the underlying renderer.
- * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the rhombus.
- * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the rhombus.
- * @param {number} w The width of the rhombus.
- * @param {number} h The height of the rhombus.
- * @param {boolean=} invert Specifies if the rhombus will be inverted.
- */
-Graphics__prototype.N/*addRhombus*/ = function addRhombus (x, y, w, h, invert) {
- this.g/*addPolygon*/([
- x + w / 2, y,
- x + w, y + h / 2,
- x + w / 2, y + h,
- x, y + h / 2
- ], invert);
+
+ var di = invert ? -2 : 2,
+ transformedPoints = [];
+
+ for (var i = invert ? points.length - 2 : 0; i < points.length && i >= 0; i += di) {
+ transformedPoints.push(this$1.A/*currentTransform*/.L/*transformIconPoint*/(points[i], points[i + 1]));
+ }
+
+ this.M/*_renderer*/.g/*addPolygon*/(transformedPoints);
+};
+
+/**
+ * Adds a polygon to the underlying renderer.
+ * Source: http://stackoverflow.com/a/2173084
+ * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the entire ellipse.
+ * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the entire ellipse.
+ * @param {number} size The size of the ellipse.
+ * @param {boolean=} invert Specifies if the ellipse will be inverted.
+ */
+Graphics__prototype.h/*addCircle*/ = function addCircle (x, y, size, invert) {
+ var p = this.A/*currentTransform*/.L/*transformIconPoint*/(x, y, size, size);
+ this.M/*_renderer*/.h/*addCircle*/(p, size, invert);
+};
+
+/**
+ * Adds a rectangle to the underlying renderer.
+ * @param {number} x The x-coordinate of the upper left corner of the rectangle.
+ * @param {number} y The y-coordinate of the upper left corner of the rectangle.
+ * @param {number} w The width of the rectangle.
+ * @param {number} h The height of the rectangle.
+ * @param {boolean=} invert Specifies if the rectangle will be inverted.
+ */
+Graphics__prototype.i/*addRectangle*/ = function addRectangle (x, y, w, h, invert) {
+ this.g/*addPolygon*/([
+ x, y,
+ x + w, y,
+ x + w, y + h,
+ x, y + h
+ ], invert);
+};
+
+/**
+ * Adds a right triangle to the underlying renderer.
+ * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the triangle.
+ * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the triangle.
+ * @param {number} w The width of the triangle.
+ * @param {number} h The height of the triangle.
+ * @param {number} r The rotation of the triangle (clockwise). 0 = right corner of the triangle in the lower left corner of the bounding rectangle.
+ * @param {boolean=} invert Specifies if the triangle will be inverted.
+ */
+Graphics__prototype.j/*addTriangle*/ = function addTriangle (x, y, w, h, r, invert) {
+ var points = [
+ x + w, y,
+ x + w, y + h,
+ x, y + h,
+ x, y
+ ];
+ points.splice(((r || 0) % 4) * 2, 2);
+ this.g/*addPolygon*/(points, invert);
};
-/**
- * @param {number} index
- * @param {Graphics} g
- * @param {number} cell
- * @param {number} positionIndex
- */
-function centerShape(index, g, cell, positionIndex) {
- index = index % 14;
-
- var k, m, w, h, inner, outer;
-
- !index ? (
- k = cell * 0.42,
- g.g/*addPolygon*/([
- 0, 0,
- cell, 0,
- cell, cell - k * 2,
- cell - k, cell,
- 0, cell
- ])) :
-
- index == 1 ? (
- w = 0 | (cell * 0.5),
- h = 0 | (cell * 0.8),
-
- g.j/*addTriangle*/(cell - w, 0, w, h, 2)) :
-
- index == 2 ? (
- w = 0 | (cell / 3),
- g.i/*addRectangle*/(w, w, cell - w, cell - w)) :
-
- index == 3 ? (
- inner = cell * 0.1,
- // Use fixed outer border widths in small icons to ensure the border is drawn
- outer =
- cell < 6 ? 1 :
- cell < 8 ? 2 :
- (0 | (cell * 0.25)),
-
- inner =
- inner > 1 ? (0 | inner) : // large icon => truncate decimals
- inner > 0.5 ? 1 : // medium size icon => fixed width
- inner, // small icon => anti-aliased border
-
- g.i/*addRectangle*/(outer, outer, cell - inner - outer, cell - inner - outer)) :
-
- index == 4 ? (
- m = 0 | (cell * 0.15),
- w = 0 | (cell * 0.5),
- g.h/*addCircle*/(cell - w - m, cell - w - m, w)) :
-
- index == 5 ? (
- inner = cell * 0.1,
- outer = inner * 4,
-
- // Align edge to nearest pixel in large icons
- outer > 3 && (outer = 0 | outer),
-
- g.i/*addRectangle*/(0, 0, cell, cell),
- g.g/*addPolygon*/([
- outer, outer,
- cell - inner, outer,
- outer + (cell - outer - inner) / 2, cell - inner
- ], true)) :
-
- index == 6 ?
- g.g/*addPolygon*/([
- 0, 0,
- cell, 0,
- cell, cell * 0.7,
- cell * 0.4, cell * 0.4,
- cell * 0.7, cell,
- 0, cell
- ]) :
-
- index == 7 ?
- g.j/*addTriangle*/(cell / 2, cell / 2, cell / 2, cell / 2, 3) :
-
- index == 8 ? (
- g.i/*addRectangle*/(0, 0, cell, cell / 2),
- g.i/*addRectangle*/(0, cell / 2, cell / 2, cell / 2),
- g.j/*addTriangle*/(cell / 2, cell / 2, cell / 2, cell / 2, 1)) :
-
- index == 9 ? (
- inner = cell * 0.14,
- // Use fixed outer border widths in small icons to ensure the border is drawn
- outer =
- cell < 4 ? 1 :
- cell < 6 ? 2 :
- (0 | (cell * 0.35)),
-
- inner =
- cell < 8 ? inner : // small icon => anti-aliased border
- (0 | inner), // large icon => truncate decimals
-
- g.i/*addRectangle*/(0, 0, cell, cell),
- g.i/*addRectangle*/(outer, outer, cell - outer - inner, cell - outer - inner, true)) :
-
- index == 10 ? (
- inner = cell * 0.12,
- outer = inner * 3,
-
- g.i/*addRectangle*/(0, 0, cell, cell),
- g.h/*addCircle*/(outer, outer, cell - inner - outer, true)) :
-
- index == 11 ?
- g.j/*addTriangle*/(cell / 2, cell / 2, cell / 2, cell / 2, 3) :
-
- index == 12 ? (
- m = cell * 0.25,
- g.i/*addRectangle*/(0, 0, cell, cell),
- g.N/*addRhombus*/(m, m, cell - m, cell - m, true)) :
-
- // 13
- (
- !positionIndex && (
- m = cell * 0.4, w = cell * 1.2,
- g.h/*addCircle*/(m, m, w)
- )
- );
-}
-
-/**
- * @param {number} index
- * @param {Graphics} g
- * @param {number} cell
- */
-function outerShape(index, g, cell) {
- index = index % 4;
-
- var m;
-
- !index ?
- g.j/*addTriangle*/(0, 0, cell, cell, 0) :
-
- index == 1 ?
- g.j/*addTriangle*/(0, cell / 2, cell, cell / 2, 0) :
-
- index == 2 ?
- g.N/*addRhombus*/(0, 0, cell, cell) :
-
- // 3
- (
- m = cell / 6,
- g.h/*addCircle*/(m, m, cell - 2 * m)
- );
+/**
+ * Adds a rhombus to the underlying renderer.
+ * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the rhombus.
+ * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the rhombus.
+ * @param {number} w The width of the rhombus.
+ * @param {number} h The height of the rhombus.
+ * @param {boolean=} invert Specifies if the rhombus will be inverted.
+ */
+Graphics__prototype.N/*addRhombus*/ = function addRhombus (x, y, w, h, invert) {
+ this.g/*addPolygon*/([
+ x + w / 2, y,
+ x + w, y + h / 2,
+ x + w / 2, y + h,
+ x, y + h / 2
+ ], invert);
+};
+
+/**
+ * @param {number} index
+ * @param {Graphics} g
+ * @param {number} cell
+ * @param {number} positionIndex
+ */
+function centerShape(index, g, cell, positionIndex) {
+ index = index % 14;
+
+ var k, m, w, h, inner, outer;
+
+ !index ? (
+ k = cell * 0.42,
+ g.g/*addPolygon*/([
+ 0, 0,
+ cell, 0,
+ cell, cell - k * 2,
+ cell - k, cell,
+ 0, cell
+ ])) :
+
+ index == 1 ? (
+ w = 0 | (cell * 0.5),
+ h = 0 | (cell * 0.8),
+
+ g.j/*addTriangle*/(cell - w, 0, w, h, 2)) :
+
+ index == 2 ? (
+ w = 0 | (cell / 3),
+ g.i/*addRectangle*/(w, w, cell - w, cell - w)) :
+
+ index == 3 ? (
+ inner = cell * 0.1,
+ // Use fixed outer border widths in small icons to ensure the border is drawn
+ outer =
+ cell < 6 ? 1 :
+ cell < 8 ? 2 :
+ (0 | (cell * 0.25)),
+
+ inner =
+ inner > 1 ? (0 | inner) : // large icon => truncate decimals
+ inner > 0.5 ? 1 : // medium size icon => fixed width
+ inner, // small icon => anti-aliased border
+
+ g.i/*addRectangle*/(outer, outer, cell - inner - outer, cell - inner - outer)) :
+
+ index == 4 ? (
+ m = 0 | (cell * 0.15),
+ w = 0 | (cell * 0.5),
+ g.h/*addCircle*/(cell - w - m, cell - w - m, w)) :
+
+ index == 5 ? (
+ inner = cell * 0.1,
+ outer = inner * 4,
+
+ // Align edge to nearest pixel in large icons
+ outer > 3 && (outer = 0 | outer),
+
+ g.i/*addRectangle*/(0, 0, cell, cell),
+ g.g/*addPolygon*/([
+ outer, outer,
+ cell - inner, outer,
+ outer + (cell - outer - inner) / 2, cell - inner
+ ], true)) :
+
+ index == 6 ?
+ g.g/*addPolygon*/([
+ 0, 0,
+ cell, 0,
+ cell, cell * 0.7,
+ cell * 0.4, cell * 0.4,
+ cell * 0.7, cell,
+ 0, cell
+ ]) :
+
+ index == 7 ?
+ g.j/*addTriangle*/(cell / 2, cell / 2, cell / 2, cell / 2, 3) :
+
+ index == 8 ? (
+ g.i/*addRectangle*/(0, 0, cell, cell / 2),
+ g.i/*addRectangle*/(0, cell / 2, cell / 2, cell / 2),
+ g.j/*addTriangle*/(cell / 2, cell / 2, cell / 2, cell / 2, 1)) :
+
+ index == 9 ? (
+ inner = cell * 0.14,
+ // Use fixed outer border widths in small icons to ensure the border is drawn
+ outer =
+ cell < 4 ? 1 :
+ cell < 6 ? 2 :
+ (0 | (cell * 0.35)),
+
+ inner =
+ cell < 8 ? inner : // small icon => anti-aliased border
+ (0 | inner), // large icon => truncate decimals
+
+ g.i/*addRectangle*/(0, 0, cell, cell),
+ g.i/*addRectangle*/(outer, outer, cell - outer - inner, cell - outer - inner, true)) :
+
+ index == 10 ? (
+ inner = cell * 0.12,
+ outer = inner * 3,
+
+ g.i/*addRectangle*/(0, 0, cell, cell),
+ g.h/*addCircle*/(outer, outer, cell - inner - outer, true)) :
+
+ index == 11 ?
+ g.j/*addTriangle*/(cell / 2, cell / 2, cell / 2, cell / 2, 3) :
+
+ index == 12 ? (
+ m = cell * 0.25,
+ g.i/*addRectangle*/(0, 0, cell, cell),
+ g.N/*addRhombus*/(m, m, cell - m, cell - m, true)) :
+
+ // 13
+ (
+ !positionIndex && (
+ m = cell * 0.4, w = cell * 1.2,
+ g.h/*addCircle*/(m, m, w)
+ )
+ );
}
-/**
- * Gets a set of identicon color candidates for a specified hue and config.
- * @param {number} hue
- * @param {ParsedConfiguration} config
- */
-function colorTheme(hue, config) {
- hue = config.X/*hue*/(hue);
- return [
- // Dark gray
- correctedHsl(hue, config.H/*grayscaleSaturation*/, config.I/*grayscaleLightness*/(0)),
- // Mid color
- correctedHsl(hue, config.p/*colorSaturation*/, config.q/*colorLightness*/(0.5)),
- // Light gray
- correctedHsl(hue, config.H/*grayscaleSaturation*/, config.I/*grayscaleLightness*/(1)),
- // Light color
- correctedHsl(hue, config.p/*colorSaturation*/, config.q/*colorLightness*/(1)),
- // Dark color
- correctedHsl(hue, config.p/*colorSaturation*/, config.q/*colorLightness*/(0))
- ];
+/**
+ * @param {number} index
+ * @param {Graphics} g
+ * @param {number} cell
+ */
+function outerShape(index, g, cell) {
+ index = index % 4;
+
+ var m;
+
+ !index ?
+ g.j/*addTriangle*/(0, 0, cell, cell, 0) :
+
+ index == 1 ?
+ g.j/*addTriangle*/(0, cell / 2, cell, cell / 2, 0) :
+
+ index == 2 ?
+ g.N/*addRhombus*/(0, 0, cell, cell) :
+
+ // 3
+ (
+ m = cell / 6,
+ g.h/*addCircle*/(m, m, cell - 2 * m)
+ );
}
-/**
- * Draws an identicon to a specified renderer.
- * @param {Renderer} renderer
- * @param {string} hash
- * @param {Object|number=} config
- */
-function iconGenerator(renderer, hash, config) {
- var parsedConfig = getConfiguration(config, 0.08);
-
- // Set background color
- if (parsedConfig.J/*backColor*/) {
- renderer.m/*setBackground*/(parsedConfig.J/*backColor*/);
- }
-
- // Calculate padding and round to nearest integer
- var size = renderer.k/*iconSize*/;
- var padding = (0.5 + size * parsedConfig.Y/*iconPadding*/) | 0;
- size -= padding * 2;
-
- var graphics = new Graphics(renderer);
-
- // Calculate cell size and ensure it is an integer
- var cell = 0 | (size / 4);
-
- // Since the cell size is integer based, the actual icon will be slightly smaller than specified => center icon
- var x = 0 | (padding + size / 2 - cell * 2);
- var y = 0 | (padding + size / 2 - cell * 2);
-
- function renderShape(colorIndex, shapes, index, rotationIndex, positions) {
- var shapeIndex = parseHex(hash, index, 1);
- var r = rotationIndex ? parseHex(hash, rotationIndex, 1) : 0;
-
- renderer.O/*beginShape*/(availableColors[selectedColorIndexes[colorIndex]]);
-
- for (var i = 0; i < positions.length; i++) {
- graphics.A/*currentTransform*/ = new Transform(x + positions[i][0] * cell, y + positions[i][1] * cell, cell, r++ % 4);
- shapes(shapeIndex, graphics, cell, i);
- }
-
- renderer.P/*endShape*/();
- }
-
- // AVAILABLE COLORS
- var hue = parseHex(hash, -7) / 0xfffffff,
-
- // Available colors for this icon
- availableColors = colorTheme(hue, parsedConfig),
-
- // The index of the selected colors
- selectedColorIndexes = [];
-
- var index;
-
- function isDuplicate(values) {
- if (values.indexOf(index) >= 0) {
- for (var i = 0; i < values.length; i++) {
- if (selectedColorIndexes.indexOf(values[i]) >= 0) {
- return true;
- }
- }
- }
- }
-
- for (var i = 0; i < 3; i++) {
- index = parseHex(hash, 8 + i, 1) % availableColors.length;
- if (isDuplicate([0, 4]) || // Disallow dark gray and dark color combo
- isDuplicate([2, 3])) { // Disallow light gray and light color combo
- index = 1;
- }
- selectedColorIndexes.push(index);
- }
-
- // ACTUAL RENDERING
- // Sides
- renderShape(0, outerShape, 2, 3, [[1, 0], [2, 0], [2, 3], [1, 3], [0, 1], [3, 1], [3, 2], [0, 2]]);
- // Corners
- renderShape(1, outerShape, 4, 5, [[0, 0], [3, 0], [3, 3], [0, 3]]);
- // Center
- renderShape(2, centerShape, 1, null, [[1, 1], [2, 1], [2, 2], [1, 2]]);
-
- renderer.finish();
+/**
+ * Gets a set of identicon color candidates for a specified hue and config.
+ * @param {number} hue
+ * @param {ParsedConfiguration} config
+ */
+function colorTheme(hue, config) {
+ hue = config.X/*hue*/(hue);
+ return [
+ // Dark gray
+ correctedHsl(hue, config.H/*grayscaleSaturation*/, config.I/*grayscaleLightness*/(0)),
+ // Mid color
+ correctedHsl(hue, config.p/*colorSaturation*/, config.q/*colorLightness*/(0.5)),
+ // Light gray
+ correctedHsl(hue, config.H/*grayscaleSaturation*/, config.I/*grayscaleLightness*/(1)),
+ // Light color
+ correctedHsl(hue, config.p/*colorSaturation*/, config.q/*colorLightness*/(1)),
+ // Dark color
+ correctedHsl(hue, config.p/*colorSaturation*/, config.q/*colorLightness*/(0))
+ ];
}
-/**
- * Computes a SHA1 hash for any value and returns it as a hexadecimal string.
- *
- * This function is optimized for minimal code size and rather short messages.
- *
- * @param {string} message
- */
-function sha1(message) {
- var HASH_SIZE_HALF_BYTES = 40;
- var BLOCK_SIZE_WORDS = 16;
-
- // Variables
- // `var` is used to be able to minimize the number of `var` keywords.
- var i = 0,
- f = 0,
-
- // Use `encodeURI` to UTF8 encode the message without any additional libraries
- // We could use `unescape` + `encodeURI` to minimize the code, but that would be slightly risky
- // since `unescape` is deprecated.
- urlEncodedMessage = encodeURI(message) + "%80", // trailing '1' bit padding
-
- // This can be changed to a preallocated Uint32Array array for greater performance and larger code size
- data = [],
- dataSize,
-
- hashBuffer = [],
-
- a = 0x67452301,
- b = 0xefcdab89,
- c = ~a,
- d = ~b,
- e = 0xc3d2e1f0,
- hash = [a, b, c, d, e],
-
- blockStartIndex = 0,
- hexHash = "";
-
- /**
- * Rotates the value a specified number of bits to the left.
- * @param {number} value Value to rotate
- * @param {number} shift Bit count to shift.
- */
- function rotl(value, shift) {
- return (value << shift) | (value >>> (32 - shift));
- }
-
- // Message data
- for ( ; i < urlEncodedMessage.length; f++) {
- data[f >> 2] = data[f >> 2] |
- (
- (
- urlEncodedMessage[i] == "%"
- // Percent encoded byte
- ? parseInt(urlEncodedMessage.substring(i + 1, i += 3), 16)
- // Unencoded byte
- : urlEncodedMessage.charCodeAt(i++)
- )
-
- // Read bytes in reverse order (big endian words)
- << ((3 - (f & 3)) * 8)
- );
- }
-
- // f is now the length of the utf8 encoded message
- // 7 = 8 bytes (64 bit) for message size, -1 to round down
- // >> 6 = integer division with block size
- dataSize = (((f + 7) >> 6) + 1) * BLOCK_SIZE_WORDS;
-
- // Message size in bits.
- // SHA1 uses a 64 bit integer to represent the size, but since we only support short messages only the least
- // significant 32 bits are set. -8 is for the '1' bit padding byte.
- data[dataSize - 1] = f * 8 - 8;
-
- // Compute hash
- for ( ; blockStartIndex < dataSize; blockStartIndex += BLOCK_SIZE_WORDS) {
- for (i = 0; i < 80; i++) {
- f = rotl(a, 5) + e + (
- // Ch
- i < 20 ? ((b & c) ^ ((~b) & d)) + 0x5a827999 :
-
- // Parity
- i < 40 ? (b ^ c ^ d) + 0x6ed9eba1 :
-
- // Maj
- i < 60 ? ((b & c) ^ (b & d) ^ (c & d)) + 0x8f1bbcdc :
-
- // Parity
- (b ^ c ^ d) + 0xca62c1d6
- ) + (
- hashBuffer[i] = i < BLOCK_SIZE_WORDS
- // Bitwise OR is used to coerse `undefined` to 0
- ? (data[blockStartIndex + i] | 0)
- : rotl(hashBuffer[i - 3] ^ hashBuffer[i - 8] ^ hashBuffer[i - 14] ^ hashBuffer[i - 16], 1)
- );
-
- e = d;
- d = c;
- c = rotl(b, 30);
- b = a;
- a = f;
- }
-
- hash[0] = a = ((hash[0] + a) | 0);
- hash[1] = b = ((hash[1] + b) | 0);
- hash[2] = c = ((hash[2] + c) | 0);
- hash[3] = d = ((hash[3] + d) | 0);
- hash[4] = e = ((hash[4] + e) | 0);
- }
-
- // Format hex hash
- for (i = 0; i < HASH_SIZE_HALF_BYTES; i++) {
- hexHash += (
- (
- // Get word (2^3 half-bytes per word)
- hash[i >> 3] >>>
-
- // Append half-bytes in reverse order
- ((7 - (i & 7)) * 4)
- )
- // Clamp to half-byte
- & 0xf
- ).toString(16);
- }
-
- return hexHash;
+/**
+ * Draws an identicon to a specified renderer.
+ * @param {Renderer} renderer
+ * @param {string} hash
+ * @param {Object|number=} config
+ */
+function iconGenerator(renderer, hash, config) {
+ var parsedConfig = getConfiguration(config, 0.08);
+
+ // Set background color
+ if (parsedConfig.J/*backColor*/) {
+ renderer.m/*setBackground*/(parsedConfig.J/*backColor*/);
+ }
+
+ // Calculate padding and round to nearest integer
+ var size = renderer.k/*iconSize*/;
+ var padding = (0.5 + size * parsedConfig.Y/*iconPadding*/) | 0;
+ size -= padding * 2;
+
+ var graphics = new Graphics(renderer);
+
+ // Calculate cell size and ensure it is an integer
+ var cell = 0 | (size / 4);
+
+ // Since the cell size is integer based, the actual icon will be slightly smaller than specified => center icon
+ var x = 0 | (padding + size / 2 - cell * 2);
+ var y = 0 | (padding + size / 2 - cell * 2);
+
+ function renderShape(colorIndex, shapes, index, rotationIndex, positions) {
+ var shapeIndex = parseHex(hash, index, 1);
+ var r = rotationIndex ? parseHex(hash, rotationIndex, 1) : 0;
+
+ renderer.O/*beginShape*/(availableColors[selectedColorIndexes[colorIndex]]);
+
+ for (var i = 0; i < positions.length; i++) {
+ graphics.A/*currentTransform*/ = new Transform(x + positions[i][0] * cell, y + positions[i][1] * cell, cell, r++ % 4);
+ shapes(shapeIndex, graphics, cell, i);
+ }
+
+ renderer.P/*endShape*/();
+ }
+
+ // AVAILABLE COLORS
+ var hue = parseHex(hash, -7) / 0xfffffff,
+
+ // Available colors for this icon
+ availableColors = colorTheme(hue, parsedConfig),
+
+ // The index of the selected colors
+ selectedColorIndexes = [];
+
+ var index;
+
+ function isDuplicate(values) {
+ if (values.indexOf(index) >= 0) {
+ for (var i = 0; i < values.length; i++) {
+ if (selectedColorIndexes.indexOf(values[i]) >= 0) {
+ return true;
+ }
+ }
+ }
+ }
+
+ for (var i = 0; i < 3; i++) {
+ index = parseHex(hash, 8 + i, 1) % availableColors.length;
+ if (isDuplicate([0, 4]) || // Disallow dark gray and dark color combo
+ isDuplicate([2, 3])) { // Disallow light gray and light color combo
+ index = 1;
+ }
+ selectedColorIndexes.push(index);
+ }
+
+ // ACTUAL RENDERING
+ // Sides
+ renderShape(0, outerShape, 2, 3, [[1, 0], [2, 0], [2, 3], [1, 3], [0, 1], [3, 1], [3, 2], [0, 2]]);
+ // Corners
+ renderShape(1, outerShape, 4, 5, [[0, 0], [3, 0], [3, 3], [0, 3]]);
+ // Center
+ renderShape(2, centerShape, 1, null, [[1, 1], [2, 1], [2, 2], [1, 2]]);
+
+ renderer.finish();
+}
+
+/**
+ * Computes a SHA1 hash for any value and returns it as a hexadecimal string.
+ *
+ * This function is optimized for minimal code size and rather short messages.
+ *
+ * @param {string} message
+ */
+function sha1(message) {
+ var HASH_SIZE_HALF_BYTES = 40;
+ var BLOCK_SIZE_WORDS = 16;
+
+ // Variables
+ // `var` is used to be able to minimize the number of `var` keywords.
+ var i = 0,
+ f = 0,
+
+ // Use `encodeURI` to UTF8 encode the message without any additional libraries
+ // We could use `unescape` + `encodeURI` to minimize the code, but that would be slightly risky
+ // since `unescape` is deprecated.
+ urlEncodedMessage = encodeURI(message) + "%80", // trailing '1' bit padding
+
+ // This can be changed to a preallocated Uint32Array array for greater performance and larger code size
+ data = [],
+ dataSize,
+
+ hashBuffer = [],
+
+ a = 0x67452301,
+ b = 0xefcdab89,
+ c = ~a,
+ d = ~b,
+ e = 0xc3d2e1f0,
+ hash = [a, b, c, d, e],
+
+ blockStartIndex = 0,
+ hexHash = "";
+
+ /**
+ * Rotates the value a specified number of bits to the left.
+ * @param {number} value Value to rotate
+ * @param {number} shift Bit count to shift.
+ */
+ function rotl(value, shift) {
+ return (value << shift) | (value >>> (32 - shift));
+ }
+
+ // Message data
+ for ( ; i < urlEncodedMessage.length; f++) {
+ data[f >> 2] = data[f >> 2] |
+ (
+ (
+ urlEncodedMessage[i] == "%"
+ // Percent encoded byte
+ ? parseInt(urlEncodedMessage.substring(i + 1, i += 3), 16)
+ // Unencoded byte
+ : urlEncodedMessage.charCodeAt(i++)
+ )
+
+ // Read bytes in reverse order (big endian words)
+ << ((3 - (f & 3)) * 8)
+ );
+ }
+
+ // f is now the length of the utf8 encoded message
+ // 7 = 8 bytes (64 bit) for message size, -1 to round down
+ // >> 6 = integer division with block size
+ dataSize = (((f + 7) >> 6) + 1) * BLOCK_SIZE_WORDS;
+
+ // Message size in bits.
+ // SHA1 uses a 64 bit integer to represent the size, but since we only support short messages only the least
+ // significant 32 bits are set. -8 is for the '1' bit padding byte.
+ data[dataSize - 1] = f * 8 - 8;
+
+ // Compute hash
+ for ( ; blockStartIndex < dataSize; blockStartIndex += BLOCK_SIZE_WORDS) {
+ for (i = 0; i < 80; i++) {
+ f = rotl(a, 5) + e + (
+ // Ch
+ i < 20 ? ((b & c) ^ ((~b) & d)) + 0x5a827999 :
+
+ // Parity
+ i < 40 ? (b ^ c ^ d) + 0x6ed9eba1 :
+
+ // Maj
+ i < 60 ? ((b & c) ^ (b & d) ^ (c & d)) + 0x8f1bbcdc :
+
+ // Parity
+ (b ^ c ^ d) + 0xca62c1d6
+ ) + (
+ hashBuffer[i] = i < BLOCK_SIZE_WORDS
+ // Bitwise OR is used to coerse `undefined` to 0
+ ? (data[blockStartIndex + i] | 0)
+ : rotl(hashBuffer[i - 3] ^ hashBuffer[i - 8] ^ hashBuffer[i - 14] ^ hashBuffer[i - 16], 1)
+ );
+
+ e = d;
+ d = c;
+ c = rotl(b, 30);
+ b = a;
+ a = f;
+ }
+
+ hash[0] = a = ((hash[0] + a) | 0);
+ hash[1] = b = ((hash[1] + b) | 0);
+ hash[2] = c = ((hash[2] + c) | 0);
+ hash[3] = d = ((hash[3] + d) | 0);
+ hash[4] = e = ((hash[4] + e) | 0);
+ }
+
+ // Format hex hash
+ for (i = 0; i < HASH_SIZE_HALF_BYTES; i++) {
+ hexHash += (
+ (
+ // Get word (2^3 half-bytes per word)
+ hash[i >> 3] >>>
+
+ // Append half-bytes in reverse order
+ ((7 - (i & 7)) * 4)
+ )
+ // Clamp to half-byte
+ & 0xf
+ ).toString(16);
+ }
+
+ return hexHash;
+}
+
+/**
+ * Inputs a value that might be a valid hash string for Jdenticon and returns it
+ * if it is determined valid, otherwise a falsy value is returned.
+ */
+function isValidHash(hashCandidate) {
+ return /^[0-9a-f]{11,}$/i.test(hashCandidate) && hashCandidate;
}
-/**
- * Inputs a value that might be a valid hash string for Jdenticon and returns it
- * if it is determined valid, otherwise a falsy value is returned.
- */
-function isValidHash(hashCandidate) {
- return /^[0-9a-f]{11,}$/i.test(hashCandidate) && hashCandidate;
-}
-
-/**
- * Computes a hash for the specified value. Currently SHA1 is used. This function
- * always returns a valid hash.
- */
-function computeHash(value) {
- return sha1(value == null ? "" : "" + value);
+/**
+ * Computes a hash for the specified value. Currently SHA1 is used. This function
+ * always returns a valid hash.
+ */
+function computeHash(value) {
+ return sha1(value == null ? "" : "" + value);
+}
+
+
+
+/**
+ * Renderer redirecting drawing commands to a canvas context.
+ * @implements {Renderer}
+ */
+function CanvasRenderer(ctx, iconSize) {
+ var canvas = ctx.canvas;
+ var width = canvas.width;
+ var height = canvas.height;
+
+ ctx.save();
+
+ if (!iconSize) {
+ iconSize = Math.min(width, height);
+
+ ctx.translate(
+ ((width - iconSize) / 2) | 0,
+ ((height - iconSize) / 2) | 0);
+ }
+
+ /**
+ * @private
+ */
+ this.l/*_ctx*/ = ctx;
+ this.k/*iconSize*/ = iconSize;
+
+ ctx.clearRect(0, 0, iconSize, iconSize);
}
+var CanvasRenderer__prototype = CanvasRenderer.prototype;
+
+/**
+ * Fills the background with the specified color.
+ * @param {string} fillColor Fill color on the format #rrggbb[aa].
+ */
+CanvasRenderer__prototype.m/*setBackground*/ = function setBackground (fillColor) {
+ var ctx = this.l/*_ctx*/;
+ var iconSize = this.k/*iconSize*/;
+
+ ctx.fillStyle = toCss3Color(fillColor);
+ ctx.fillRect(0, 0, iconSize, iconSize);
+};
+
+/**
+ * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape.
+ * @param {string} fillColor Fill color on format #rrggbb[aa].
+ */
+CanvasRenderer__prototype.O/*beginShape*/ = function beginShape (fillColor) {
+ var ctx = this.l/*_ctx*/;
+ ctx.fillStyle = toCss3Color(fillColor);
+ ctx.beginPath();
+};
+
+/**
+ * Marks the end of the currently drawn shape. This causes the queued paths to be rendered on the canvas.
+ */
+CanvasRenderer__prototype.P/*endShape*/ = function endShape () {
+ this.l/*_ctx*/.fill();
+};
+
+/**
+ * Adds a polygon to the rendering queue.
+ * @param points An array of Point objects.
+ */
+CanvasRenderer__prototype.g/*addPolygon*/ = function addPolygon (points) {
+ var ctx = this.l/*_ctx*/;
+ ctx.moveTo(points[0].x, points[0].y);
+ for (var i = 1; i < points.length; i++) {
+ ctx.lineTo(points[i].x, points[i].y);
+ }
+ ctx.closePath();
+};
+
+/**
+ * Adds a circle to the rendering queue.
+ * @param {Point} point The upper left corner of the circle bounding box.
+ * @param {number} diameter The diameter of the circle.
+ * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).
+ */
+CanvasRenderer__prototype.h/*addCircle*/ = function addCircle (point, diameter, counterClockwise) {
+ var ctx = this.l/*_ctx*/,
+ radius = diameter / 2;
+ ctx.moveTo(point.x + radius, point.y + radius);
+ ctx.arc(point.x + radius, point.y + radius, radius, 0, Math.PI * 2, counterClockwise);
+ ctx.closePath();
+};
-
-
-/**
- * Renderer redirecting drawing commands to a canvas context.
- * @implements {Renderer}
- */
-function CanvasRenderer(ctx, iconSize) {
- var canvas = ctx.canvas;
- var width = canvas.width;
- var height = canvas.height;
-
- ctx.save();
-
- if (!iconSize) {
- iconSize = Math.min(width, height);
-
- ctx.translate(
- ((width - iconSize) / 2) | 0,
- ((height - iconSize) / 2) | 0);
- }
-
- /**
- * @private
- */
- this.l/*_ctx*/ = ctx;
- this.k/*iconSize*/ = iconSize;
-
- ctx.clearRect(0, 0, iconSize, iconSize);
-}
-var CanvasRenderer__prototype = CanvasRenderer.prototype;
-
-/**
- * Fills the background with the specified color.
- * @param {string} fillColor Fill color on the format #rrggbb[aa].
- */
-CanvasRenderer__prototype.m/*setBackground*/ = function setBackground (fillColor) {
- var ctx = this.l/*_ctx*/;
- var iconSize = this.k/*iconSize*/;
-
- ctx.fillStyle = toCss3Color(fillColor);
- ctx.fillRect(0, 0, iconSize, iconSize);
-};
-
-/**
- * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape.
- * @param {string} fillColor Fill color on format #rrggbb[aa].
- */
-CanvasRenderer__prototype.O/*beginShape*/ = function beginShape (fillColor) {
- var ctx = this.l/*_ctx*/;
- ctx.fillStyle = toCss3Color(fillColor);
- ctx.beginPath();
-};
-
-/**
- * Marks the end of the currently drawn shape. This causes the queued paths to be rendered on the canvas.
- */
-CanvasRenderer__prototype.P/*endShape*/ = function endShape () {
- this.l/*_ctx*/.fill();
-};
-
-/**
- * Adds a polygon to the rendering queue.
- * @param points An array of Point objects.
- */
-CanvasRenderer__prototype.g/*addPolygon*/ = function addPolygon (points) {
- var ctx = this.l/*_ctx*/;
- ctx.moveTo(points[0].x, points[0].y);
- for (var i = 1; i < points.length; i++) {
- ctx.lineTo(points[i].x, points[i].y);
- }
- ctx.closePath();
-};
-
-/**
- * Adds a circle to the rendering queue.
- * @param {Point} point The upper left corner of the circle bounding box.
- * @param {number} diameter The diameter of the circle.
- * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).
- */
-CanvasRenderer__prototype.h/*addCircle*/ = function addCircle (point, diameter, counterClockwise) {
- var ctx = this.l/*_ctx*/,
- radius = diameter / 2;
- ctx.moveTo(point.x + radius, point.y + radius);
- ctx.arc(point.x + radius, point.y + radius, radius, 0, Math.PI * 2, counterClockwise);
- ctx.closePath();
-};
-
-/**
- * Called when the icon has been completely drawn.
- */
-CanvasRenderer__prototype.finish = function finish () {
- this.l/*_ctx*/.restore();
+/**
+ * Called when the icon has been completely drawn.
+ */
+CanvasRenderer__prototype.finish = function finish () {
+ this.l/*_ctx*/.restore();
};
-/**
- * Draws an identicon to a context.
- * @param {CanvasRenderingContext2D} ctx - Canvas context on which the icon will be drawn at location (0, 0).
- * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.
- * @param {number} size - Icon size in pixels.
- * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any
- * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be
- * specified in place of a configuration object.
- */
-function drawIcon(ctx, hashOrValue, size, config) {
- if (!ctx) {
- throw new Error("No canvas specified.");
- }
-
- iconGenerator(new CanvasRenderer(ctx, size),
- isValidHash(hashOrValue) || computeHash(hashOrValue),
- config);
-
- var canvas = ctx.canvas;
- if (canvas) {
- canvas[IS_RENDERED_PROPERTY] = true;
- }
+/**
+ * Draws an identicon to a context.
+ * @param {CanvasRenderingContext2D} ctx - Canvas context on which the icon will be drawn at location (0, 0).
+ * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.
+ * @param {number} size - Icon size in pixels.
+ * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any
+ * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be
+ * specified in place of a configuration object.
+ */
+function drawIcon(ctx, hashOrValue, size, config) {
+ if (!ctx) {
+ throw new Error("No canvas specified.");
+ }
+
+ iconGenerator(new CanvasRenderer(ctx, size),
+ isValidHash(hashOrValue) || computeHash(hashOrValue),
+ config);
+
+ var canvas = ctx.canvas;
+ if (canvas) {
+ canvas[IS_RENDERED_PROPERTY] = true;
+ }
+}
+
+/**
+ * Prepares a measure to be used as a measure in an SVG path, by
+ * rounding the measure to a single decimal. This reduces the file
+ * size of the generated SVG with more than 50% in some cases.
+ */
+function svgValue(value) {
+ return ((value * 10 + 0.5) | 0) / 10;
+}
+
+/**
+ * Represents an SVG path element.
+ */
+function SvgPath() {
+ /**
+ * This property holds the data string (path.d) of the SVG path.
+ * @type {string}
+ */
+ this.B/*dataString*/ = "";
}
+var SvgPath__prototype = SvgPath.prototype;
-/**
- * Prepares a measure to be used as a measure in an SVG path, by
- * rounding the measure to a single decimal. This reduces the file
- * size of the generated SVG with more than 50% in some cases.
- */
-function svgValue(value) {
- return ((value * 10 + 0.5) | 0) / 10;
-}
-
-/**
- * Represents an SVG path element.
- */
-function SvgPath() {
- /**
- * This property holds the data string (path.d) of the SVG path.
- * @type {string}
- */
- this.B/*dataString*/ = "";
-}
-var SvgPath__prototype = SvgPath.prototype;
-
-/**
- * Adds a polygon with the current fill color to the SVG path.
- * @param points An array of Point objects.
- */
-SvgPath__prototype.g/*addPolygon*/ = function addPolygon (points) {
- var dataString = "";
- for (var i = 0; i < points.length; i++) {
- dataString += (i ? "L" : "M") + svgValue(points[i].x) + " " + svgValue(points[i].y);
- }
- this.B/*dataString*/ += dataString + "Z";
-};
-
-/**
- * Adds a circle with the current fill color to the SVG path.
- * @param {Point} point The upper left corner of the circle bounding box.
- * @param {number} diameter The diameter of the circle.
- * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).
- */
-SvgPath__prototype.h/*addCircle*/ = function addCircle (point, diameter, counterClockwise) {
- var sweepFlag = counterClockwise ? 0 : 1,
- svgRadius = svgValue(diameter / 2),
- svgDiameter = svgValue(diameter),
- svgArc = "a" + svgRadius + "," + svgRadius + " 0 1," + sweepFlag + " ";
-
- this.B/*dataString*/ +=
- "M" + svgValue(point.x) + " " + svgValue(point.y + diameter / 2) +
- svgArc + svgDiameter + ",0" +
- svgArc + (-svgDiameter) + ",0";
+/**
+ * Adds a polygon with the current fill color to the SVG path.
+ * @param points An array of Point objects.
+ */
+SvgPath__prototype.g/*addPolygon*/ = function addPolygon (points) {
+ var dataString = "";
+ for (var i = 0; i < points.length; i++) {
+ dataString += (i ? "L" : "M") + svgValue(points[i].x) + " " + svgValue(points[i].y);
+ }
+ this.B/*dataString*/ += dataString + "Z";
};
-
-
-/**
- * Renderer producing SVG output.
- * @implements {Renderer}
- */
-function SvgRenderer(target) {
- /**
- * @type {SvgPath}
- * @private
- */
- this.C/*_path*/;
-
- /**
- * @type {Object.}
- * @private
- */
- this.D/*_pathsByColor*/ = { };
-
- /**
- * @type {SvgElement|SvgWriter}
- * @private
- */
- this.R/*_target*/ = target;
-
- /**
- * @type {number}
- */
- this.k/*iconSize*/ = target.k/*iconSize*/;
-}
-var SvgRenderer__prototype = SvgRenderer.prototype;
-
-/**
- * Fills the background with the specified color.
- * @param {string} fillColor Fill color on the format #rrggbb[aa].
- */
-SvgRenderer__prototype.m/*setBackground*/ = function setBackground (fillColor) {
- var match = /^(#......)(..)?/.exec(fillColor),
- opacity = match[2] ? parseHex(match[2], 0) / 255 : 1;
- this.R/*_target*/.m/*setBackground*/(match[1], opacity);
-};
-
-/**
- * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape.
- * @param {string} color Fill color on format #xxxxxx.
- */
-SvgRenderer__prototype.O/*beginShape*/ = function beginShape (color) {
- this.C/*_path*/ = this.D/*_pathsByColor*/[color] || (this.D/*_pathsByColor*/[color] = new SvgPath());
-};
-
-/**
- * Marks the end of the currently drawn shape.
- */
-SvgRenderer__prototype.P/*endShape*/ = function endShape () { };
-
-/**
- * Adds a polygon with the current fill color to the SVG.
- * @param points An array of Point objects.
- */
-SvgRenderer__prototype.g/*addPolygon*/ = function addPolygon (points) {
- this.C/*_path*/.g/*addPolygon*/(points);
-};
-
-/**
- * Adds a circle with the current fill color to the SVG.
- * @param {Point} point The upper left corner of the circle bounding box.
- * @param {number} diameter The diameter of the circle.
- * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).
- */
-SvgRenderer__prototype.h/*addCircle*/ = function addCircle (point, diameter, counterClockwise) {
- this.C/*_path*/.h/*addCircle*/(point, diameter, counterClockwise);
-};
-
-/**
- * Called when the icon has been completely drawn.
- */
+/**
+ * Adds a circle with the current fill color to the SVG path.
+ * @param {Point} point The upper left corner of the circle bounding box.
+ * @param {number} diameter The diameter of the circle.
+ * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).
+ */
+SvgPath__prototype.h/*addCircle*/ = function addCircle (point, diameter, counterClockwise) {
+ var sweepFlag = counterClockwise ? 0 : 1,
+ svgRadius = svgValue(diameter / 2),
+ svgDiameter = svgValue(diameter),
+ svgArc = "a" + svgRadius + "," + svgRadius + " 0 1," + sweepFlag + " ";
+
+ this.B/*dataString*/ +=
+ "M" + svgValue(point.x) + " " + svgValue(point.y + diameter / 2) +
+ svgArc + svgDiameter + ",0" +
+ svgArc + (-svgDiameter) + ",0";
+};
+
+
+
+/**
+ * Renderer producing SVG output.
+ * @implements {Renderer}
+ */
+function SvgRenderer(target) {
+ /**
+ * @type {SvgPath}
+ * @private
+ */
+ this.C/*_path*/;
+
+ /**
+ * @type {Object.}
+ * @private
+ */
+ this.D/*_pathsByColor*/ = { };
+
+ /**
+ * @type {SvgElement|SvgWriter}
+ * @private
+ */
+ this.R/*_target*/ = target;
+
+ /**
+ * @type {number}
+ */
+ this.k/*iconSize*/ = target.k/*iconSize*/;
+}
+var SvgRenderer__prototype = SvgRenderer.prototype;
+
+/**
+ * Fills the background with the specified color.
+ * @param {string} fillColor Fill color on the format #rrggbb[aa].
+ */
+SvgRenderer__prototype.m/*setBackground*/ = function setBackground (fillColor) {
+ var match = /^(#......)(..)?/.exec(fillColor),
+ opacity = match[2] ? parseHex(match[2], 0) / 255 : 1;
+ this.R/*_target*/.m/*setBackground*/(match[1], opacity);
+};
+
+/**
+ * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape.
+ * @param {string} color Fill color on format #xxxxxx.
+ */
+SvgRenderer__prototype.O/*beginShape*/ = function beginShape (color) {
+ this.C/*_path*/ = this.D/*_pathsByColor*/[color] || (this.D/*_pathsByColor*/[color] = new SvgPath());
+};
+
+/**
+ * Marks the end of the currently drawn shape.
+ */
+SvgRenderer__prototype.P/*endShape*/ = function endShape () { };
+
+/**
+ * Adds a polygon with the current fill color to the SVG.
+ * @param points An array of Point objects.
+ */
+SvgRenderer__prototype.g/*addPolygon*/ = function addPolygon (points) {
+ this.C/*_path*/.g/*addPolygon*/(points);
+};
+
+/**
+ * Adds a circle with the current fill color to the SVG.
+ * @param {Point} point The upper left corner of the circle bounding box.
+ * @param {number} diameter The diameter of the circle.
+ * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).
+ */
+SvgRenderer__prototype.h/*addCircle*/ = function addCircle (point, diameter, counterClockwise) {
+ this.C/*_path*/.h/*addCircle*/(point, diameter, counterClockwise);
+};
+
+/**
+ * Called when the icon has been completely drawn.
+ */
SvgRenderer__prototype.finish = function finish () {
var this$1 = this;
-
- var pathsByColor = this.D/*_pathsByColor*/;
- for (var color in pathsByColor) {
- // hasOwnProperty cannot be shadowed in pathsByColor
- // eslint-disable-next-line no-prototype-builtins
- if (pathsByColor.hasOwnProperty(color)) {
- this$1.R/*_target*/.S/*appendPath*/(color, pathsByColor[color].B/*dataString*/);
- }
- }
+
+ var pathsByColor = this.D/*_pathsByColor*/;
+ for (var color in pathsByColor) {
+ // hasOwnProperty cannot be shadowed in pathsByColor
+ // eslint-disable-next-line no-prototype-builtins
+ if (pathsByColor.hasOwnProperty(color)) {
+ this$1.R/*_target*/.S/*appendPath*/(color, pathsByColor[color].B/*dataString*/);
+ }
+ }
+};
+
+var SVG_CONSTANTS = {
+ T/*XMLNS*/: "http://www.w3.org/2000/svg",
+ U/*WIDTH*/: "width",
+ V/*HEIGHT*/: "height",
+};
+
+/**
+ * Renderer producing SVG output.
+ */
+function SvgWriter(iconSize) {
+ /**
+ * @type {number}
+ */
+ this.k/*iconSize*/ = iconSize;
+
+ /**
+ * @type {string}
+ * @private
+ */
+ this.F/*_s*/ =
+ '';
+}
+var SvgWriter__prototype = SvgWriter.prototype;
+
+/**
+ * Fills the background with the specified color.
+ * @param {string} fillColor Fill color on the format #rrggbb.
+ * @param {number} opacity Opacity in the range [0.0, 1.0].
+ */
+SvgWriter__prototype.m/*setBackground*/ = function setBackground (fillColor, opacity) {
+ if (opacity) {
+ this.F/*_s*/ += ' ';
+ }
};
-var SVG_CONSTANTS = {
- T/*XMLNS*/: "http://www.w3.org/2000/svg",
- U/*WIDTH*/: "width",
- V/*HEIGHT*/: "height",
+/**
+ * Writes a path to the SVG string.
+ * @param {string} color Fill color on format #rrggbb.
+ * @param {string} dataString The SVG path data string.
+ */
+SvgWriter__prototype.S/*appendPath*/ = function appendPath (color, dataString) {
+ this.F/*_s*/ += ' ';
};
-/**
- * Renderer producing SVG output.
- */
-function SvgWriter(iconSize) {
- /**
- * @type {number}
- */
- this.k/*iconSize*/ = iconSize;
-
- /**
- * @type {string}
- * @private
- */
- this.F/*_s*/ =
- '';
-}
-var SvgWriter__prototype = SvgWriter.prototype;
-
-/**
- * Fills the background with the specified color.
- * @param {string} fillColor Fill color on the format #rrggbb.
- * @param {number} opacity Opacity in the range [0.0, 1.0].
- */
-SvgWriter__prototype.m/*setBackground*/ = function setBackground (fillColor, opacity) {
- if (opacity) {
- this.F/*_s*/ += ' ';
- }
-};
-
-/**
- * Writes a path to the SVG string.
- * @param {string} color Fill color on format #rrggbb.
- * @param {string} dataString The SVG path data string.
- */
-SvgWriter__prototype.S/*appendPath*/ = function appendPath (color, dataString) {
- this.F/*_s*/ += ' ';
-};
-
-/**
- * Gets the rendered image as an SVG string.
- */
-SvgWriter__prototype.toString = function toString () {
- return this.F/*_s*/ + " ";
+/**
+ * Gets the rendered image as an SVG string.
+ */
+SvgWriter__prototype.toString = function toString () {
+ return this.F/*_s*/ + " ";
};
-/**
- * Draws an identicon as an SVG string.
- * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.
- * @param {number} size - Icon size in pixels.
- * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any
- * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be
- * specified in place of a configuration object.
- * @returns {string} SVG string
- */
-function toSvg(hashOrValue, size, config) {
- var writer = new SvgWriter(size);
- iconGenerator(new SvgRenderer(writer),
- isValidHash(hashOrValue) || computeHash(hashOrValue),
- config);
- return writer.toString();
+/**
+ * Draws an identicon as an SVG string.
+ * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.
+ * @param {number} size - Icon size in pixels.
+ * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any
+ * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be
+ * specified in place of a configuration object.
+ * @returns {string} SVG string
+ */
+function toSvg(hashOrValue, size, config) {
+ var writer = new SvgWriter(size);
+ iconGenerator(new SvgRenderer(writer),
+ isValidHash(hashOrValue) || computeHash(hashOrValue),
+ config);
+ return writer.toString();
}
-/**
- * Creates a new element and adds it to the specified parent.
- * @param {Element} parentNode
- * @param {string} name
- * @param {...(string|number)} keyValuePairs
- */
+/**
+ * Creates a new element and adds it to the specified parent.
+ * @param {Element} parentNode
+ * @param {string} name
+ * @param {...(string|number)} keyValuePairs
+ */
function SvgElement_append(parentNode, name) {
var keyValuePairs = [], len = arguments.length - 2;
while ( len-- > 0 ) keyValuePairs[ len ] = arguments[ len + 2 ];
-
- var el = document.createElementNS(SVG_CONSTANTS.T/*XMLNS*/, name);
-
- for (var i = 0; i + 1 < keyValuePairs.length; i += 2) {
- el.setAttribute(
- /** @type {string} */(keyValuePairs[i]),
- /** @type {string} */(keyValuePairs[i + 1])
- );
- }
-
- parentNode.appendChild(el);
-}
-
-
-/**
- * Renderer producing SVG output.
- */
-function SvgElement(element) {
- // Don't use the clientWidth and clientHeight properties on SVG elements
- // since Firefox won't serve a proper value of these properties on SVG
- // elements (https://bugzilla.mozilla.org/show_bug.cgi?id=874811)
- // Instead use 100px as a hardcoded size (the svg viewBox will rescale
- // the icon to the correct dimensions)
- var iconSize = this.k/*iconSize*/ = Math.min(
- (Number(element.getAttribute(SVG_CONSTANTS.U/*WIDTH*/)) || 100),
- (Number(element.getAttribute(SVG_CONSTANTS.V/*HEIGHT*/)) || 100)
- );
-
- /**
- * @type {Element}
- * @private
- */
- this.W/*_el*/ = element;
-
- // Clear current SVG child elements
- while (element.firstChild) {
- element.removeChild(element.firstChild);
- }
-
- // Set viewBox attribute to ensure the svg scales nicely.
- element.setAttribute("viewBox", "0 0 " + iconSize + " " + iconSize);
- element.setAttribute("preserveAspectRatio", "xMidYMid meet");
-}
-var SvgElement__prototype = SvgElement.prototype;
-
-/**
- * Fills the background with the specified color.
- * @param {string} fillColor Fill color on the format #rrggbb.
- * @param {number} opacity Opacity in the range [0.0, 1.0].
- */
-SvgElement__prototype.m/*setBackground*/ = function setBackground (fillColor, opacity) {
- if (opacity) {
- SvgElement_append(this.W/*_el*/, "rect",
- SVG_CONSTANTS.U/*WIDTH*/, "100%",
- SVG_CONSTANTS.V/*HEIGHT*/, "100%",
- "fill", fillColor,
- "opacity", opacity);
- }
-};
-
-/**
- * Appends a path to the SVG element.
- * @param {string} color Fill color on format #xxxxxx.
- * @param {string} dataString The SVG path data string.
- */
-SvgElement__prototype.S/*appendPath*/ = function appendPath (color, dataString) {
- SvgElement_append(this.W/*_el*/, "path",
- "fill", color,
- "d", dataString);
+
+ var el = document.createElementNS(SVG_CONSTANTS.T/*XMLNS*/, name);
+
+ for (var i = 0; i + 1 < keyValuePairs.length; i += 2) {
+ el.setAttribute(
+ /** @type {string} */(keyValuePairs[i]),
+ /** @type {string} */(keyValuePairs[i + 1])
+ );
+ }
+
+ parentNode.appendChild(el);
+}
+
+
+/**
+ * Renderer producing SVG output.
+ */
+function SvgElement(element) {
+ // Don't use the clientWidth and clientHeight properties on SVG elements
+ // since Firefox won't serve a proper value of these properties on SVG
+ // elements (https://bugzilla.mozilla.org/show_bug.cgi?id=874811)
+ // Instead use 100px as a hardcoded size (the svg viewBox will rescale
+ // the icon to the correct dimensions)
+ var iconSize = this.k/*iconSize*/ = Math.min(
+ (Number(element.getAttribute(SVG_CONSTANTS.U/*WIDTH*/)) || 100),
+ (Number(element.getAttribute(SVG_CONSTANTS.V/*HEIGHT*/)) || 100)
+ );
+
+ /**
+ * @type {Element}
+ * @private
+ */
+ this.W/*_el*/ = element;
+
+ // Clear current SVG child elements
+ while (element.firstChild) {
+ element.removeChild(element.firstChild);
+ }
+
+ // Set viewBox attribute to ensure the svg scales nicely.
+ element.setAttribute("viewBox", "0 0 " + iconSize + " " + iconSize);
+ element.setAttribute("preserveAspectRatio", "xMidYMid meet");
+}
+var SvgElement__prototype = SvgElement.prototype;
+
+/**
+ * Fills the background with the specified color.
+ * @param {string} fillColor Fill color on the format #rrggbb.
+ * @param {number} opacity Opacity in the range [0.0, 1.0].
+ */
+SvgElement__prototype.m/*setBackground*/ = function setBackground (fillColor, opacity) {
+ if (opacity) {
+ SvgElement_append(this.W/*_el*/, "rect",
+ SVG_CONSTANTS.U/*WIDTH*/, "100%",
+ SVG_CONSTANTS.V/*HEIGHT*/, "100%",
+ "fill", fillColor,
+ "opacity", opacity);
+ }
};
-/**
- * Updates all canvas elements with the `data-jdenticon-hash` or `data-jdenticon-value` attribute.
- */
-function updateAll() {
- if (documentQuerySelectorAll) {
- update(ICON_SELECTOR);
- }
-}
-
-/**
- * Updates all canvas elements with the `data-jdenticon-hash` or `data-jdenticon-value` attribute that have not already
- * been rendered.
- */
-function updateAllConditional() {
- if (documentQuerySelectorAll) {
- /** @type {NodeListOf} */
- var elements = documentQuerySelectorAll(ICON_SELECTOR);
-
- for (var i = 0; i < elements.length; i++) {
- var el = elements[i];
- if (!el[IS_RENDERED_PROPERTY]) {
- update(el);
- }
- }
- }
-}
-
-/**
- * Updates the identicon in the specified `` or `` elements.
- * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type
- * `` or ``, or a CSS selector to such an element.
- * @param {*=} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or
- * `data-jdenticon-value` attribute will be evaluated.
- * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any
- * global configuration in its entirety. For backward compability a padding value in the range [0.0, 0.5) can be
- * specified in place of a configuration object.
- */
-function update(el, hashOrValue, config) {
- renderDomElement(el, hashOrValue, config, function (el, iconType) {
- if (iconType) {
- return iconType == ICON_TYPE_SVG ?
- new SvgRenderer(new SvgElement(el)) :
- new CanvasRenderer(/** @type {HTMLCanvasElement} */(el).getContext("2d"));
- }
- });
-}
-
-/**
- * Updates the identicon in the specified canvas or svg elements.
- * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type
- * `` or ``, or a CSS selector to such an element.
- * @param {*} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or
- * `data-jdenticon-value` attribute will be evaluated.
- * @param {Object|number|undefined} config
- * @param {function(Element,number):Renderer} rendererFactory - Factory function for creating an icon renderer.
- */
-function renderDomElement(el, hashOrValue, config, rendererFactory) {
- if (typeof el === "string") {
- if (documentQuerySelectorAll) {
- var elements = documentQuerySelectorAll(el);
- for (var i = 0; i < elements.length; i++) {
- renderDomElement(elements[i], hashOrValue, config, rendererFactory);
- }
- }
- return;
- }
-
- // Hash selection. The result from getValidHash or computeHash is
- // accepted as a valid hash.
- var hash =
- // 1. Explicit valid hash
- isValidHash(hashOrValue) ||
-
- // 2. Explicit value (`!= null` catches both null and undefined)
- hashOrValue != null && computeHash(hashOrValue) ||
-
- // 3. `data-jdenticon-hash` attribute
- isValidHash(el.getAttribute(ATTRIBUTES.t/*HASH*/)) ||
-
- // 4. `data-jdenticon-value` attribute.
- // We want to treat an empty attribute as an empty value.
- // Some browsers return empty string even if the attribute
- // is not specified, so use hasAttribute to determine if
- // the attribute is specified.
- el.hasAttribute(ATTRIBUTES.o/*VALUE*/) && computeHash(el.getAttribute(ATTRIBUTES.o/*VALUE*/));
-
- if (!hash) {
- // No hash specified. Don't render an icon.
- return;
- }
-
- var renderer = rendererFactory(el, getIdenticonType(el));
- if (renderer) {
- // Draw icon
- iconGenerator(renderer, hash, config);
- el[IS_RENDERED_PROPERTY] = true;
- }
+/**
+ * Appends a path to the SVG element.
+ * @param {string} color Fill color on format #xxxxxx.
+ * @param {string} dataString The SVG path data string.
+ */
+SvgElement__prototype.S/*appendPath*/ = function appendPath (color, dataString) {
+ SvgElement_append(this.W/*_el*/, "path",
+ "fill", color,
+ "d", dataString);
+};
+
+/**
+ * Updates all canvas elements with the `data-jdenticon-hash` or `data-jdenticon-value` attribute.
+ */
+function updateAll() {
+ if (documentQuerySelectorAll) {
+ update(ICON_SELECTOR);
+ }
+}
+
+/**
+ * Updates all canvas elements with the `data-jdenticon-hash` or `data-jdenticon-value` attribute that have not already
+ * been rendered.
+ */
+function updateAllConditional() {
+ if (documentQuerySelectorAll) {
+ /** @type {NodeListOf} */
+ var elements = documentQuerySelectorAll(ICON_SELECTOR);
+
+ for (var i = 0; i < elements.length; i++) {
+ var el = elements[i];
+ if (!el[IS_RENDERED_PROPERTY]) {
+ update(el);
+ }
+ }
+ }
+}
+
+/**
+ * Updates the identicon in the specified `` or `` elements.
+ * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type
+ * `` or ``, or a CSS selector to such an element.
+ * @param {*=} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or
+ * `data-jdenticon-value` attribute will be evaluated.
+ * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any
+ * global configuration in its entirety. For backward compability a padding value in the range [0.0, 0.5) can be
+ * specified in place of a configuration object.
+ */
+function update(el, hashOrValue, config) {
+ renderDomElement(el, hashOrValue, config, function (el, iconType) {
+ if (iconType) {
+ return iconType == ICON_TYPE_SVG ?
+ new SvgRenderer(new SvgElement(el)) :
+ new CanvasRenderer(/** @type {HTMLCanvasElement} */(el).getContext("2d"));
+ }
+ });
+}
+
+/**
+ * Updates the identicon in the specified canvas or svg elements.
+ * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type
+ * `` or ``, or a CSS selector to such an element.
+ * @param {*} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or
+ * `data-jdenticon-value` attribute will be evaluated.
+ * @param {Object|number|undefined} config
+ * @param {function(Element,number):Renderer} rendererFactory - Factory function for creating an icon renderer.
+ */
+function renderDomElement(el, hashOrValue, config, rendererFactory) {
+ if (typeof el === "string") {
+ if (documentQuerySelectorAll) {
+ var elements = documentQuerySelectorAll(el);
+ for (var i = 0; i < elements.length; i++) {
+ renderDomElement(elements[i], hashOrValue, config, rendererFactory);
+ }
+ }
+ return;
+ }
+
+ // Hash selection. The result from getValidHash or computeHash is
+ // accepted as a valid hash.
+ var hash =
+ // 1. Explicit valid hash
+ isValidHash(hashOrValue) ||
+
+ // 2. Explicit value (`!= null` catches both null and undefined)
+ hashOrValue != null && computeHash(hashOrValue) ||
+
+ // 3. `data-jdenticon-hash` attribute
+ isValidHash(el.getAttribute(ATTRIBUTES.t/*HASH*/)) ||
+
+ // 4. `data-jdenticon-value` attribute.
+ // We want to treat an empty attribute as an empty value.
+ // Some browsers return empty string even if the attribute
+ // is not specified, so use hasAttribute to determine if
+ // the attribute is specified.
+ el.hasAttribute(ATTRIBUTES.o/*VALUE*/) && computeHash(el.getAttribute(ATTRIBUTES.o/*VALUE*/));
+
+ if (!hash) {
+ // No hash specified. Don't render an icon.
+ return;
+ }
+
+ var renderer = rendererFactory(el, getIdenticonType(el));
+ if (renderer) {
+ // Draw icon
+ iconGenerator(renderer, hash, config);
+ el[IS_RENDERED_PROPERTY] = true;
+ }
}
-/**
- * Renders an identicon for all matching supported elements.
- *
- * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon. If not
- * specified the `data-jdenticon-hash` and `data-jdenticon-value` attributes of each element will be
- * evaluated.
- * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any global
- * configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be
- * specified in place of a configuration object.
- */
-function jdenticonJqueryPlugin(hashOrValue, config) {
- this["each"](function (index, el) {
- update(el, hashOrValue, config);
- });
- return this;
+/**
+ * Renders an identicon for all matching supported elements.
+ *
+ * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon. If not
+ * specified the `data-jdenticon-hash` and `data-jdenticon-value` attributes of each element will be
+ * evaluated.
+ * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any global
+ * configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be
+ * specified in place of a configuration object.
+ */
+function jdenticonJqueryPlugin(hashOrValue, config) {
+ this["each"](function (index, el) {
+ update(el, hashOrValue, config);
+ });
+ return this;
}
-// This file is compiled to dist/jdenticon.js and dist/jdenticon.min.js
-
-var jdenticon = updateAll;
-
-defineConfigProperty(jdenticon);
-
-// Export public API
-jdenticon["configure"] = configure;
-jdenticon["drawIcon"] = drawIcon;
-jdenticon["toSvg"] = toSvg;
-jdenticon["update"] = update;
-jdenticon["updateCanvas"] = update;
-jdenticon["updateSvg"] = update;
-
-/**
- * Specifies the version of the Jdenticon package in use.
- * @type {string}
- */
-jdenticon["version"] = "3.3.0";
-
-/**
- * Specifies which bundle of Jdenticon that is used.
- * @type {string}
- */
-jdenticon["bundle"] = "browser-umd";
-
-// Basic jQuery plugin
-var jQuery = GLOBAL["jQuery"];
-if (jQuery) {
- jQuery["fn"]["jdenticon"] = jdenticonJqueryPlugin;
-}
-
-/**
- * This function is called once upon page load.
- */
-function jdenticonStartup() {
- var replaceMode = (
- jdenticon[CONFIG_PROPERTIES.n/*MODULE*/] ||
- GLOBAL[CONFIG_PROPERTIES.G/*GLOBAL*/] ||
- { }
- )["replaceMode"];
-
- if (replaceMode != "never") {
- updateAllConditional();
-
- if (replaceMode == "observe") {
- observer(update);
- }
- }
-}
-
-// Schedule to render all identicons on the page once it has been loaded.
-whenDocumentIsReady(jdenticonStartup);
-
+// This file is compiled to dist/jdenticon.js and dist/jdenticon.min.js
+
+var jdenticon = updateAll;
+
+defineConfigProperty(jdenticon);
+
+// Export public API
+jdenticon["configure"] = configure;
+jdenticon["drawIcon"] = drawIcon;
+jdenticon["toSvg"] = toSvg;
+jdenticon["update"] = update;
+jdenticon["updateCanvas"] = update;
+jdenticon["updateSvg"] = update;
+
+/**
+ * Specifies the version of the Jdenticon package in use.
+ * @type {string}
+ */
+jdenticon["version"] = "3.3.0";
+
+/**
+ * Specifies which bundle of Jdenticon that is used.
+ * @type {string}
+ */
+jdenticon["bundle"] = "browser-umd";
+
+// Basic jQuery plugin
+var jQuery = GLOBAL["jQuery"];
+if (jQuery) {
+ jQuery["fn"]["jdenticon"] = jdenticonJqueryPlugin;
+}
+
+/**
+ * This function is called once upon page load.
+ */
+function jdenticonStartup() {
+ var replaceMode = (
+ jdenticon[CONFIG_PROPERTIES.n/*MODULE*/] ||
+ GLOBAL[CONFIG_PROPERTIES.G/*GLOBAL*/] ||
+ { }
+ )["replaceMode"];
+
+ if (replaceMode != "never") {
+ updateAllConditional();
+
+ if (replaceMode == "observe") {
+ observer(update);
+ }
+ }
+}
+
+// Schedule to render all identicons on the page once it has been loaded.
+whenDocumentIsReady(jdenticonStartup);
+
return jdenticon;
-
+
});
\ No newline at end of file
diff --git a/src/static/scripts/jquery-3.7.1.slim.js b/src/static/scripts/jquery-4.0.0.slim.js
similarity index 64%
rename from src/static/scripts/jquery-3.7.1.slim.js
rename to src/static/scripts/jquery-4.0.0.slim.js
index f122b10d..a7bb40cf 100644
--- a/src/static/scripts/jquery-3.7.1.slim.js
+++ b/src/static/scripts/jquery-4.0.0.slim.js
@@ -1,12 +1,12 @@
/*!
- * jQuery JavaScript Library v3.7.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/animatedSelector,-effects/Tween
+ * jQuery JavaScript Library v4.0.0+slim
* https://jquery.com/
*
* Copyright OpenJS Foundation and other contributors
* Released under the MIT license
- * https://jquery.org/license
+ * https://jquery.com/license/
*
- * Date: 2023-08-28T13:37Z
+ * Date: 2026-01-18T00:20Z
*/
( function( global, factory ) {
@@ -16,19 +16,7 @@
// For CommonJS and CommonJS-like environments where a proper `window`
// is present, execute the factory and get jQuery.
- // For environments that do not have a `window` with a `document`
- // (such as Node.js), expose a factory as module.exports.
- // This accentuates the need for the creation of a real `window`.
- // e.g. var jQuery = require("jquery")(window);
- // See ticket trac-14549 for more info.
- module.exports = global.document ?
- factory( global, true ) :
- function( w ) {
- if ( !w.document ) {
- throw new Error( "jQuery requires a window with a document" );
- }
- return factory( w );
- };
+ module.exports = factory( global, true );
} else {
factory( global );
}
@@ -36,29 +24,31 @@
// Pass this if window is not defined yet
} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
-// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
-// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
-// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
-// enough that all such attempts are guarded in a try block.
"use strict";
+if ( !window.document ) {
+ throw new Error( "jQuery requires a window with a document" );
+}
+
var arr = [];
var getProto = Object.getPrototypeOf;
var slice = arr.slice;
+// Support: IE 11+
+// IE doesn't have Array#flat; provide a fallback.
var flat = arr.flat ? function( array ) {
return arr.flat.call( array );
} : function( array ) {
return arr.concat.apply( [], array );
};
-
var push = arr.push;
var indexOf = arr.indexOf;
+// [[Class]] -> type pairs
var class2type = {};
var toString = class2type.toString;
@@ -69,85 +59,64 @@ var fnToString = hasOwn.toString;
var ObjectFunctionString = fnToString.call( Object );
+// All support tests are defined in their respective modules.
var support = {};
-var isFunction = function isFunction( obj ) {
-
- // Support: Chrome <=57, Firefox <=52
- // In some browsers, typeof returns "function" for HTML elements
- // (i.e., `typeof document.createElement( "object" ) === "function"`).
- // We don't want to classify *any* DOM node as a function.
- // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5
- // Plus for old WebKit, typeof returns "function" for HTML collections
- // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756)
- return typeof obj === "function" && typeof obj.nodeType !== "number" &&
- typeof obj.item !== "function";
- };
+function toType( obj ) {
+ if ( obj == null ) {
+ return obj + "";
+ }
+ return typeof obj === "object" ?
+ class2type[ toString.call( obj ) ] || "object" :
+ typeof obj;
+}
-var isWindow = function isWindow( obj ) {
- return obj != null && obj === obj.window;
- };
+function isWindow( obj ) {
+ return obj != null && obj === obj.window;
+}
+function isArrayLike( obj ) {
-var document = window.document;
+ var length = !!obj && obj.length,
+ type = toType( obj );
+ if ( typeof obj === "function" || isWindow( obj ) ) {
+ return false;
+ }
+ return type === "array" || length === 0 ||
+ typeof length === "number" && length > 0 && ( length - 1 ) in obj;
+}
- var preservedScriptAttributes = {
- type: true,
- src: true,
- nonce: true,
- noModule: true
- };
+var document$1 = window.document;
- function DOMEval( code, node, doc ) {
- doc = doc || document;
-
- var i, val,
- script = doc.createElement( "script" );
-
- script.text = code;
- if ( node ) {
- for ( i in preservedScriptAttributes ) {
-
- // Support: Firefox 64+, Edge 18+
- // Some browsers don't support the "nonce" property on scripts.
- // On the other hand, just using `getAttribute` is not enough as
- // the `nonce` attribute is reset to an empty string whenever it
- // becomes browsing-context connected.
- // See https://github.com/whatwg/html/issues/2369
- // See https://html.spec.whatwg.org/#nonce-attributes
- // The `node.getAttribute` check was added for the sake of
- // `jQuery.globalEval` so that it can fake a nonce-containing node
- // via an object.
- val = node[ i ] || node.getAttribute && node.getAttribute( i );
- if ( val ) {
- script.setAttribute( i, val );
- }
- }
- }
- doc.head.appendChild( script ).parentNode.removeChild( script );
- }
+var preservedScriptAttributes = {
+ type: true,
+ src: true,
+ nonce: true,
+ noModule: true
+};
+function DOMEval( code, node, doc ) {
+ doc = doc || document$1;
-function toType( obj ) {
- if ( obj == null ) {
- return obj + "";
+ var i,
+ script = doc.createElement( "script" );
+
+ script.text = code;
+ for ( i in preservedScriptAttributes ) {
+ if ( node && node[ i ] ) {
+ script[ i ] = node[ i ];
+ }
}
- // Support: Android <=2.3 only (functionish RegExp)
- return typeof obj === "object" || typeof obj === "function" ?
- class2type[ toString.call( obj ) ] || "object" :
- typeof obj;
+ if ( doc.head.appendChild( script ).parentNode ) {
+ script.parentNode.removeChild( script );
+ }
}
-/* global Symbol */
-// Defining this global in .eslintrc.json would create a danger of using the global
-// unguarded in another place, it seems safer to define global only for this module
-
-
-var version = "3.7.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/animatedSelector,-effects/Tween",
+var version = "4.0.0+slim",
rhtmlSuffix = /HTML$/i,
@@ -243,13 +212,7 @@ jQuery.fn = jQuery.prototype = {
end: function() {
return this.prevObject || this.constructor();
- },
-
- // For internal use only.
- // Behaves like an Array's method, not like a jQuery method.
- push: push,
- sort: arr.sort,
- splice: arr.splice
+ }
};
jQuery.extend = jQuery.fn.extend = function() {
@@ -269,7 +232,7 @@ jQuery.extend = jQuery.fn.extend = function() {
}
// Handle case when target is a string or something (possible in deep copy)
- if ( typeof target !== "object" && !isFunction( target ) ) {
+ if ( typeof target !== "object" && typeof target !== "function" ) {
target = {};
}
@@ -427,6 +390,7 @@ jQuery.extend( {
return ret;
},
+
// results is for internal usage only
makeArray: function( arr, results ) {
var ret = results || [];
@@ -458,8 +422,20 @@ jQuery.extend( {
return !rhtmlSuffix.test( namespace || docElem && docElem.nodeName || "HTML" );
},
- // Support: Android <=4.0 only, PhantomJS 1 only
- // push.apply(_, arraylike) throws on ancient WebKit
+ // Note: an element does not contain itself
+ contains: function( a, b ) {
+ var bup = b && b.parentNode;
+
+ return a === bup || !!( bup && bup.nodeType === 1 && (
+
+ // Support: IE 9 - 11+
+ // IE doesn't have `contains` on SVG.
+ a.contains ?
+ a.contains( bup ) :
+ a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
+ ) );
+ },
+
merge: function( first, second ) {
var len = +second.length,
j = 0,
@@ -543,201 +519,128 @@ jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symb
class2type[ "[object " + name + "]" ] = name.toLowerCase();
} );
-function isArrayLike( obj ) {
-
- // Support: real iOS 8.2 only (not reproducible in simulator)
- // `in` check used to prevent JIT error (gh-2145)
- // hasOwn isn't used here due to false negatives
- // regarding Nodelist length in IE
- var length = !!obj && "length" in obj && obj.length,
- type = toType( obj );
-
- if ( isFunction( obj ) || isWindow( obj ) ) {
- return false;
- }
-
- return type === "array" || length === 0 ||
- typeof length === "number" && length > 0 && ( length - 1 ) in obj;
-}
-
-
function nodeName( elem, name ) {
-
return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
-
}
-var pop = arr.pop;
+var pop = arr.pop;
-var sort = arr.sort;
+// https://www.w3.org/TR/css3-selectors/#whitespace
+var whitespace = "[\\x20\\t\\r\\n\\f]";
+var isIE = document$1.documentMode;
-var splice = arr.splice;
+var rbuggyQSA = isIE && new RegExp(
+ // Support: IE 9 - 11+
+ // IE's :disabled selector does not pick up the children of disabled fieldsets
+ ":enabled|:disabled|" +
-var whitespace = "[\\x20\\t\\r\\n\\f]";
+ // Support: IE 11+
+ // IE 11 doesn't find elements on a `[name='']` query in some cases.
+ // Adding a temporary attribute to the document before the selection works
+ // around the issue.
+ "\\[" + whitespace + "*name" + whitespace + "*=" +
+ whitespace + "*(?:''|\"\")"
+);
var rtrimCSS = new RegExp(
"^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$",
"g"
);
+// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
+var identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
+ "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+";
+var rleadingCombinator = new RegExp( "^" + whitespace + "*([>+~]|" +
+ whitespace + ")" + whitespace + "*" );
+var rdescend = new RegExp( whitespace + "|>" );
-// Note: an element does not contain itself
-jQuery.contains = function( a, b ) {
- var bup = b && b.parentNode;
-
- return a === bup || !!( bup && bup.nodeType === 1 && (
-
- // Support: IE 9 - 11+
- // IE doesn't have `contains` on SVG.
- a.contains ?
- a.contains( bup ) :
- a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
- ) );
-};
+var rsibling = /[+~]/;
+var documentElement$1 = document$1.documentElement;
+// Support: IE 9 - 11+
+// IE requires a prefix.
+var matches = documentElement$1.matches || documentElement$1.msMatchesSelector;
+/**
+ * Create key-value caches of limited size
+ * @returns {function(string, object)} Returns the Object data after storing it on itself with
+ * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ * deleting the oldest entry
+ */
+function createCache() {
+ var keys = [];
-// CSS string/identifier serialization
-// https://drafts.csswg.org/cssom/#common-serializing-idioms
-var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
+ function cache( key, value ) {
-function fcssescape( ch, asCodePoint ) {
- if ( asCodePoint ) {
+ // Use (key + " ") to avoid collision with native prototype properties
+ // (see https://github.com/jquery/sizzle/issues/157)
+ if ( keys.push( key + " " ) > jQuery.expr.cacheLength ) {
- // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
- if ( ch === "\0" ) {
- return "\uFFFD";
+ // Only keep the most recent entries
+ delete cache[ keys.shift() ];
}
-
- // Control characters and (dependent upon position) numbers get escaped as code points
- return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
+ return ( cache[ key + " " ] = value );
}
-
- // Other potentially-special ASCII characters get backslash-escaped
- return "\\" + ch;
+ return cache;
}
-jQuery.escapeSelector = function( sel ) {
- return ( sel + "" ).replace( rcssescape, fcssescape );
-};
-
-
-
-
-var preferredDoc = document,
- pushNative = push;
-
-( function() {
-
-var i,
- Expr,
- outermostContext,
- sortInput,
- hasDuplicate,
- push = pushNative,
-
- // Local document vars
- document,
- documentElement,
- documentIsHTML,
- rbuggyQSA,
- matches,
-
- // Instance-specific data
- expando = jQuery.expando,
- dirruns = 0,
- done = 0,
- classCache = createCache(),
- tokenCache = createCache(),
- compilerCache = createCache(),
- nonnativeSelectorCache = createCache(),
- sortOrder = function( a, b ) {
- if ( a === b ) {
- hasDuplicate = true;
- }
- return 0;
- },
-
- booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|" +
- "loop|multiple|open|readonly|required|scoped",
-
- // Regular expressions
-
- // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
- identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
- "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
-
- // Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors
- attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
-
- // Operator (capture 2)
- "*([*^$|!~]?=)" + whitespace +
-
- // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
- "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
- whitespace + "*\\]",
-
- pseudos = ":(" + identifier + ")(?:\\((" +
-
- // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
- // 1. quoted (capture 3; capture 4 or capture 5)
- "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
+/**
+ * Checks a node for validity as a jQuery selector context
+ * @param {Element|Object=} context
+ * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
+ */
+function testContext( context ) {
+ return context && typeof context.getElementsByTagName !== "undefined" && context;
+}
- // 2. simple (capture 6)
- "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
+// Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors
+var attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
- // 3. anything else (capture 2)
- ".*" +
- ")\\)|)",
+ // Operator (capture 2)
+ "*([*^$|!~]?=)" + whitespace +
- // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
- rwhitespace = new RegExp( whitespace + "+", "g" ),
+ // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
+ "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
+ whitespace + "*\\]";
- rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
- rleadingCombinator = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" +
- whitespace + "*" ),
- rdescend = new RegExp( whitespace + "|>" ),
+var pseudos = ":(" + identifier + ")(?:\\((" +
- rpseudo = new RegExp( pseudos ),
- ridentifier = new RegExp( "^" + identifier + "$" ),
+ // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
+ // 1. quoted (capture 3; capture 4 or capture 5)
+ "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
- matchExpr = {
- ID: new RegExp( "^#(" + identifier + ")" ),
- CLASS: new RegExp( "^\\.(" + identifier + ")" ),
- TAG: new RegExp( "^(" + identifier + "|[*])" ),
- ATTR: new RegExp( "^" + attributes ),
- PSEUDO: new RegExp( "^" + pseudos ),
- CHILD: new RegExp(
- "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
- whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
- whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
- bool: new RegExp( "^(?:" + booleans + ")$", "i" ),
+ // 2. simple (capture 6)
+ "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
- // For use in libraries implementing .is()
- // We use this for POS matching in `select`
- needsContext: new RegExp( "^" + whitespace +
- "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
- "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
- },
+ // 3. anything else (capture 2)
+ ".*" +
+ ")\\)|)";
- rinputs = /^(?:input|select|textarea|button)$/i,
- rheader = /^h\d$/i,
+var filterMatchExpr = {
+ ID: new RegExp( "^#(" + identifier + ")" ),
+ CLASS: new RegExp( "^\\.(" + identifier + ")" ),
+ TAG: new RegExp( "^(" + identifier + "|[*])" ),
+ ATTR: new RegExp( "^" + attributes ),
+ PSEUDO: new RegExp( "^" + pseudos ),
+ CHILD: new RegExp(
+ "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
+ whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
+ whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" )
+};
- // Easily-parseable/retrievable ID or TAG or CLASS selectors
- rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+var rpseudo = new RegExp( pseudos );
- rsibling = /[+~]/,
+// CSS escapes
+// https://www.w3.org/TR/CSS21/syndata.html#escaped-characters
- // CSS escapes
- // https://www.w3.org/TR/CSS21/syndata.html#escaped-characters
- runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace +
- "?|\\\\([^\\r\\n\\f])", "g" ),
+var runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace +
+ "?|\\\\([^\\r\\n\\f])", "g" ),
funescape = function( escape, nonHex ) {
var high = "0x" + escape.slice( 1 ) - 0x10000;
@@ -754,738 +657,435 @@ var i,
return high < 0 ?
String.fromCharCode( high + 0x10000 ) :
String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
- },
-
- // Used for iframes; see `setDocument`.
- // Support: IE 9 - 11+, Edge 12 - 18+
- // Removing the function wrapper causes a "Permission Denied"
- // error in IE/Edge.
- unloadHandler = function() {
- setDocument();
- },
-
- inDisabledFieldset = addCombinator(
- function( elem ) {
- return elem.disabled === true && nodeName( elem, "fieldset" );
- },
- { dir: "parentNode", next: "legend" }
- );
+ };
-// Support: IE <=9 only
-// Accessing document.activeElement can throw unexpectedly
-// https://bugs.jquery.com/ticket/13393
-function safeActiveElement() {
- try {
- return document.activeElement;
- } catch ( err ) { }
+function unescapeSelector( sel ) {
+ return sel.replace( runescape, funescape );
}
-// Optimize for push.apply( _, NodeList )
-try {
- push.apply(
- ( arr = slice.call( preferredDoc.childNodes ) ),
- preferredDoc.childNodes
- );
-
- // Support: Android <=4.0
- // Detect silently failing push.apply
- // eslint-disable-next-line no-unused-expressions
- arr[ preferredDoc.childNodes.length ].nodeType;
-} catch ( e ) {
- push = {
- apply: function( target, els ) {
- pushNative.apply( target, slice.call( els ) );
- },
- call: function( target ) {
- pushNative.apply( target, slice.call( arguments, 1 ) );
- }
- };
+function selectorError( msg ) {
+ jQuery.error( "Syntax error, unrecognized expression: " + msg );
}
-function find( selector, context, results, seed ) {
- var m, i, elem, nid, match, groups, newSelector,
- newContext = context && context.ownerDocument,
-
- // nodeType defaults to 9, since context defaults to document
- nodeType = context ? context.nodeType : 9;
+var rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" );
- results = results || [];
+var tokenCache = createCache();
- // Return early from calls with invalid selector or context
- if ( typeof selector !== "string" || !selector ||
- nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
+function tokenize( selector, parseOnly ) {
+ var matched, match, tokens, type,
+ soFar, groups, preFilters,
+ cached = tokenCache[ selector + " " ];
- return results;
+ if ( cached ) {
+ return parseOnly ? 0 : cached.slice( 0 );
}
- // Try to shortcut find operations (as opposed to filters) in HTML documents
- if ( !seed ) {
- setDocument( context );
- context = context || document;
-
- if ( documentIsHTML ) {
+ soFar = selector;
+ groups = [];
+ preFilters = jQuery.expr.preFilter;
- // If the selector is sufficiently simple, try using a "get*By*" DOM method
- // (excepting DocumentFragment context, where the methods don't exist)
- if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {
+ while ( soFar ) {
- // ID selector
- if ( ( m = match[ 1 ] ) ) {
+ // Comma and first run
+ if ( !matched || ( match = rcomma.exec( soFar ) ) ) {
+ if ( match ) {
- // Document context
- if ( nodeType === 9 ) {
- if ( ( elem = context.getElementById( m ) ) ) {
+ // Don't consume trailing commas as valid
+ soFar = soFar.slice( match[ 0 ].length ) || soFar;
+ }
+ groups.push( ( tokens = [] ) );
+ }
- // Support: IE 9 only
- // getElementById can match elements by name instead of ID
- if ( elem.id === m ) {
- push.call( results, elem );
- return results;
- }
- } else {
- return results;
- }
+ matched = false;
- // Element context
- } else {
+ // Combinators
+ if ( ( match = rleadingCombinator.exec( soFar ) ) ) {
+ matched = match.shift();
+ tokens.push( {
+ value: matched,
- // Support: IE 9 only
- // getElementById can match elements by name instead of ID
- if ( newContext && ( elem = newContext.getElementById( m ) ) &&
- find.contains( context, elem ) &&
- elem.id === m ) {
+ // Cast descendant combinators to space
+ type: match[ 0 ].replace( rtrimCSS, " " )
+ } );
+ soFar = soFar.slice( matched.length );
+ }
- push.call( results, elem );
- return results;
- }
- }
+ // Filters
+ for ( type in filterMatchExpr ) {
+ if ( ( match = jQuery.expr.match[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
+ ( match = preFilters[ type ]( match ) ) ) ) {
+ matched = match.shift();
+ tokens.push( {
+ value: matched,
+ type: type,
+ matches: match
+ } );
+ soFar = soFar.slice( matched.length );
+ }
+ }
- // Type selector
- } else if ( match[ 2 ] ) {
- push.apply( results, context.getElementsByTagName( selector ) );
- return results;
+ if ( !matched ) {
+ break;
+ }
+ }
- // Class selector
- } else if ( ( m = match[ 3 ] ) && context.getElementsByClassName ) {
- push.apply( results, context.getElementsByClassName( m ) );
- return results;
- }
- }
+ // Return the length of the invalid excess
+ // if we're just parsing
+ // Otherwise, throw an error or return tokens
+ if ( parseOnly ) {
+ return soFar.length;
+ }
- // Take advantage of querySelectorAll
- if ( !nonnativeSelectorCache[ selector + " " ] &&
- ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) ) {
+ return soFar ?
+ selectorError( selector ) :
- newSelector = selector;
- newContext = context;
+ // Cache the tokens
+ tokenCache( selector, groups ).slice( 0 );
+}
- // qSA considers elements outside a scoping root when evaluating child or
- // descendant combinators, which is not what we want.
- // In such cases, we work around the behavior by prefixing every selector in the
- // list with an ID selector referencing the scope context.
- // The technique has to be used as well when a leading combinator is used
- // as such selectors are not recognized by querySelectorAll.
- // Thanks to Andrew Dupont for this technique.
- if ( nodeType === 1 &&
- ( rdescend.test( selector ) || rleadingCombinator.test( selector ) ) ) {
+var preFilter = {
+ ATTR: function( match ) {
+ match[ 1 ] = unescapeSelector( match[ 1 ] );
- // Expand context for sibling selectors
- newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
- context;
+ // Move the given value to match[3] whether quoted or unquoted
+ match[ 3 ] = unescapeSelector( match[ 3 ] || match[ 4 ] || match[ 5 ] || "" );
- // We can use :scope instead of the ID hack if the browser
- // supports it & if we're not changing the context.
- // Support: IE 11+, Edge 17 - 18+
- // IE/Edge sometimes throw a "Permission denied" error when
- // strict-comparing two documents; shallow comparisons work.
- // eslint-disable-next-line eqeqeq
- if ( newContext != context || !support.scope ) {
+ if ( match[ 2 ] === "~=" ) {
+ match[ 3 ] = " " + match[ 3 ] + " ";
+ }
- // Capture the context ID, setting it first if necessary
- if ( ( nid = context.getAttribute( "id" ) ) ) {
- nid = jQuery.escapeSelector( nid );
- } else {
- context.setAttribute( "id", ( nid = expando ) );
- }
- }
+ return match.slice( 0, 4 );
+ },
- // Prefix every selector in the list
- groups = tokenize( selector );
- i = groups.length;
- while ( i-- ) {
- groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
- toSelector( groups[ i ] );
- }
- newSelector = groups.join( "," );
- }
+ CHILD: function( match ) {
- try {
- push.apply( results,
- newContext.querySelectorAll( newSelector )
- );
- return results;
- } catch ( qsaError ) {
- nonnativeSelectorCache( selector, true );
- } finally {
- if ( nid === expando ) {
- context.removeAttribute( "id" );
- }
- }
+ /* matches from filterMatchExpr["CHILD"]
+ 1 type (only|nth|...)
+ 2 what (child|of-type)
+ 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+ 4 xn-component of xn+y argument ([+-]?\d*n|)
+ 5 sign of xn-component
+ 6 x of xn-component
+ 7 sign of y-component
+ 8 y of y-component
+ */
+ match[ 1 ] = match[ 1 ].toLowerCase();
+
+ if ( match[ 1 ].slice( 0, 3 ) === "nth" ) {
+
+ // nth-* requires argument
+ if ( !match[ 3 ] ) {
+ selectorError( match[ 0 ] );
}
- }
- }
- // All others
- return select( selector.replace( rtrimCSS, "$1" ), context, results, seed );
-}
+ // numeric x and y parameters for jQuery.expr.filter.CHILD
+ // remember that false/true cast respectively to 0/1
+ match[ 4 ] = +( match[ 4 ] ?
+ match[ 5 ] + ( match[ 6 ] || 1 ) :
+ 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" )
+ );
+ match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" );
-/**
- * Create key-value caches of limited size
- * @returns {function(string, object)} Returns the Object data after storing it on itself with
- * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
- * deleting the oldest entry
- */
-function createCache() {
- var keys = [];
+ // other types prohibit arguments
+ } else if ( match[ 3 ] ) {
+ selectorError( match[ 0 ] );
+ }
- function cache( key, value ) {
+ return match;
+ },
- // Use (key + " ") to avoid collision with native prototype properties
- // (see https://github.com/jquery/sizzle/issues/157)
- if ( keys.push( key + " " ) > Expr.cacheLength ) {
+ PSEUDO: function( match ) {
+ var excess,
+ unquoted = !match[ 6 ] && match[ 2 ];
- // Only keep the most recent entries
- delete cache[ keys.shift() ];
+ if ( filterMatchExpr.CHILD.test( match[ 0 ] ) ) {
+ return null;
}
- return ( cache[ key + " " ] = value );
- }
- return cache;
-}
-/**
- * Mark a function for special use by jQuery selector module
- * @param {Function} fn The function to mark
- */
-function markFunction( fn ) {
- fn[ expando ] = true;
- return fn;
-}
+ // Accept quoted arguments as-is
+ if ( match[ 3 ] ) {
+ match[ 2 ] = match[ 4 ] || match[ 5 ] || "";
-/**
- * Support testing using an element
- * @param {Function} fn Passed the created element and returns a boolean result
- */
-function assert( fn ) {
- var el = document.createElement( "fieldset" );
+ // Strip excess characters from unquoted arguments
+ } else if ( unquoted && rpseudo.test( unquoted ) &&
- try {
- return !!fn( el );
- } catch ( e ) {
- return false;
- } finally {
+ // Get excess from tokenize (recursively)
+ ( excess = tokenize( unquoted, true ) ) &&
- // Remove from its parent by default
- if ( el.parentNode ) {
- el.parentNode.removeChild( el );
+ // advance to the next closing parenthesis
+ ( excess = unquoted.indexOf( ")", unquoted.length - excess ) -
+ unquoted.length ) ) {
+
+ // excess is a negative index
+ match[ 0 ] = match[ 0 ].slice( 0, excess );
+ match[ 2 ] = unquoted.slice( 0, excess );
}
- // release memory in IE
- el = null;
+ // Return only captures needed by the pseudo filter method (type and argument)
+ return match.slice( 0, 3 );
}
-}
+};
-/**
- * Returns a function to use in pseudos for input types
- * @param {String} type
- */
-function createInputPseudo( type ) {
- return function( elem ) {
- return nodeName( elem, "input" ) && elem.type === type;
- };
+function toSelector( tokens ) {
+ var i = 0,
+ len = tokens.length,
+ selector = "";
+ for ( ; i < len; i++ ) {
+ selector += tokens[ i ].value;
+ }
+ return selector;
}
-/**
- * Returns a function to use in pseudos for buttons
- * @param {String} type
- */
-function createButtonPseudo( type ) {
- return function( elem ) {
- return ( nodeName( elem, "input" ) || nodeName( elem, "button" ) ) &&
- elem.type === type;
- };
-}
+// Multifunctional method to get and set values of a collection
+// The value/s can optionally be executed if it's a function
+function access( elems, fn, key, value, chainable, emptyGet, raw ) {
+ var i = 0,
+ len = elems.length,
+ bulk = key == null;
-/**
- * Returns a function to use in pseudos for :enabled/:disabled
- * @param {Boolean} disabled true for :disabled; false for :enabled
- */
-function createDisabledPseudo( disabled ) {
+ // Sets many values
+ if ( toType( key ) === "object" ) {
+ chainable = true;
+ for ( i in key ) {
+ access( elems, fn, i, key[ i ], true, emptyGet, raw );
+ }
- // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
- return function( elem ) {
+ // Sets one value
+ } else if ( value !== undefined ) {
+ chainable = true;
- // Only certain elements can match :enabled or :disabled
- // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
- // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
- if ( "form" in elem ) {
+ if ( typeof value !== "function" ) {
+ raw = true;
+ }
- // Check for inherited disabledness on relevant non-disabled elements:
- // * listed form-associated elements in a disabled fieldset
- // https://html.spec.whatwg.org/multipage/forms.html#category-listed
- // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
- // * option elements in a disabled optgroup
- // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
- // All such elements have a "form" property.
- if ( elem.parentNode && elem.disabled === false ) {
+ if ( bulk ) {
- // Option elements defer to a parent optgroup if present
- if ( "label" in elem ) {
- if ( "label" in elem.parentNode ) {
- return elem.parentNode.disabled === disabled;
- } else {
- return elem.disabled === disabled;
- }
- }
+ // Bulk operations run against the entire set
+ if ( raw ) {
+ fn.call( elems, value );
+ fn = null;
- // Support: IE 6 - 11+
- // Use the isDisabled shortcut property to check for disabled fieldset ancestors
- return elem.isDisabled === disabled ||
+ // ...except when executing function values
+ } else {
+ bulk = fn;
+ fn = function( elem, _key, value ) {
+ return bulk.call( jQuery( elem ), value );
+ };
+ }
+ }
- // Where there is no isDisabled, check manually
- elem.isDisabled !== !disabled &&
- inDisabledFieldset( elem ) === disabled;
+ if ( fn ) {
+ for ( ; i < len; i++ ) {
+ fn(
+ elems[ i ], key, raw ?
+ value :
+ value.call( elems[ i ], i, fn( elems[ i ], key ) )
+ );
}
+ }
+ }
- return elem.disabled === disabled;
+ if ( chainable ) {
+ return elems;
+ }
- // Try to winnow out elements that can't be disabled before trusting the disabled property.
- // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
- // even exist on them, let alone have a boolean value.
- } else if ( "label" in elem ) {
- return elem.disabled === disabled;
- }
+ // Gets
+ if ( bulk ) {
+ return fn.call( elems );
+ }
- // Remaining elements are neither :enabled nor :disabled
- return false;
- };
+ return len ? fn( elems[ 0 ], key ) : emptyGet;
}
-/**
- * Returns a function to use in pseudos for positionals
- * @param {Function} fn
- */
-function createPositionalPseudo( fn ) {
- return markFunction( function( argument ) {
- argument = +argument;
- return markFunction( function( seed, matches ) {
- var j,
- matchIndexes = fn( [], seed.length, argument ),
- i = matchIndexes.length;
+// Only count HTML whitespace
+// Other whitespace should count in values
+// https://infra.spec.whatwg.org/#ascii-whitespace
+var rnothtmlwhite = /[^\x20\t\r\n\f]+/g;
- // Match elements found at the specified indexes
- while ( i-- ) {
- if ( seed[ ( j = matchIndexes[ i ] ) ] ) {
- seed[ j ] = !( matches[ j ] = seed[ j ] );
- }
- }
+jQuery.fn.extend( {
+ attr: function( name, value ) {
+ return access( this, jQuery.attr, name, value, arguments.length > 1 );
+ },
+
+ removeAttr: function( name ) {
+ return this.each( function() {
+ jQuery.removeAttr( this, name );
} );
- } );
-}
+ }
+} );
-/**
- * Checks a node for validity as a jQuery selector context
- * @param {Element|Object=} context
- * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
- */
-function testContext( context ) {
- return context && typeof context.getElementsByTagName !== "undefined" && context;
-}
-
-/**
- * Sets document-related variables once based on the current document
- * @param {Element|Object} [node] An element or document object to use to set the document
- * @returns {Object} Returns the current document
- */
-function setDocument( node ) {
- var subWindow,
- doc = node ? node.ownerDocument || node : preferredDoc;
-
- // Return early if doc is invalid or already selected
- // Support: IE 11+, Edge 17 - 18+
- // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
- // two documents; shallow comparisons work.
- // eslint-disable-next-line eqeqeq
- if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {
- return document;
- }
-
- // Update global variables
- document = doc;
- documentElement = document.documentElement;
- documentIsHTML = !jQuery.isXMLDoc( document );
-
- // Support: iOS 7 only, IE 9 - 11+
- // Older browsers didn't support unprefixed `matches`.
- matches = documentElement.matches ||
- documentElement.webkitMatchesSelector ||
- documentElement.msMatchesSelector;
-
- // Support: IE 9 - 11+, Edge 12 - 18+
- // Accessing iframe documents after unload throws "permission denied" errors
- // (see trac-13936).
- // Limit the fix to IE & Edge Legacy; despite Edge 15+ implementing `matches`,
- // all IE 9+ and Edge Legacy versions implement `msMatchesSelector` as well.
- if ( documentElement.msMatchesSelector &&
-
- // Support: IE 11+, Edge 17 - 18+
- // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
- // two documents; shallow comparisons work.
- // eslint-disable-next-line eqeqeq
- preferredDoc != document &&
- ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {
-
- // Support: IE 9 - 11+, Edge 12 - 18+
- subWindow.addEventListener( "unload", unloadHandler );
- }
-
- // Support: IE <10
- // Check if getElementById returns elements by name
- // The broken getElementById methods don't pick up programmatically-set names,
- // so use a roundabout getElementsByName test
- support.getById = assert( function( el ) {
- documentElement.appendChild( el ).id = jQuery.expando;
- return !document.getElementsByName ||
- !document.getElementsByName( jQuery.expando ).length;
- } );
-
- // Support: IE 9 only
- // Check to see if it's possible to do matchesSelector
- // on a disconnected node.
- support.disconnectedMatch = assert( function( el ) {
- return matches.call( el, "*" );
- } );
-
- // Support: IE 9 - 11+, Edge 12 - 18+
- // IE/Edge don't support the :scope pseudo-class.
- support.scope = assert( function() {
- return document.querySelectorAll( ":scope" );
- } );
+jQuery.extend( {
+ attr: function( elem, name, value ) {
+ var ret, hooks,
+ nType = elem.nodeType;
- // Support: Chrome 105 - 111 only, Safari 15.4 - 16.3 only
- // Make sure the `:has()` argument is parsed unforgivingly.
- // We include `*` in the test to detect buggy implementations that are
- // _selectively_ forgiving (specifically when the list includes at least
- // one valid selector).
- // Note that we treat complete lack of support for `:has()` as if it were
- // spec-compliant support, which is fine because use of `:has()` in such
- // environments will fail in the qSA path and fall back to jQuery traversal
- // anyway.
- support.cssHas = assert( function() {
- try {
- document.querySelector( ":has(*,:jqfake)" );
- return false;
- } catch ( e ) {
- return true;
+ // Don't get/set attributes on text, comment and attribute nodes
+ if ( nType === 3 || nType === 8 || nType === 2 ) {
+ return;
}
- } );
-
- // ID filter and find
- if ( support.getById ) {
- Expr.filter.ID = function( id ) {
- var attrId = id.replace( runescape, funescape );
- return function( elem ) {
- return elem.getAttribute( "id" ) === attrId;
- };
- };
- Expr.find.ID = function( id, context ) {
- if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
- var elem = context.getElementById( id );
- return elem ? [ elem ] : [];
- }
- };
- } else {
- Expr.filter.ID = function( id ) {
- var attrId = id.replace( runescape, funescape );
- return function( elem ) {
- var node = typeof elem.getAttributeNode !== "undefined" &&
- elem.getAttributeNode( "id" );
- return node && node.value === attrId;
- };
- };
-
- // Support: IE 6 - 7 only
- // getElementById is not reliable as a find shortcut
- Expr.find.ID = function( id, context ) {
- if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
- var node, i, elems,
- elem = context.getElementById( id );
-
- if ( elem ) {
-
- // Verify the id attribute
- node = elem.getAttributeNode( "id" );
- if ( node && node.value === id ) {
- return [ elem ];
- }
-
- // Fall back on getElementsByName
- elems = context.getElementsByName( id );
- i = 0;
- while ( ( elem = elems[ i++ ] ) ) {
- node = elem.getAttributeNode( "id" );
- if ( node && node.value === id ) {
- return [ elem ];
- }
- }
- }
- return [];
- }
- };
- }
-
- // Tag
- Expr.find.TAG = function( tag, context ) {
- if ( typeof context.getElementsByTagName !== "undefined" ) {
- return context.getElementsByTagName( tag );
-
- // DocumentFragment nodes don't have gEBTN
- } else {
- return context.querySelectorAll( tag );
+ // Fallback to prop when attributes are not supported
+ if ( typeof elem.getAttribute === "undefined" ) {
+ return jQuery.prop( elem, name, value );
}
- };
- // Class
- Expr.find.CLASS = function( className, context ) {
- if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
- return context.getElementsByClassName( className );
+ // Attribute hooks are determined by the lowercase version
+ // Grab necessary hook if one is defined
+ if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
+ hooks = jQuery.attrHooks[ name.toLowerCase() ];
}
- };
-
- /* QSA/matchesSelector
- ---------------------------------------------------------------------- */
-
- // QSA and matchesSelector support
- rbuggyQSA = [];
-
- // Build QSA regex
- // Regex strategy adopted from Diego Perini
- assert( function( el ) {
-
- var input;
-
- documentElement.appendChild( el ).innerHTML =
- " " +
- "" +
- " ";
+ if ( value !== undefined ) {
+ if ( value === null ||
- // Support: iOS <=7 - 8 only
- // Boolean attributes and "value" are not treated correctly in some XML documents
- if ( !el.querySelectorAll( "[selected]" ).length ) {
- rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
- }
+ // For compat with previous handling of boolean attributes,
+ // remove when `false` passed. For ARIA attributes -
+ // many of which recognize a `"false"` value - continue to
+ // set the `"false"` value as jQuery <4 did.
+ ( value === false && name.toLowerCase().indexOf( "aria-" ) !== 0 ) ) {
- // Support: iOS <=7 - 8 only
- if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
- rbuggyQSA.push( "~=" );
- }
+ jQuery.removeAttr( elem, name );
+ return;
+ }
- // Support: iOS 8 only
- // https://bugs.webkit.org/show_bug.cgi?id=136851
- // In-page `selector#id sibling-combinator selector` fails
- if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
- rbuggyQSA.push( ".#.+[+~]" );
- }
+ if ( hooks && "set" in hooks &&
+ ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
+ return ret;
+ }
- // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+
- // In some of the document kinds, these selectors wouldn't work natively.
- // This is probably OK but for backwards compatibility we want to maintain
- // handling them through jQuery traversal in jQuery 3.x.
- if ( !el.querySelectorAll( ":checked" ).length ) {
- rbuggyQSA.push( ":checked" );
+ elem.setAttribute( name, value );
+ return value;
}
- // Support: Windows 8 Native Apps
- // The type and name attributes are restricted during .innerHTML assignment
- input = document.createElement( "input" );
- input.setAttribute( "type", "hidden" );
- el.appendChild( input ).setAttribute( "name", "D" );
-
- // Support: IE 9 - 11+
- // IE's :disabled selector does not pick up the children of disabled fieldsets
- // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+
- // In some of the document kinds, these selectors wouldn't work natively.
- // This is probably OK but for backwards compatibility we want to maintain
- // handling them through jQuery traversal in jQuery 3.x.
- documentElement.appendChild( el ).disabled = true;
- if ( el.querySelectorAll( ":disabled" ).length !== 2 ) {
- rbuggyQSA.push( ":enabled", ":disabled" );
- }
-
- // Support: IE 11+, Edge 15 - 18+
- // IE 11/Edge don't find elements on a `[name='']` query in some cases.
- // Adding a temporary attribute to the document before the selection works
- // around the issue.
- // Interestingly, IE 10 & older don't seem to have the issue.
- input = document.createElement( "input" );
- input.setAttribute( "name", "" );
- el.appendChild( input );
- if ( !el.querySelectorAll( "[name='']" ).length ) {
- rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" +
- whitespace + "*(?:''|\"\")" );
+ if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
+ return ret;
}
- } );
- if ( !support.cssHas ) {
+ ret = elem.getAttribute( name );
- // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+
- // Our regular `try-catch` mechanism fails to detect natively-unsupported
- // pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`)
- // in browsers that parse the `:has()` argument as a forgiving selector list.
- // https://drafts.csswg.org/selectors/#relational now requires the argument
- // to be parsed unforgivingly, but browsers have not yet fully adjusted.
- rbuggyQSA.push( ":has" );
- }
+ // Non-existent attributes return null, we normalize to undefined
+ return ret == null ? undefined : ret;
+ },
- rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );
+ attrHooks: {},
- /* Sorting
- ---------------------------------------------------------------------- */
+ removeAttr: function( elem, value ) {
+ var name,
+ i = 0,
- // Document order sorting
- sortOrder = function( a, b ) {
+ // Attribute names can contain non-HTML whitespace characters
+ // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
+ attrNames = value && value.match( rnothtmlwhite );
- // Flag for duplicate removal
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
+ if ( attrNames && elem.nodeType === 1 ) {
+ while ( ( name = attrNames[ i++ ] ) ) {
+ elem.removeAttribute( name );
+ }
}
+ }
+} );
- // Sort on method existence if only one input has compareDocumentPosition
- var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
- if ( compare ) {
- return compare;
+// Support: IE <=11+
+// An input loses its value after becoming a radio
+if ( isIE ) {
+ jQuery.attrHooks.type = {
+ set: function( elem, value ) {
+ if ( value === "radio" && nodeName( elem, "input" ) ) {
+ var val = elem.value;
+ elem.setAttribute( "type", value );
+ if ( val ) {
+ elem.value = val;
+ }
+ return value;
+ }
}
+ };
+}
- // Calculate position if both inputs belong to the same document
- // Support: IE 11+, Edge 17 - 18+
- // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
- // two documents; shallow comparisons work.
- // eslint-disable-next-line eqeqeq
- compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?
- a.compareDocumentPosition( b ) :
-
- // Otherwise we know they are disconnected
- 1;
-
- // Disconnected nodes
- if ( compare & 1 ||
- ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {
-
- // Choose the first element that is related to our preferred document
- // Support: IE 11+, Edge 17 - 18+
- // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
- // two documents; shallow comparisons work.
- // eslint-disable-next-line eqeqeq
- if ( a === document || a.ownerDocument == preferredDoc &&
- find.contains( preferredDoc, a ) ) {
- return -1;
- }
+// CSS string/identifier serialization
+// https://drafts.csswg.org/cssom/#common-serializing-idioms
+var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
- // Support: IE 11+, Edge 17 - 18+
- // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
- // two documents; shallow comparisons work.
- // eslint-disable-next-line eqeqeq
- if ( b === document || b.ownerDocument == preferredDoc &&
- find.contains( preferredDoc, b ) ) {
- return 1;
- }
+function fcssescape( ch, asCodePoint ) {
+ if ( asCodePoint ) {
- // Maintain original order
- return sortInput ?
- ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
- 0;
+ // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
+ if ( ch === "\0" ) {
+ return "\uFFFD";
}
- return compare & 4 ? -1 : 1;
- };
+ // Control characters and (dependent upon position) numbers get escaped as code points
+ return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
+ }
- return document;
+ // Other potentially-special ASCII characters get backslash-escaped
+ return "\\" + ch;
}
-find.matches = function( expr, elements ) {
- return find( expr, null, null, elements );
+jQuery.escapeSelector = function( sel ) {
+ return ( sel + "" ).replace( rcssescape, fcssescape );
};
-find.matchesSelector = function( elem, expr ) {
- setDocument( elem );
+var sort = arr.sort;
- if ( documentIsHTML &&
- !nonnativeSelectorCache[ expr + " " ] &&
- ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
+var splice = arr.splice;
- try {
- var ret = matches.call( elem, expr );
+var hasDuplicate;
- // IE 9's matchesSelector returns false on disconnected nodes
- if ( ret || support.disconnectedMatch ||
+// Document order sorting
+function sortOrder( a, b ) {
- // As well, disconnected nodes are said to be in a document
- // fragment in IE 9
- elem.document && elem.document.nodeType !== 11 ) {
- return ret;
- }
- } catch ( e ) {
- nonnativeSelectorCache( expr, true );
- }
+ // Flag for duplicate removal
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
}
- return find( expr, document, null, [ elem ] ).length > 0;
-};
-
-find.contains = function( context, elem ) {
+ // Sort on method existence if only one input has compareDocumentPosition
+ var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
+ if ( compare ) {
+ return compare;
+ }
- // Set document vars if needed
- // Support: IE 11+, Edge 17 - 18+
- // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // Calculate position if both inputs belong to the same document
+ // Support: IE 11+
+ // IE sometimes throws a "Permission denied" error when strict-comparing
// two documents; shallow comparisons work.
// eslint-disable-next-line eqeqeq
- if ( ( context.ownerDocument || context ) != document ) {
- setDocument( context );
- }
- return jQuery.contains( context, elem );
-};
-
+ compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?
+ a.compareDocumentPosition( b ) :
-find.attr = function( elem, name ) {
+ // Otherwise we know they are disconnected
+ 1;
- // Set document vars if needed
- // Support: IE 11+, Edge 17 - 18+
- // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
- // two documents; shallow comparisons work.
- // eslint-disable-next-line eqeqeq
- if ( ( elem.ownerDocument || elem ) != document ) {
- setDocument( elem );
- }
+ // Disconnected nodes
+ if ( compare & 1 ) {
- var fn = Expr.attrHandle[ name.toLowerCase() ],
+ // Choose the first element that is related to the document
+ // Support: IE 11+
+ // IE sometimes throws a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( a == document$1 || a.ownerDocument == document$1 &&
+ jQuery.contains( document$1, a ) ) {
+ return -1;
+ }
- // Don't get fooled by Object.prototype properties (see trac-13807)
- val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
- fn( elem, name, !documentIsHTML ) :
- undefined;
+ // Support: IE 11+
+ // IE sometimes throws a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( b == document$1 || b.ownerDocument == document$1 &&
+ jQuery.contains( document$1, b ) ) {
+ return 1;
+ }
- if ( val !== undefined ) {
- return val;
+ // Maintain original order
+ return 0;
}
- return elem.getAttribute( name );
-};
-
-find.error = function( msg ) {
- throw new Error( "Syntax error, unrecognized expression: " + msg );
-};
+ return compare & 4 ? -1 : 1;
+}
/**
* Document sorting and removing duplicates
@@ -1497,13 +1097,8 @@ jQuery.uniqueSort = function( results ) {
j = 0,
i = 0;
- // Unless we *know* we can detect duplicates, assume their presence
- //
- // Support: Android <=4.0+
- // Testing for detecting duplicates is unpredictable so instead assume we can't
- // depend on duplicate detection in all browsers without a stable sort.
- hasDuplicate = !support.sortStable;
- sortInput = !support.sortStable && slice.call( results, 0 );
+ hasDuplicate = false;
+
sort.call( results, sortOrder );
if ( hasDuplicate ) {
@@ -1517,10 +1112,6 @@ jQuery.uniqueSort = function( results ) {
}
}
- // Clear input after sorting to release objects
- // See https://github.com/jquery/sizzle/pull/225
- sortInput = null;
-
return results;
};
@@ -1528,6394 +1119,5097 @@ jQuery.fn.uniqueSort = function() {
return this.pushStack( jQuery.uniqueSort( slice.apply( this ) ) );
};
-Expr = jQuery.expr = {
+var i,
+ outermostContext,
- // Can be adjusted by the user
- cacheLength: 50,
+ // Local document vars
+ document,
+ documentElement,
+ documentIsHTML,
- createPseudo: markFunction,
+ // Instance-specific data
+ dirruns = 0,
+ done = 0,
+ classCache = createCache(),
+ compilerCache = createCache(),
+ nonnativeSelectorCache = createCache(),
- match: matchExpr,
+ // Regular expressions
- attrHandle: {},
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+ rwhitespace = new RegExp( whitespace + "+", "g" ),
- find: {},
+ ridentifier = new RegExp( "^" + identifier + "$" ),
- relative: {
- ">": { dir: "parentNode", first: true },
- " ": { dir: "parentNode" },
- "+": { dir: "previousSibling", first: true },
- "~": { dir: "previousSibling" }
- },
+ matchExpr = jQuery.extend( {
+
+ // For use in libraries implementing .is()
+ // We use this for POS matching in `select`
+ needsContext: new RegExp( "^" + whitespace +
+ "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
+ "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+ }, filterMatchExpr ),
- preFilter: {
- ATTR: function( match ) {
- match[ 1 ] = match[ 1 ].replace( runescape, funescape );
+ rinputs = /^(?:input|select|textarea|button)$/i,
+ rheader = /^h\d$/i,
- // Move the given value to match[3] whether quoted or unquoted
- match[ 3 ] = ( match[ 3 ] || match[ 4 ] || match[ 5 ] || "" )
- .replace( runescape, funescape );
+ // Easily-parseable/retrievable ID or TAG or CLASS selectors
+ rquickExpr$1 = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
- if ( match[ 2 ] === "~=" ) {
- match[ 3 ] = " " + match[ 3 ] + " ";
- }
+ // Used for iframes; see `setDocument`.
+ // Support: IE 9 - 11+
+ // Removing the function wrapper causes a "Permission Denied"
+ // error in IE.
+ unloadHandler = function() {
+ setDocument();
+ },
- return match.slice( 0, 4 );
+ inDisabledFieldset = addCombinator(
+ function( elem ) {
+ return elem.disabled === true && nodeName( elem, "fieldset" );
},
+ { dir: "parentNode", next: "legend" }
+ );
- CHILD: function( match ) {
-
- /* matches from matchExpr["CHILD"]
- 1 type (only|nth|...)
- 2 what (child|of-type)
- 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
- 4 xn-component of xn+y argument ([+-]?\d*n|)
- 5 sign of xn-component
- 6 x of xn-component
- 7 sign of y-component
- 8 y of y-component
- */
- match[ 1 ] = match[ 1 ].toLowerCase();
-
- if ( match[ 1 ].slice( 0, 3 ) === "nth" ) {
-
- // nth-* requires argument
- if ( !match[ 3 ] ) {
- find.error( match[ 0 ] );
- }
+function find( selector, context, results, seed ) {
+ var m, i, elem, nid, match, groups, newSelector,
+ newContext = context && context.ownerDocument,
- // numeric x and y parameters for Expr.filter.CHILD
- // remember that false/true cast respectively to 0/1
- match[ 4 ] = +( match[ 4 ] ?
- match[ 5 ] + ( match[ 6 ] || 1 ) :
- 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" )
- );
- match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" );
+ // nodeType defaults to 9, since context defaults to document
+ nodeType = context ? context.nodeType : 9;
- // other types prohibit arguments
- } else if ( match[ 3 ] ) {
- find.error( match[ 0 ] );
- }
+ results = results || [];
- return match;
- },
-
- PSEUDO: function( match ) {
- var excess,
- unquoted = !match[ 6 ] && match[ 2 ];
-
- if ( matchExpr.CHILD.test( match[ 0 ] ) ) {
- return null;
- }
-
- // Accept quoted arguments as-is
- if ( match[ 3 ] ) {
- match[ 2 ] = match[ 4 ] || match[ 5 ] || "";
-
- // Strip excess characters from unquoted arguments
- } else if ( unquoted && rpseudo.test( unquoted ) &&
-
- // Get excess from tokenize (recursively)
- ( excess = tokenize( unquoted, true ) ) &&
-
- // advance to the next closing parenthesis
- ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) {
-
- // excess is a negative index
- match[ 0 ] = match[ 0 ].slice( 0, excess );
- match[ 2 ] = unquoted.slice( 0, excess );
- }
-
- // Return only captures needed by the pseudo filter method (type and argument)
- return match.slice( 0, 3 );
- }
- },
-
- filter: {
-
- TAG: function( nodeNameSelector ) {
- var expectedNodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
- return nodeNameSelector === "*" ?
- function() {
- return true;
- } :
- function( elem ) {
- return nodeName( elem, expectedNodeName );
- };
- },
-
- CLASS: function( className ) {
- var pattern = classCache[ className + " " ];
-
- return pattern ||
- ( pattern = new RegExp( "(^|" + whitespace + ")" + className +
- "(" + whitespace + "|$)" ) ) &&
- classCache( className, function( elem ) {
- return pattern.test(
- typeof elem.className === "string" && elem.className ||
- typeof elem.getAttribute !== "undefined" &&
- elem.getAttribute( "class" ) ||
- ""
- );
- } );
- },
-
- ATTR: function( name, operator, check ) {
- return function( elem ) {
- var result = find.attr( elem, name );
-
- if ( result == null ) {
- return operator === "!=";
- }
- if ( !operator ) {
- return true;
- }
-
- result += "";
-
- if ( operator === "=" ) {
- return result === check;
- }
- if ( operator === "!=" ) {
- return result !== check;
- }
- if ( operator === "^=" ) {
- return check && result.indexOf( check ) === 0;
- }
- if ( operator === "*=" ) {
- return check && result.indexOf( check ) > -1;
- }
- if ( operator === "$=" ) {
- return check && result.slice( -check.length ) === check;
- }
- if ( operator === "~=" ) {
- return ( " " + result.replace( rwhitespace, " " ) + " " )
- .indexOf( check ) > -1;
- }
- if ( operator === "|=" ) {
- return result === check || result.slice( 0, check.length + 1 ) === check + "-";
- }
-
- return false;
- };
- },
-
- CHILD: function( type, what, _argument, first, last ) {
- var simple = type.slice( 0, 3 ) !== "nth",
- forward = type.slice( -4 ) !== "last",
- ofType = what === "of-type";
-
- return first === 1 && last === 0 ?
-
- // Shortcut for :nth-*(n)
- function( elem ) {
- return !!elem.parentNode;
- } :
-
- function( elem, _context, xml ) {
- var cache, outerCache, node, nodeIndex, start,
- dir = simple !== forward ? "nextSibling" : "previousSibling",
- parent = elem.parentNode,
- name = ofType && elem.nodeName.toLowerCase(),
- useCache = !xml && !ofType,
- diff = false;
-
- if ( parent ) {
-
- // :(first|last|only)-(child|of-type)
- if ( simple ) {
- while ( dir ) {
- node = elem;
- while ( ( node = node[ dir ] ) ) {
- if ( ofType ?
- nodeName( node, name ) :
- node.nodeType === 1 ) {
-
- return false;
- }
- }
-
- // Reverse direction for :only-* (if we haven't yet done so)
- start = dir = type === "only" && !start && "nextSibling";
- }
- return true;
- }
-
- start = [ forward ? parent.firstChild : parent.lastChild ];
-
- // non-xml :nth-child(...) stores cache data on `parent`
- if ( forward && useCache ) {
-
- // Seek `elem` from a previously-cached index
- outerCache = parent[ expando ] || ( parent[ expando ] = {} );
- cache = outerCache[ type ] || [];
- nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
- diff = nodeIndex && cache[ 2 ];
- node = nodeIndex && parent.childNodes[ nodeIndex ];
-
- while ( ( node = ++nodeIndex && node && node[ dir ] ||
-
- // Fallback to seeking `elem` from the start
- ( diff = nodeIndex = 0 ) || start.pop() ) ) {
-
- // When found, cache indexes on `parent` and break
- if ( node.nodeType === 1 && ++diff && node === elem ) {
- outerCache[ type ] = [ dirruns, nodeIndex, diff ];
- break;
- }
- }
-
- } else {
-
- // Use previously-cached element index if available
- if ( useCache ) {
- outerCache = elem[ expando ] || ( elem[ expando ] = {} );
- cache = outerCache[ type ] || [];
- nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
- diff = nodeIndex;
- }
-
- // xml :nth-child(...)
- // or :nth-last-child(...) or :nth(-last)?-of-type(...)
- if ( diff === false ) {
-
- // Use the same loop as above to seek `elem` from the start
- while ( ( node = ++nodeIndex && node && node[ dir ] ||
- ( diff = nodeIndex = 0 ) || start.pop() ) ) {
-
- if ( ( ofType ?
- nodeName( node, name ) :
- node.nodeType === 1 ) &&
- ++diff ) {
-
- // Cache the index of each encountered element
- if ( useCache ) {
- outerCache = node[ expando ] ||
- ( node[ expando ] = {} );
- outerCache[ type ] = [ dirruns, diff ];
- }
-
- if ( node === elem ) {
- break;
- }
- }
- }
- }
- }
-
- // Incorporate the offset, then check against cycle size
- diff -= last;
- return diff === first || ( diff % first === 0 && diff / first >= 0 );
- }
- };
- },
-
- PSEUDO: function( pseudo, argument ) {
-
- // pseudo-class names are case-insensitive
- // https://www.w3.org/TR/selectors/#pseudo-classes
- // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
- // Remember that setFilters inherits from pseudos
- var args,
- fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
- find.error( "unsupported pseudo: " + pseudo );
-
- // The user may use createPseudo to indicate that
- // arguments are needed to create the filter function
- // just as jQuery does
- if ( fn[ expando ] ) {
- return fn( argument );
- }
-
- // But maintain support for old signatures
- if ( fn.length > 1 ) {
- args = [ pseudo, pseudo, "", argument ];
- return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
- markFunction( function( seed, matches ) {
- var idx,
- matched = fn( seed, argument ),
- i = matched.length;
- while ( i-- ) {
- idx = indexOf.call( seed, matched[ i ] );
- seed[ idx ] = !( matches[ idx ] = matched[ i ] );
- }
- } ) :
- function( elem ) {
- return fn( elem, 0, args );
- };
- }
-
- return fn;
- }
- },
-
- pseudos: {
-
- // Potentially complex pseudos
- not: markFunction( function( selector ) {
-
- // Trim the selector passed to compile
- // to avoid treating leading and trailing
- // spaces as combinators
- var input = [],
- results = [],
- matcher = compile( selector.replace( rtrimCSS, "$1" ) );
-
- return matcher[ expando ] ?
- markFunction( function( seed, matches, _context, xml ) {
- var elem,
- unmatched = matcher( seed, null, xml, [] ),
- i = seed.length;
-
- // Match elements unmatched by `matcher`
- while ( i-- ) {
- if ( ( elem = unmatched[ i ] ) ) {
- seed[ i ] = !( matches[ i ] = elem );
- }
- }
- } ) :
- function( elem, _context, xml ) {
- input[ 0 ] = elem;
- matcher( input, null, xml, results );
-
- // Don't keep the element
- // (see https://github.com/jquery/sizzle/issues/299)
- input[ 0 ] = null;
- return !results.pop();
- };
- } ),
-
- has: markFunction( function( selector ) {
- return function( elem ) {
- return find( selector, elem ).length > 0;
- };
- } ),
-
- contains: markFunction( function( text ) {
- text = text.replace( runescape, funescape );
- return function( elem ) {
- return ( elem.textContent || jQuery.text( elem ) ).indexOf( text ) > -1;
- };
- } ),
-
- // "Whether an element is represented by a :lang() selector
- // is based solely on the element's language value
- // being equal to the identifier C,
- // or beginning with the identifier C immediately followed by "-".
- // The matching of C against the element's language value is performed case-insensitively.
- // The identifier C does not have to be a valid language name."
- // https://www.w3.org/TR/selectors/#lang-pseudo
- lang: markFunction( function( lang ) {
-
- // lang value must be a valid identifier
- if ( !ridentifier.test( lang || "" ) ) {
- find.error( "unsupported lang: " + lang );
- }
- lang = lang.replace( runescape, funescape ).toLowerCase();
- return function( elem ) {
- var elemLang;
- do {
- if ( ( elemLang = documentIsHTML ?
- elem.lang :
- elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {
-
- elemLang = elemLang.toLowerCase();
- return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
- }
- } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );
- return false;
- };
- } ),
-
- // Miscellaneous
- target: function( elem ) {
- var hash = window.location && window.location.hash;
- return hash && hash.slice( 1 ) === elem.id;
- },
-
- root: function( elem ) {
- return elem === documentElement;
- },
-
- focus: function( elem ) {
- return elem === safeActiveElement() &&
- document.hasFocus() &&
- !!( elem.type || elem.href || ~elem.tabIndex );
- },
-
- // Boolean properties
- enabled: createDisabledPseudo( false ),
- disabled: createDisabledPseudo( true ),
-
- checked: function( elem ) {
-
- // In CSS3, :checked should return both checked and selected elements
- // https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- return ( nodeName( elem, "input" ) && !!elem.checked ) ||
- ( nodeName( elem, "option" ) && !!elem.selected );
- },
-
- selected: function( elem ) {
-
- // Support: IE <=11+
- // Accessing the selectedIndex property
- // forces the browser to treat the default option as
- // selected when in an optgroup.
- if ( elem.parentNode ) {
- // eslint-disable-next-line no-unused-expressions
- elem.parentNode.selectedIndex;
- }
-
- return elem.selected === true;
- },
-
- // Contents
- empty: function( elem ) {
-
- // https://www.w3.org/TR/selectors/#empty-pseudo
- // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
- // but not by others (comment: 8; processing instruction: 7; etc.)
- // nodeType < 6 works because attributes (2) do not appear as children
- for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
- if ( elem.nodeType < 6 ) {
- return false;
- }
- }
- return true;
- },
-
- parent: function( elem ) {
- return !Expr.pseudos.empty( elem );
- },
-
- // Element/input types
- header: function( elem ) {
- return rheader.test( elem.nodeName );
- },
-
- input: function( elem ) {
- return rinputs.test( elem.nodeName );
- },
-
- button: function( elem ) {
- return nodeName( elem, "input" ) && elem.type === "button" ||
- nodeName( elem, "button" );
- },
-
- text: function( elem ) {
- var attr;
- return nodeName( elem, "input" ) && elem.type === "text" &&
-
- // Support: IE <10 only
- // New HTML5 attribute values (e.g., "search") appear
- // with elem.type === "text"
- ( ( attr = elem.getAttribute( "type" ) ) == null ||
- attr.toLowerCase() === "text" );
- },
-
- // Position-in-collection
- first: createPositionalPseudo( function() {
- return [ 0 ];
- } ),
-
- last: createPositionalPseudo( function( _matchIndexes, length ) {
- return [ length - 1 ];
- } ),
-
- eq: createPositionalPseudo( function( _matchIndexes, length, argument ) {
- return [ argument < 0 ? argument + length : argument ];
- } ),
-
- even: createPositionalPseudo( function( matchIndexes, length ) {
- var i = 0;
- for ( ; i < length; i += 2 ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- } ),
-
- odd: createPositionalPseudo( function( matchIndexes, length ) {
- var i = 1;
- for ( ; i < length; i += 2 ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- } ),
-
- lt: createPositionalPseudo( function( matchIndexes, length, argument ) {
- var i;
-
- if ( argument < 0 ) {
- i = argument + length;
- } else if ( argument > length ) {
- i = length;
- } else {
- i = argument;
- }
-
- for ( ; --i >= 0; ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- } ),
-
- gt: createPositionalPseudo( function( matchIndexes, length, argument ) {
- var i = argument < 0 ? argument + length : argument;
- for ( ; ++i < length; ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- } )
- }
-};
-
-Expr.pseudos.nth = Expr.pseudos.eq;
-
-// Add button/input type pseudos
-for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
- Expr.pseudos[ i ] = createInputPseudo( i );
-}
-for ( i in { submit: true, reset: true } ) {
- Expr.pseudos[ i ] = createButtonPseudo( i );
-}
-
-// Easy API for creating new setFilters
-function setFilters() {}
-setFilters.prototype = Expr.filters = Expr.pseudos;
-Expr.setFilters = new setFilters();
-
-function tokenize( selector, parseOnly ) {
- var matched, match, tokens, type,
- soFar, groups, preFilters,
- cached = tokenCache[ selector + " " ];
-
- if ( cached ) {
- return parseOnly ? 0 : cached.slice( 0 );
- }
-
- soFar = selector;
- groups = [];
- preFilters = Expr.preFilter;
-
- while ( soFar ) {
-
- // Comma and first run
- if ( !matched || ( match = rcomma.exec( soFar ) ) ) {
- if ( match ) {
-
- // Don't consume trailing commas as valid
- soFar = soFar.slice( match[ 0 ].length ) || soFar;
- }
- groups.push( ( tokens = [] ) );
- }
-
- matched = false;
-
- // Combinators
- if ( ( match = rleadingCombinator.exec( soFar ) ) ) {
- matched = match.shift();
- tokens.push( {
- value: matched,
-
- // Cast descendant combinators to space
- type: match[ 0 ].replace( rtrimCSS, " " )
- } );
- soFar = soFar.slice( matched.length );
- }
-
- // Filters
- for ( type in Expr.filter ) {
- if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
- ( match = preFilters[ type ]( match ) ) ) ) {
- matched = match.shift();
- tokens.push( {
- value: matched,
- type: type,
- matches: match
- } );
- soFar = soFar.slice( matched.length );
- }
- }
-
- if ( !matched ) {
- break;
- }
- }
-
- // Return the length of the invalid excess
- // if we're just parsing
- // Otherwise, throw an error or return tokens
- if ( parseOnly ) {
- return soFar.length;
- }
-
- return soFar ?
- find.error( selector ) :
-
- // Cache the tokens
- tokenCache( selector, groups ).slice( 0 );
-}
-
-function toSelector( tokens ) {
- var i = 0,
- len = tokens.length,
- selector = "";
- for ( ; i < len; i++ ) {
- selector += tokens[ i ].value;
- }
- return selector;
-}
-
-function addCombinator( matcher, combinator, base ) {
- var dir = combinator.dir,
- skip = combinator.next,
- key = skip || dir,
- checkNonElements = base && key === "parentNode",
- doneName = done++;
-
- return combinator.first ?
-
- // Check against closest ancestor/preceding element
- function( elem, context, xml ) {
- while ( ( elem = elem[ dir ] ) ) {
- if ( elem.nodeType === 1 || checkNonElements ) {
- return matcher( elem, context, xml );
- }
- }
- return false;
- } :
-
- // Check against all ancestor/preceding elements
- function( elem, context, xml ) {
- var oldCache, outerCache,
- newCache = [ dirruns, doneName ];
-
- // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
- if ( xml ) {
- while ( ( elem = elem[ dir ] ) ) {
- if ( elem.nodeType === 1 || checkNonElements ) {
- if ( matcher( elem, context, xml ) ) {
- return true;
- }
- }
- }
- } else {
- while ( ( elem = elem[ dir ] ) ) {
- if ( elem.nodeType === 1 || checkNonElements ) {
- outerCache = elem[ expando ] || ( elem[ expando ] = {} );
-
- if ( skip && nodeName( elem, skip ) ) {
- elem = elem[ dir ] || elem;
- } else if ( ( oldCache = outerCache[ key ] ) &&
- oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
-
- // Assign to newCache so results back-propagate to previous elements
- return ( newCache[ 2 ] = oldCache[ 2 ] );
- } else {
-
- // Reuse newcache so results back-propagate to previous elements
- outerCache[ key ] = newCache;
-
- // A match means we're done; a fail means we have to keep checking
- if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {
- return true;
- }
- }
- }
- }
- }
- return false;
- };
-}
-
-function elementMatcher( matchers ) {
- return matchers.length > 1 ?
- function( elem, context, xml ) {
- var i = matchers.length;
- while ( i-- ) {
- if ( !matchers[ i ]( elem, context, xml ) ) {
- return false;
- }
- }
- return true;
- } :
- matchers[ 0 ];
-}
-
-function multipleContexts( selector, contexts, results ) {
- var i = 0,
- len = contexts.length;
- for ( ; i < len; i++ ) {
- find( selector, contexts[ i ], results );
- }
- return results;
-}
-
-function condense( unmatched, map, filter, context, xml ) {
- var elem,
- newUnmatched = [],
- i = 0,
- len = unmatched.length,
- mapped = map != null;
-
- for ( ; i < len; i++ ) {
- if ( ( elem = unmatched[ i ] ) ) {
- if ( !filter || filter( elem, context, xml ) ) {
- newUnmatched.push( elem );
- if ( mapped ) {
- map.push( i );
- }
- }
- }
- }
-
- return newUnmatched;
-}
-
-function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
- if ( postFilter && !postFilter[ expando ] ) {
- postFilter = setMatcher( postFilter );
- }
- if ( postFinder && !postFinder[ expando ] ) {
- postFinder = setMatcher( postFinder, postSelector );
- }
- return markFunction( function( seed, results, context, xml ) {
- var temp, i, elem, matcherOut,
- preMap = [],
- postMap = [],
- preexisting = results.length,
-
- // Get initial elements from seed or context
- elems = seed ||
- multipleContexts( selector || "*",
- context.nodeType ? [ context ] : context, [] ),
-
- // Prefilter to get matcher input, preserving a map for seed-results synchronization
- matcherIn = preFilter && ( seed || !selector ) ?
- condense( elems, preMap, preFilter, context, xml ) :
- elems;
-
- if ( matcher ) {
-
- // If we have a postFinder, or filtered seed, or non-seed postFilter
- // or preexisting results,
- matcherOut = postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
-
- // ...intermediate processing is necessary
- [] :
-
- // ...otherwise use results directly
- results;
-
- // Find primary matches
- matcher( matcherIn, matcherOut, context, xml );
- } else {
- matcherOut = matcherIn;
- }
-
- // Apply postFilter
- if ( postFilter ) {
- temp = condense( matcherOut, postMap );
- postFilter( temp, [], context, xml );
-
- // Un-match failing elements by moving them back to matcherIn
- i = temp.length;
- while ( i-- ) {
- if ( ( elem = temp[ i ] ) ) {
- matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );
- }
- }
- }
-
- if ( seed ) {
- if ( postFinder || preFilter ) {
- if ( postFinder ) {
-
- // Get the final matcherOut by condensing this intermediate into postFinder contexts
- temp = [];
- i = matcherOut.length;
- while ( i-- ) {
- if ( ( elem = matcherOut[ i ] ) ) {
-
- // Restore matcherIn since elem is not yet a final match
- temp.push( ( matcherIn[ i ] = elem ) );
- }
- }
- postFinder( null, ( matcherOut = [] ), temp, xml );
- }
-
- // Move matched elements from seed to results to keep them synchronized
- i = matcherOut.length;
- while ( i-- ) {
- if ( ( elem = matcherOut[ i ] ) &&
- ( temp = postFinder ? indexOf.call( seed, elem ) : preMap[ i ] ) > -1 ) {
-
- seed[ temp ] = !( results[ temp ] = elem );
- }
- }
- }
-
- // Add elements to results, through postFinder if defined
- } else {
- matcherOut = condense(
- matcherOut === results ?
- matcherOut.splice( preexisting, matcherOut.length ) :
- matcherOut
- );
- if ( postFinder ) {
- postFinder( null, results, matcherOut, xml );
- } else {
- push.apply( results, matcherOut );
- }
- }
- } );
-}
-
-function matcherFromTokens( tokens ) {
- var checkContext, matcher, j,
- len = tokens.length,
- leadingRelative = Expr.relative[ tokens[ 0 ].type ],
- implicitRelative = leadingRelative || Expr.relative[ " " ],
- i = leadingRelative ? 1 : 0,
-
- // The foundational matcher ensures that elements are reachable from top-level context(s)
- matchContext = addCombinator( function( elem ) {
- return elem === checkContext;
- }, implicitRelative, true ),
- matchAnyContext = addCombinator( function( elem ) {
- return indexOf.call( checkContext, elem ) > -1;
- }, implicitRelative, true ),
- matchers = [ function( elem, context, xml ) {
-
- // Support: IE 11+, Edge 17 - 18+
- // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
- // two documents; shallow comparisons work.
- // eslint-disable-next-line eqeqeq
- var ret = ( !leadingRelative && ( xml || context != outermostContext ) ) || (
- ( checkContext = context ).nodeType ?
- matchContext( elem, context, xml ) :
- matchAnyContext( elem, context, xml ) );
-
- // Avoid hanging onto element
- // (see https://github.com/jquery/sizzle/issues/299)
- checkContext = null;
- return ret;
- } ];
-
- for ( ; i < len; i++ ) {
- if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {
- matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
- } else {
- matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );
-
- // Return special upon seeing a positional matcher
- if ( matcher[ expando ] ) {
-
- // Find the next relative operator (if any) for proper handling
- j = ++i;
- for ( ; j < len; j++ ) {
- if ( Expr.relative[ tokens[ j ].type ] ) {
- break;
- }
- }
- return setMatcher(
- i > 1 && elementMatcher( matchers ),
- i > 1 && toSelector(
-
- // If the preceding token was a descendant combinator, insert an implicit any-element `*`
- tokens.slice( 0, i - 1 )
- .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } )
- ).replace( rtrimCSS, "$1" ),
- matcher,
- i < j && matcherFromTokens( tokens.slice( i, j ) ),
- j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),
- j < len && toSelector( tokens )
- );
- }
- matchers.push( matcher );
- }
- }
-
- return elementMatcher( matchers );
-}
-
-function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
- var bySet = setMatchers.length > 0,
- byElement = elementMatchers.length > 0,
- superMatcher = function( seed, context, xml, results, outermost ) {
- var elem, j, matcher,
- matchedCount = 0,
- i = "0",
- unmatched = seed && [],
- setMatched = [],
- contextBackup = outermostContext,
-
- // We must always have either seed elements or outermost context
- elems = seed || byElement && Expr.find.TAG( "*", outermost ),
-
- // Use integer dirruns iff this is the outermost matcher
- dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),
- len = elems.length;
-
- if ( outermost ) {
-
- // Support: IE 11+, Edge 17 - 18+
- // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
- // two documents; shallow comparisons work.
- // eslint-disable-next-line eqeqeq
- outermostContext = context == document || context || outermost;
- }
-
- // Add elements passing elementMatchers directly to results
- // Support: iOS <=7 - 9 only
- // Tolerate NodeList properties (IE: "length"; Safari: ) matching
- // elements by id. (see trac-14142)
- for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {
- if ( byElement && elem ) {
- j = 0;
-
- // Support: IE 11+, Edge 17 - 18+
- // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
- // two documents; shallow comparisons work.
- // eslint-disable-next-line eqeqeq
- if ( !context && elem.ownerDocument != document ) {
- setDocument( elem );
- xml = !documentIsHTML;
- }
- while ( ( matcher = elementMatchers[ j++ ] ) ) {
- if ( matcher( elem, context || document, xml ) ) {
- push.call( results, elem );
- break;
- }
- }
- if ( outermost ) {
- dirruns = dirrunsUnique;
- }
- }
-
- // Track unmatched elements for set filters
- if ( bySet ) {
-
- // They will have gone through all possible matchers
- if ( ( elem = !matcher && elem ) ) {
- matchedCount--;
- }
-
- // Lengthen the array for every element, matched or not
- if ( seed ) {
- unmatched.push( elem );
- }
- }
- }
-
- // `i` is now the count of elements visited above, and adding it to `matchedCount`
- // makes the latter nonnegative.
- matchedCount += i;
-
- // Apply set filters to unmatched elements
- // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
- // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
- // no element matchers and no seed.
- // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
- // case, which will result in a "00" `matchedCount` that differs from `i` but is also
- // numerically zero.
- if ( bySet && i !== matchedCount ) {
- j = 0;
- while ( ( matcher = setMatchers[ j++ ] ) ) {
- matcher( unmatched, setMatched, context, xml );
- }
-
- if ( seed ) {
-
- // Reintegrate element matches to eliminate the need for sorting
- if ( matchedCount > 0 ) {
- while ( i-- ) {
- if ( !( unmatched[ i ] || setMatched[ i ] ) ) {
- setMatched[ i ] = pop.call( results );
- }
- }
- }
-
- // Discard index placeholder values to get only actual matches
- setMatched = condense( setMatched );
- }
-
- // Add matches to results
- push.apply( results, setMatched );
-
- // Seedless set matches succeeding multiple successful matchers stipulate sorting
- if ( outermost && !seed && setMatched.length > 0 &&
- ( matchedCount + setMatchers.length ) > 1 ) {
-
- jQuery.uniqueSort( results );
- }
- }
-
- // Override manipulation of globals by nested matchers
- if ( outermost ) {
- dirruns = dirrunsUnique;
- outermostContext = contextBackup;
- }
-
- return unmatched;
- };
-
- return bySet ?
- markFunction( superMatcher ) :
- superMatcher;
-}
-
-function compile( selector, match /* Internal Use Only */ ) {
- var i,
- setMatchers = [],
- elementMatchers = [],
- cached = compilerCache[ selector + " " ];
-
- if ( !cached ) {
-
- // Generate a function of recursive functions that can be used to check each element
- if ( !match ) {
- match = tokenize( selector );
- }
- i = match.length;
- while ( i-- ) {
- cached = matcherFromTokens( match[ i ] );
- if ( cached[ expando ] ) {
- setMatchers.push( cached );
- } else {
- elementMatchers.push( cached );
- }
- }
-
- // Cache the compiled function
- cached = compilerCache( selector,
- matcherFromGroupMatchers( elementMatchers, setMatchers ) );
-
- // Save selector and tokenization
- cached.selector = selector;
- }
- return cached;
-}
-
-/**
- * A low-level selection function that works with jQuery's compiled
- * selector functions
- * @param {String|Function} selector A selector or a pre-compiled
- * selector function built with jQuery selector compile
- * @param {Element} context
- * @param {Array} [results]
- * @param {Array} [seed] A set of elements to match against
- */
-function select( selector, context, results, seed ) {
- var i, tokens, token, type, find,
- compiled = typeof selector === "function" && selector,
- match = !seed && tokenize( ( selector = compiled.selector || selector ) );
-
- results = results || [];
-
- // Try to minimize operations if there is only one selector in the list and no seed
- // (the latter of which guarantees us context)
- if ( match.length === 1 ) {
-
- // Reduce context if the leading compound selector is an ID
- tokens = match[ 0 ] = match[ 0 ].slice( 0 );
- if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&
- context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {
-
- context = ( Expr.find.ID(
- token.matches[ 0 ].replace( runescape, funescape ),
- context
- ) || [] )[ 0 ];
- if ( !context ) {
- return results;
-
- // Precompiled matchers will still verify ancestry, so step up a level
- } else if ( compiled ) {
- context = context.parentNode;
- }
-
- selector = selector.slice( tokens.shift().value.length );
- }
-
- // Fetch a seed set for right-to-left matching
- i = matchExpr.needsContext.test( selector ) ? 0 : tokens.length;
- while ( i-- ) {
- token = tokens[ i ];
-
- // Abort if we hit a combinator
- if ( Expr.relative[ ( type = token.type ) ] ) {
- break;
- }
- if ( ( find = Expr.find[ type ] ) ) {
-
- // Search, expanding context for leading sibling combinators
- if ( ( seed = find(
- token.matches[ 0 ].replace( runescape, funescape ),
- rsibling.test( tokens[ 0 ].type ) &&
- testContext( context.parentNode ) || context
- ) ) ) {
-
- // If seed is empty or no tokens remain, we can return early
- tokens.splice( i, 1 );
- selector = seed.length && toSelector( tokens );
- if ( !selector ) {
- push.apply( results, seed );
- return results;
- }
-
- break;
- }
- }
- }
- }
-
- // Compile and execute a filtering function if one is not provided
- // Provide `match` to avoid retokenization if we modified the selector above
- ( compiled || compile( selector, match ) )(
- seed,
- context,
- !documentIsHTML,
- results,
- !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
- );
- return results;
-}
-
-// One-time assignments
-
-// Support: Android <=4.0 - 4.1+
-// Sort stability
-support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando;
-
-// Initialize against the default document
-setDocument();
-
-// Support: Android <=4.0 - 4.1+
-// Detached nodes confoundingly follow *each other*
-support.sortDetached = assert( function( el ) {
-
- // Should return 1, but returns 4 (following)
- return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1;
-} );
-
-jQuery.find = find;
-
-// Deprecated
-jQuery.expr[ ":" ] = jQuery.expr.pseudos;
-jQuery.unique = jQuery.uniqueSort;
-
-// These have always been private, but they used to be documented as part of
-// Sizzle so let's maintain them for now for backwards compatibility purposes.
-find.compile = compile;
-find.select = select;
-find.setDocument = setDocument;
-find.tokenize = tokenize;
-
-find.escape = jQuery.escapeSelector;
-find.getText = jQuery.text;
-find.isXML = jQuery.isXMLDoc;
-find.selectors = jQuery.expr;
-find.support = jQuery.support;
-find.uniqueSort = jQuery.uniqueSort;
-
- /* eslint-enable */
-
-} )();
-
-
-var dir = function( elem, dir, until ) {
- var matched = [],
- truncate = until !== undefined;
-
- while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
- if ( elem.nodeType === 1 ) {
- if ( truncate && jQuery( elem ).is( until ) ) {
- break;
- }
- matched.push( elem );
- }
- }
- return matched;
-};
-
-
-var siblings = function( n, elem ) {
- var matched = [];
-
- for ( ; n; n = n.nextSibling ) {
- if ( n.nodeType === 1 && n !== elem ) {
- matched.push( n );
- }
- }
-
- return matched;
-};
-
-
-var rneedsContext = jQuery.expr.match.needsContext;
-
-var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
-
-
-
-// Implement the identical functionality for filter and not
-function winnow( elements, qualifier, not ) {
- if ( isFunction( qualifier ) ) {
- return jQuery.grep( elements, function( elem, i ) {
- return !!qualifier.call( elem, i, elem ) !== not;
- } );
- }
-
- // Single element
- if ( qualifier.nodeType ) {
- return jQuery.grep( elements, function( elem ) {
- return ( elem === qualifier ) !== not;
- } );
- }
-
- // Arraylike of elements (jQuery, arguments, Array)
- if ( typeof qualifier !== "string" ) {
- return jQuery.grep( elements, function( elem ) {
- return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
- } );
- }
-
- // Filtered directly for both simple and complex selectors
- return jQuery.filter( qualifier, elements, not );
-}
-
-jQuery.filter = function( expr, elems, not ) {
- var elem = elems[ 0 ];
-
- if ( not ) {
- expr = ":not(" + expr + ")";
- }
-
- if ( elems.length === 1 && elem.nodeType === 1 ) {
- return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
- }
-
- return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
- return elem.nodeType === 1;
- } ) );
-};
-
-jQuery.fn.extend( {
- find: function( selector ) {
- var i, ret,
- len = this.length,
- self = this;
-
- if ( typeof selector !== "string" ) {
- return this.pushStack( jQuery( selector ).filter( function() {
- for ( i = 0; i < len; i++ ) {
- if ( jQuery.contains( self[ i ], this ) ) {
- return true;
- }
- }
- } ) );
- }
-
- ret = this.pushStack( [] );
-
- for ( i = 0; i < len; i++ ) {
- jQuery.find( selector, self[ i ], ret );
- }
-
- return len > 1 ? jQuery.uniqueSort( ret ) : ret;
- },
- filter: function( selector ) {
- return this.pushStack( winnow( this, selector || [], false ) );
- },
- not: function( selector ) {
- return this.pushStack( winnow( this, selector || [], true ) );
- },
- is: function( selector ) {
- return !!winnow(
- this,
-
- // If this is a positional/relative selector, check membership in the returned set
- // so $("p:first").is("p:last") won't return true for a doc with two "p".
- typeof selector === "string" && rneedsContext.test( selector ) ?
- jQuery( selector ) :
- selector || [],
- false
- ).length;
- }
-} );
-
-
-// Initialize a jQuery object
-
-
-// A central reference to the root jQuery(document)
-var rootjQuery,
-
- // A simple way to check for HTML strings
- // Prioritize #id over to avoid XSS via location.hash (trac-9521)
- // Strict HTML recognition (trac-11290: must start with <)
- // Shortcut simple #id case for speed
- rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
-
- init = jQuery.fn.init = function( selector, context, root ) {
- var match, elem;
-
- // HANDLE: $(""), $(null), $(undefined), $(false)
- if ( !selector ) {
- return this;
- }
-
- // Method init() accepts an alternate rootjQuery
- // so migrate can support jQuery.sub (gh-2101)
- root = root || rootjQuery;
-
- // Handle HTML strings
- if ( typeof selector === "string" ) {
- if ( selector[ 0 ] === "<" &&
- selector[ selector.length - 1 ] === ">" &&
- selector.length >= 3 ) {
-
- // Assume that strings that start and end with <> are HTML and skip the regex check
- match = [ null, selector, null ];
-
- } else {
- match = rquickExpr.exec( selector );
- }
-
- // Match html or make sure no context is specified for #id
- if ( match && ( match[ 1 ] || !context ) ) {
-
- // HANDLE: $(html) -> $(array)
- if ( match[ 1 ] ) {
- context = context instanceof jQuery ? context[ 0 ] : context;
-
- // Option to run scripts is true for back-compat
- // Intentionally let the error be thrown if parseHTML is not present
- jQuery.merge( this, jQuery.parseHTML(
- match[ 1 ],
- context && context.nodeType ? context.ownerDocument || context : document,
- true
- ) );
-
- // HANDLE: $(html, props)
- if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
- for ( match in context ) {
-
- // Properties of context are called as methods if possible
- if ( isFunction( this[ match ] ) ) {
- this[ match ]( context[ match ] );
-
- // ...and otherwise set as attributes
- } else {
- this.attr( match, context[ match ] );
- }
- }
- }
-
- return this;
-
- // HANDLE: $(#id)
- } else {
- elem = document.getElementById( match[ 2 ] );
-
- if ( elem ) {
-
- // Inject the element directly into the jQuery object
- this[ 0 ] = elem;
- this.length = 1;
- }
- return this;
- }
-
- // HANDLE: $(expr, $(...))
- } else if ( !context || context.jquery ) {
- return ( context || root ).find( selector );
-
- // HANDLE: $(expr, context)
- // (which is just equivalent to: $(context).find(expr)
- } else {
- return this.constructor( context ).find( selector );
- }
-
- // HANDLE: $(DOMElement)
- } else if ( selector.nodeType ) {
- this[ 0 ] = selector;
- this.length = 1;
- return this;
-
- // HANDLE: $(function)
- // Shortcut for document ready
- } else if ( isFunction( selector ) ) {
- return root.ready !== undefined ?
- root.ready( selector ) :
-
- // Execute immediately if ready is not present
- selector( jQuery );
- }
-
- return jQuery.makeArray( selector, this );
- };
-
-// Give the init function the jQuery prototype for later instantiation
-init.prototype = jQuery.fn;
-
-// Initialize central reference
-rootjQuery = jQuery( document );
-
-
-var rparentsprev = /^(?:parents|prev(?:Until|All))/,
-
- // Methods guaranteed to produce a unique set when starting from a unique set
- guaranteedUnique = {
- children: true,
- contents: true,
- next: true,
- prev: true
- };
-
-jQuery.fn.extend( {
- has: function( target ) {
- var targets = jQuery( target, this ),
- l = targets.length;
-
- return this.filter( function() {
- var i = 0;
- for ( ; i < l; i++ ) {
- if ( jQuery.contains( this, targets[ i ] ) ) {
- return true;
- }
- }
- } );
- },
-
- closest: function( selectors, context ) {
- var cur,
- i = 0,
- l = this.length,
- matched = [],
- targets = typeof selectors !== "string" && jQuery( selectors );
-
- // Positional selectors never match, since there's no _selection_ context
- if ( !rneedsContext.test( selectors ) ) {
- for ( ; i < l; i++ ) {
- for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
-
- // Always skip document fragments
- if ( cur.nodeType < 11 && ( targets ?
- targets.index( cur ) > -1 :
-
- // Don't pass non-elements to jQuery#find
- cur.nodeType === 1 &&
- jQuery.find.matchesSelector( cur, selectors ) ) ) {
-
- matched.push( cur );
- break;
- }
- }
- }
- }
-
- return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
- },
-
- // Determine the position of an element within the set
- index: function( elem ) {
-
- // No argument, return index in parent
- if ( !elem ) {
- return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
- }
-
- // Index in selector
- if ( typeof elem === "string" ) {
- return indexOf.call( jQuery( elem ), this[ 0 ] );
- }
-
- // Locate the position of the desired element
- return indexOf.call( this,
-
- // If it receives a jQuery object, the first element is used
- elem.jquery ? elem[ 0 ] : elem
- );
- },
-
- add: function( selector, context ) {
- return this.pushStack(
- jQuery.uniqueSort(
- jQuery.merge( this.get(), jQuery( selector, context ) )
- )
- );
- },
-
- addBack: function( selector ) {
- return this.add( selector == null ?
- this.prevObject : this.prevObject.filter( selector )
- );
- }
-} );
-
-function sibling( cur, dir ) {
- while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
- return cur;
-}
-
-jQuery.each( {
- parent: function( elem ) {
- var parent = elem.parentNode;
- return parent && parent.nodeType !== 11 ? parent : null;
- },
- parents: function( elem ) {
- return dir( elem, "parentNode" );
- },
- parentsUntil: function( elem, _i, until ) {
- return dir( elem, "parentNode", until );
- },
- next: function( elem ) {
- return sibling( elem, "nextSibling" );
- },
- prev: function( elem ) {
- return sibling( elem, "previousSibling" );
- },
- nextAll: function( elem ) {
- return dir( elem, "nextSibling" );
- },
- prevAll: function( elem ) {
- return dir( elem, "previousSibling" );
- },
- nextUntil: function( elem, _i, until ) {
- return dir( elem, "nextSibling", until );
- },
- prevUntil: function( elem, _i, until ) {
- return dir( elem, "previousSibling", until );
- },
- siblings: function( elem ) {
- return siblings( ( elem.parentNode || {} ).firstChild, elem );
- },
- children: function( elem ) {
- return siblings( elem.firstChild );
- },
- contents: function( elem ) {
- if ( elem.contentDocument != null &&
-
- // Support: IE 11+
- // elements with no `data` attribute has an object
- // `contentDocument` with a `null` prototype.
- getProto( elem.contentDocument ) ) {
-
- return elem.contentDocument;
- }
-
- // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
- // Treat the template element as a regular one in browsers that
- // don't support it.
- if ( nodeName( elem, "template" ) ) {
- elem = elem.content || elem;
- }
-
- return jQuery.merge( [], elem.childNodes );
- }
-}, function( name, fn ) {
- jQuery.fn[ name ] = function( until, selector ) {
- var matched = jQuery.map( this, fn, until );
-
- if ( name.slice( -5 ) !== "Until" ) {
- selector = until;
- }
-
- if ( selector && typeof selector === "string" ) {
- matched = jQuery.filter( selector, matched );
- }
-
- if ( this.length > 1 ) {
-
- // Remove duplicates
- if ( !guaranteedUnique[ name ] ) {
- jQuery.uniqueSort( matched );
- }
-
- // Reverse order for parents* and prev-derivatives
- if ( rparentsprev.test( name ) ) {
- matched.reverse();
- }
- }
-
- return this.pushStack( matched );
- };
-} );
-var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
-
-
-
-// Convert String-formatted options into Object-formatted ones
-function createOptions( options ) {
- var object = {};
- jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
- object[ flag ] = true;
- } );
- return object;
-}
-
-/*
- * Create a callback list using the following parameters:
- *
- * options: an optional list of space-separated options that will change how
- * the callback list behaves or a more traditional option object
- *
- * By default a callback list will act like an event callback list and can be
- * "fired" multiple times.
- *
- * Possible options:
- *
- * once: will ensure the callback list can only be fired once (like a Deferred)
- *
- * memory: will keep track of previous values and will call any callback added
- * after the list has been fired right away with the latest "memorized"
- * values (like a Deferred)
- *
- * unique: will ensure a callback can only be added once (no duplicate in the list)
- *
- * stopOnFalse: interrupt callings when a callback returns false
- *
- */
-jQuery.Callbacks = function( options ) {
-
- // Convert options from String-formatted to Object-formatted if needed
- // (we check in cache first)
- options = typeof options === "string" ?
- createOptions( options ) :
- jQuery.extend( {}, options );
-
- var // Flag to know if list is currently firing
- firing,
-
- // Last fire value for non-forgettable lists
- memory,
-
- // Flag to know if list was already fired
- fired,
-
- // Flag to prevent firing
- locked,
-
- // Actual callback list
- list = [],
-
- // Queue of execution data for repeatable lists
- queue = [],
-
- // Index of currently firing callback (modified by add/remove as needed)
- firingIndex = -1,
-
- // Fire callbacks
- fire = function() {
-
- // Enforce single-firing
- locked = locked || options.once;
-
- // Execute callbacks for all pending executions,
- // respecting firingIndex overrides and runtime changes
- fired = firing = true;
- for ( ; queue.length; firingIndex = -1 ) {
- memory = queue.shift();
- while ( ++firingIndex < list.length ) {
-
- // Run callback and check for early termination
- if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
- options.stopOnFalse ) {
-
- // Jump to end and forget the data so .add doesn't re-fire
- firingIndex = list.length;
- memory = false;
- }
- }
- }
-
- // Forget the data if we're done with it
- if ( !options.memory ) {
- memory = false;
- }
-
- firing = false;
-
- // Clean up if we're done firing for good
- if ( locked ) {
-
- // Keep an empty list if we have data for future add calls
- if ( memory ) {
- list = [];
-
- // Otherwise, this object is spent
- } else {
- list = "";
- }
- }
- },
-
- // Actual Callbacks object
- self = {
-
- // Add a callback or a collection of callbacks to the list
- add: function() {
- if ( list ) {
-
- // If we have memory from a past run, we should fire after adding
- if ( memory && !firing ) {
- firingIndex = list.length - 1;
- queue.push( memory );
- }
-
- ( function add( args ) {
- jQuery.each( args, function( _, arg ) {
- if ( isFunction( arg ) ) {
- if ( !options.unique || !self.has( arg ) ) {
- list.push( arg );
- }
- } else if ( arg && arg.length && toType( arg ) !== "string" ) {
-
- // Inspect recursively
- add( arg );
- }
- } );
- } )( arguments );
-
- if ( memory && !firing ) {
- fire();
- }
- }
- return this;
- },
-
- // Remove a callback from the list
- remove: function() {
- jQuery.each( arguments, function( _, arg ) {
- var index;
- while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
- list.splice( index, 1 );
-
- // Handle firing indexes
- if ( index <= firingIndex ) {
- firingIndex--;
- }
- }
- } );
- return this;
- },
-
- // Check if a given callback is in the list.
- // If no argument is given, return whether or not list has callbacks attached.
- has: function( fn ) {
- return fn ?
- jQuery.inArray( fn, list ) > -1 :
- list.length > 0;
- },
-
- // Remove all callbacks from the list
- empty: function() {
- if ( list ) {
- list = [];
- }
- return this;
- },
-
- // Disable .fire and .add
- // Abort any current/pending executions
- // Clear all callbacks and values
- disable: function() {
- locked = queue = [];
- list = memory = "";
- return this;
- },
- disabled: function() {
- return !list;
- },
-
- // Disable .fire
- // Also disable .add unless we have memory (since it would have no effect)
- // Abort any pending executions
- lock: function() {
- locked = queue = [];
- if ( !memory && !firing ) {
- list = memory = "";
- }
- return this;
- },
- locked: function() {
- return !!locked;
- },
-
- // Call all callbacks with the given context and arguments
- fireWith: function( context, args ) {
- if ( !locked ) {
- args = args || [];
- args = [ context, args.slice ? args.slice() : args ];
- queue.push( args );
- if ( !firing ) {
- fire();
- }
- }
- return this;
- },
-
- // Call all the callbacks with the given arguments
- fire: function() {
- self.fireWith( this, arguments );
- return this;
- },
-
- // To know if the callbacks have already been called at least once
- fired: function() {
- return !!fired;
- }
- };
-
- return self;
-};
-
-
-function Identity( v ) {
- return v;
-}
-function Thrower( ex ) {
- throw ex;
-}
-
-function adoptValue( value, resolve, reject, noValue ) {
- var method;
-
- try {
-
- // Check for promise aspect first to privilege synchronous behavior
- if ( value && isFunction( ( method = value.promise ) ) ) {
- method.call( value ).done( resolve ).fail( reject );
-
- // Other thenables
- } else if ( value && isFunction( ( method = value.then ) ) ) {
- method.call( value, resolve, reject );
-
- // Other non-thenables
- } else {
-
- // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
- // * false: [ value ].slice( 0 ) => resolve( value )
- // * true: [ value ].slice( 1 ) => resolve()
- resolve.apply( undefined, [ value ].slice( noValue ) );
- }
-
- // For Promises/A+, convert exceptions into rejections
- // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
- // Deferred#then to conditionally suppress rejection.
- } catch ( value ) {
+ // Return early from calls with invalid selector or context
+ if ( typeof selector !== "string" || !selector ||
+ nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
- // Support: Android 4.0 only
- // Strict mode functions invoked without .call/.apply get global-object context
- reject.apply( undefined, [ value ] );
+ return results;
}
-}
-
-jQuery.extend( {
-
- Deferred: function( func ) {
- var tuples = [
-
- // action, add listener, callbacks,
- // ... .then handlers, argument index, [final state]
- [ "notify", "progress", jQuery.Callbacks( "memory" ),
- jQuery.Callbacks( "memory" ), 2 ],
- [ "resolve", "done", jQuery.Callbacks( "once memory" ),
- jQuery.Callbacks( "once memory" ), 0, "resolved" ],
- [ "reject", "fail", jQuery.Callbacks( "once memory" ),
- jQuery.Callbacks( "once memory" ), 1, "rejected" ]
- ],
- state = "pending",
- promise = {
- state: function() {
- return state;
- },
- always: function() {
- deferred.done( arguments ).fail( arguments );
- return this;
- },
- "catch": function( fn ) {
- return promise.then( null, fn );
- },
-
- // Keep pipe for back-compat
- pipe: function( /* fnDone, fnFail, fnProgress */ ) {
- var fns = arguments;
-
- return jQuery.Deferred( function( newDefer ) {
- jQuery.each( tuples, function( _i, tuple ) {
-
- // Map tuples (progress, done, fail) to arguments (done, fail, progress)
- var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
-
- // deferred.progress(function() { bind to newDefer or newDefer.notify })
- // deferred.done(function() { bind to newDefer or newDefer.resolve })
- // deferred.fail(function() { bind to newDefer or newDefer.reject })
- deferred[ tuple[ 1 ] ]( function() {
- var returned = fn && fn.apply( this, arguments );
- if ( returned && isFunction( returned.promise ) ) {
- returned.promise()
- .progress( newDefer.notify )
- .done( newDefer.resolve )
- .fail( newDefer.reject );
- } else {
- newDefer[ tuple[ 0 ] + "With" ](
- this,
- fn ? [ returned ] : arguments
- );
- }
- } );
- } );
- fns = null;
- } ).promise();
- },
- then: function( onFulfilled, onRejected, onProgress ) {
- var maxDepth = 0;
- function resolve( depth, deferred, handler, special ) {
- return function() {
- var that = this,
- args = arguments,
- mightThrow = function() {
- var returned, then;
-
- // Support: Promises/A+ section 2.3.3.3.3
- // https://promisesaplus.com/#point-59
- // Ignore double-resolution attempts
- if ( depth < maxDepth ) {
- return;
- }
- returned = handler.apply( that, args );
+ // Try to shortcut find operations (as opposed to filters) in HTML documents
+ if ( !seed ) {
+ setDocument( context );
+ context = context || document;
- // Support: Promises/A+ section 2.3.1
- // https://promisesaplus.com/#point-48
- if ( returned === deferred.promise() ) {
- throw new TypeError( "Thenable self-resolution" );
- }
+ if ( documentIsHTML ) {
- // Support: Promises/A+ sections 2.3.3.1, 3.5
- // https://promisesaplus.com/#point-54
- // https://promisesaplus.com/#point-75
- // Retrieve `then` only once
- then = returned &&
-
- // Support: Promises/A+ section 2.3.4
- // https://promisesaplus.com/#point-64
- // Only check objects and functions for thenability
- ( typeof returned === "object" ||
- typeof returned === "function" ) &&
- returned.then;
-
- // Handle a returned thenable
- if ( isFunction( then ) ) {
-
- // Special processors (notify) just wait for resolution
- if ( special ) {
- then.call(
- returned,
- resolve( maxDepth, deferred, Identity, special ),
- resolve( maxDepth, deferred, Thrower, special )
- );
-
- // Normal processors (resolve) also hook into progress
- } else {
-
- // ...and disregard older resolution values
- maxDepth++;
-
- then.call(
- returned,
- resolve( maxDepth, deferred, Identity, special ),
- resolve( maxDepth, deferred, Thrower, special ),
- resolve( maxDepth, deferred, Identity,
- deferred.notifyWith )
- );
- }
+ // If the selector is sufficiently simple, try using a "get*By*" DOM method
+ // (excepting DocumentFragment context, where the methods don't exist)
+ if ( nodeType !== 11 && ( match = rquickExpr$1.exec( selector ) ) ) {
- // Handle all other returned values
- } else {
+ // ID selector
+ if ( ( m = match[ 1 ] ) ) {
- // Only substitute handlers pass on context
- // and multiple values (non-spec behavior)
- if ( handler !== Identity ) {
- that = undefined;
- args = [ returned ];
- }
+ // Document context
+ if ( nodeType === 9 ) {
+ if ( ( elem = context.getElementById( m ) ) ) {
+ push.call( results, elem );
+ }
+ return results;
- // Process the value(s)
- // Default process is resolve
- ( special || deferred.resolveWith )( that, args );
- }
- },
-
- // Only normal processors (resolve) catch and reject exceptions
- process = special ?
- mightThrow :
- function() {
- try {
- mightThrow();
- } catch ( e ) {
-
- if ( jQuery.Deferred.exceptionHook ) {
- jQuery.Deferred.exceptionHook( e,
- process.error );
- }
-
- // Support: Promises/A+ section 2.3.3.3.4.1
- // https://promisesaplus.com/#point-61
- // Ignore post-resolution exceptions
- if ( depth + 1 >= maxDepth ) {
-
- // Only substitute handlers pass on context
- // and multiple values (non-spec behavior)
- if ( handler !== Thrower ) {
- that = undefined;
- args = [ e ];
- }
-
- deferred.rejectWith( that, args );
- }
- }
- };
-
- // Support: Promises/A+ section 2.3.3.3.1
- // https://promisesaplus.com/#point-57
- // Re-resolve promises immediately to dodge false rejection from
- // subsequent errors
- if ( depth ) {
- process();
- } else {
+ // Element context
+ } else {
+ if ( newContext && ( elem = newContext.getElementById( m ) ) &&
+ jQuery.contains( context, elem ) ) {
- // Call an optional hook to record the error, in case of exception
- // since it's otherwise lost when execution goes async
- if ( jQuery.Deferred.getErrorHook ) {
- process.error = jQuery.Deferred.getErrorHook();
-
- // The deprecated alias of the above. While the name suggests
- // returning the stack, not an error instance, jQuery just passes
- // it directly to `console.warn` so both will work; an instance
- // just better cooperates with source maps.
- } else if ( jQuery.Deferred.getStackHook ) {
- process.error = jQuery.Deferred.getStackHook();
- }
- window.setTimeout( process );
- }
- };
+ push.call( results, elem );
+ return results;
+ }
}
- return jQuery.Deferred( function( newDefer ) {
-
- // progress_handlers.add( ... )
- tuples[ 0 ][ 3 ].add(
- resolve(
- 0,
- newDefer,
- isFunction( onProgress ) ?
- onProgress :
- Identity,
- newDefer.notifyWith
- )
- );
-
- // fulfilled_handlers.add( ... )
- tuples[ 1 ][ 3 ].add(
- resolve(
- 0,
- newDefer,
- isFunction( onFulfilled ) ?
- onFulfilled :
- Identity
- )
- );
-
- // rejected_handlers.add( ... )
- tuples[ 2 ][ 3 ].add(
- resolve(
- 0,
- newDefer,
- isFunction( onRejected ) ?
- onRejected :
- Thrower
- )
- );
- } ).promise();
- },
+ // Type selector
+ } else if ( match[ 2 ] ) {
+ push.apply( results, context.getElementsByTagName( selector ) );
+ return results;
- // Get a promise for this deferred
- // If obj is provided, the promise aspect is added to the object
- promise: function( obj ) {
- return obj != null ? jQuery.extend( obj, promise ) : promise;
+ // Class selector
+ } else if ( ( m = match[ 3 ] ) && context.getElementsByClassName ) {
+ push.apply( results, context.getElementsByClassName( m ) );
+ return results;
}
- },
- deferred = {};
+ }
- // Add list-specific methods
- jQuery.each( tuples, function( i, tuple ) {
- var list = tuple[ 2 ],
- stateString = tuple[ 5 ];
+ // Take advantage of querySelectorAll
+ if ( !nonnativeSelectorCache[ selector + " " ] &&
+ ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) ) {
- // promise.progress = list.add
- // promise.done = list.add
- // promise.fail = list.add
- promise[ tuple[ 1 ] ] = list.add;
+ newSelector = selector;
+ newContext = context;
- // Handle state
- if ( stateString ) {
- list.add(
- function() {
+ // qSA considers elements outside a scoping root when evaluating child or
+ // descendant combinators, which is not what we want.
+ // In such cases, we work around the behavior by prefixing every selector in the
+ // list with an ID selector referencing the scope context.
+ // The technique has to be used as well when a leading combinator is used
+ // as such selectors are not recognized by querySelectorAll.
+ // Thanks to Andrew Dupont for this technique.
+ if ( nodeType === 1 &&
+ ( rdescend.test( selector ) || rleadingCombinator.test( selector ) ) ) {
- // state = "resolved" (i.e., fulfilled)
- // state = "rejected"
- state = stateString;
- },
+ // Expand context for sibling selectors
+ newContext = rsibling.test( selector ) &&
+ testContext( context.parentNode ) ||
+ context;
- // rejected_callbacks.disable
- // fulfilled_callbacks.disable
- tuples[ 3 - i ][ 2 ].disable,
+ // Outside of IE, if we're not changing the context we can
+ // use :scope instead of an ID.
+ // Support: IE 11+
+ // IE sometimes throws a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( newContext != context || isIE ) {
- // rejected_handlers.disable
- // fulfilled_handlers.disable
- tuples[ 3 - i ][ 3 ].disable,
+ // Capture the context ID, setting it first if necessary
+ if ( ( nid = context.getAttribute( "id" ) ) ) {
+ nid = jQuery.escapeSelector( nid );
+ } else {
+ context.setAttribute( "id", ( nid = jQuery.expando ) );
+ }
+ }
- // progress_callbacks.lock
- tuples[ 0 ][ 2 ].lock,
+ // Prefix every selector in the list
+ groups = tokenize( selector );
+ i = groups.length;
+ while ( i-- ) {
+ groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
+ toSelector( groups[ i ] );
+ }
+ newSelector = groups.join( "," );
+ }
- // progress_handlers.lock
- tuples[ 0 ][ 3 ].lock
- );
+ try {
+ push.apply( results,
+ newContext.querySelectorAll( newSelector )
+ );
+ return results;
+ } catch ( qsaError ) {
+ nonnativeSelectorCache( selector, true );
+ } finally {
+ if ( nid === jQuery.expando ) {
+ context.removeAttribute( "id" );
+ }
+ }
}
+ }
+ }
- // progress_handlers.fire
- // fulfilled_handlers.fire
- // rejected_handlers.fire
- list.add( tuple[ 3 ].fire );
+ // All others
+ return select( selector.replace( rtrimCSS, "$1" ), context, results, seed );
+}
- // deferred.notify = function() { deferred.notifyWith(...) }
- // deferred.resolve = function() { deferred.resolveWith(...) }
- // deferred.reject = function() { deferred.rejectWith(...) }
- deferred[ tuple[ 0 ] ] = function() {
- deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
- return this;
- };
+/**
+ * Mark a function for special use by jQuery selector module
+ * @param {Function} fn The function to mark
+ */
+function markFunction( fn ) {
+ fn[ jQuery.expando ] = true;
+ return fn;
+}
- // deferred.notifyWith = list.fireWith
- // deferred.resolveWith = list.fireWith
- // deferred.rejectWith = list.fireWith
- deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
- } );
+/**
+ * Returns a function to use in pseudos for input types
+ * @param {String} type
+ */
+function createInputPseudo( type ) {
+ return function( elem ) {
+ return nodeName( elem, "input" ) && elem.type === type;
+ };
+}
+
+/**
+ * Returns a function to use in pseudos for buttons
+ * @param {String} type
+ */
+function createButtonPseudo( type ) {
+ return function( elem ) {
+ return ( nodeName( elem, "input" ) || nodeName( elem, "button" ) ) &&
+ elem.type === type;
+ };
+}
- // Make the deferred a promise
- promise.promise( deferred );
+/**
+ * Returns a function to use in pseudos for :enabled/:disabled
+ * @param {Boolean} disabled true for :disabled; false for :enabled
+ */
+function createDisabledPseudo( disabled ) {
- // Call given func if any
- if ( func ) {
- func.call( deferred, deferred );
- }
+ // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
+ return function( elem ) {
- // All done!
- return deferred;
- },
+ // Only certain elements can match :enabled or :disabled
+ // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
+ // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
+ if ( "form" in elem ) {
- // Deferred helper
- when: function( singleValue ) {
- var
+ // Check for inherited disabledness on relevant non-disabled elements:
+ // * listed form-associated elements in a disabled fieldset
+ // https://html.spec.whatwg.org/multipage/forms.html#category-listed
+ // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
+ // * option elements in a disabled optgroup
+ // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
+ // All such elements have a "form" property.
+ if ( elem.parentNode && elem.disabled === false ) {
- // count of uncompleted subordinates
- remaining = arguments.length,
+ // Option elements defer to a parent optgroup if present
+ if ( "label" in elem ) {
+ if ( "label" in elem.parentNode ) {
+ return elem.parentNode.disabled === disabled;
+ } else {
+ return elem.disabled === disabled;
+ }
+ }
- // count of unprocessed arguments
- i = remaining,
+ // Support: IE 6 - 11+
+ // Use the isDisabled shortcut property to check for disabled fieldset ancestors
+ return elem.isDisabled === disabled ||
- // subordinate fulfillment data
- resolveContexts = Array( i ),
- resolveValues = slice.call( arguments ),
+ // Where there is no isDisabled, check manually
+ elem.isDisabled !== !disabled &&
+ inDisabledFieldset( elem ) === disabled;
+ }
- // the primary Deferred
- primary = jQuery.Deferred(),
+ return elem.disabled === disabled;
- // subordinate callback factory
- updateFunc = function( i ) {
- return function( value ) {
- resolveContexts[ i ] = this;
- resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
- if ( !( --remaining ) ) {
- primary.resolveWith( resolveContexts, resolveValues );
- }
- };
- };
+ // Try to winnow out elements that can't be disabled before trusting the disabled property.
+ // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
+ // even exist on them, let alone have a boolean value.
+ } else if ( "label" in elem ) {
+ return elem.disabled === disabled;
+ }
- // Single- and empty arguments are adopted like Promise.resolve
- if ( remaining <= 1 ) {
- adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject,
- !remaining );
+ // Remaining elements are neither :enabled nor :disabled
+ return false;
+ };
+}
- // Use .then() to unwrap secondary thenables (cf. gh-3000)
- if ( primary.state() === "pending" ||
- isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
+/**
+ * Returns a function to use in pseudos for positionals
+ * @param {Function} fn
+ */
+function createPositionalPseudo( fn ) {
+ return markFunction( function( argument ) {
+ argument = +argument;
+ return markFunction( function( seed, matches ) {
+ var j,
+ matchIndexes = fn( [], seed.length, argument ),
+ i = matchIndexes.length;
- return primary.then();
+ // Match elements found at the specified indexes
+ while ( i-- ) {
+ if ( seed[ ( j = matchIndexes[ i ] ) ] ) {
+ seed[ j ] = !( matches[ j ] = seed[ j ] );
+ }
}
- }
+ } );
+ } );
+}
- // Multiple arguments are aggregated like Promise.all array elements
- while ( i-- ) {
- adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject );
- }
+/**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [node] An element or document object to use to set the document
+ */
+function setDocument( node ) {
+ var subWindow,
+ doc = node ? node.ownerDocument || node : document$1;
- return primary.promise();
+ // Return early if doc is invalid or already selected
+ // Support: IE 11+
+ // IE sometimes throws a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( doc == document || doc.nodeType !== 9 ) {
+ return;
}
-} );
+ // Update global variables
+ document = doc;
+ documentElement = document.documentElement;
+ documentIsHTML = !jQuery.isXMLDoc( document );
-// These usually indicate a programmer mistake during development,
-// warn about them ASAP rather than swallowing them by default.
-var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
-
-// If `jQuery.Deferred.getErrorHook` is defined, `asyncError` is an error
-// captured before the async barrier to get the original error cause
-// which may otherwise be hidden.
-jQuery.Deferred.exceptionHook = function( error, asyncError ) {
-
- // Support: IE 8 - 9 only
- // Console exists when dev tools are open, which can happen at any time
- if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
- window.console.warn( "jQuery.Deferred exception: " + error.message,
- error.stack, asyncError );
+ // Support: IE 9 - 11+
+ // Accessing iframe documents after unload throws "permission denied" errors (see trac-13936)
+ // Support: IE 11+
+ // IE sometimes throws a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( isIE && document$1 != document &&
+ ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {
+ subWindow.addEventListener( "unload", unloadHandler );
}
+}
+
+find.matches = function( expr, elements ) {
+ return find( expr, null, null, elements );
};
+find.matchesSelector = function( elem, expr ) {
+ setDocument( elem );
+ if ( documentIsHTML &&
+ !nonnativeSelectorCache[ expr + " " ] &&
+ ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
+ try {
+ return matches.call( elem, expr );
+ } catch ( e ) {
+ nonnativeSelectorCache( expr, true );
+ }
+ }
-jQuery.readyException = function( error ) {
- window.setTimeout( function() {
- throw error;
- } );
+ return find( expr, document, null, [ elem ] ).length > 0;
};
+jQuery.expr = {
+ // Can be adjusted by the user
+ cacheLength: 50,
+ createPseudo: markFunction,
-// The deferred used on DOM ready
-var readyList = jQuery.Deferred();
-
-jQuery.fn.ready = function( fn ) {
+ match: matchExpr,
- readyList
- .then( fn )
+ find: {
+ ID: function( id, context ) {
+ if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+ var elem = context.getElementById( id );
+ return elem ? [ elem ] : [];
+ }
+ },
- // Wrap jQuery.readyException in a function so that the lookup
- // happens at the time of error handling instead of callback
- // registration.
- .catch( function( error ) {
- jQuery.readyException( error );
- } );
+ TAG: function( tag, context ) {
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
+ return context.getElementsByTagName( tag );
- return this;
-};
+ // DocumentFragment nodes don't have gEBTN
+ } else {
+ return context.querySelectorAll( tag );
+ }
+ },
-jQuery.extend( {
+ CLASS: function( className, context ) {
+ if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
+ return context.getElementsByClassName( className );
+ }
+ }
+ },
- // Is the DOM ready to be used? Set to true once it occurs.
- isReady: false,
+ relative: {
+ ">": { dir: "parentNode", first: true },
+ " ": { dir: "parentNode" },
+ "+": { dir: "previousSibling", first: true },
+ "~": { dir: "previousSibling" }
+ },
- // A counter to track how many items to wait for before
- // the ready event fires. See trac-6781
- readyWait: 1,
+ preFilter: preFilter,
- // Handle when the DOM is ready
- ready: function( wait ) {
+ filter: {
+ ID: function( id ) {
+ var attrId = unescapeSelector( id );
+ return function( elem ) {
+ return elem.getAttribute( "id" ) === attrId;
+ };
+ },
- // Abort if there are pending holds or we're already ready
- if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
- return;
- }
+ TAG: function( nodeNameSelector ) {
+ var expectedNodeName = unescapeSelector( nodeNameSelector ).toLowerCase();
+ return nodeNameSelector === "*" ?
- // Remember that the DOM is ready
- jQuery.isReady = true;
+ function() {
+ return true;
+ } :
- // If a normal DOM Ready event fired, decrement, and wait if need be
- if ( wait !== true && --jQuery.readyWait > 0 ) {
- return;
- }
+ function( elem ) {
+ return nodeName( elem, expectedNodeName );
+ };
+ },
- // If there are functions bound, to execute
- readyList.resolveWith( document, [ jQuery ] );
- }
-} );
+ CLASS: function( className ) {
+ var pattern = classCache[ className + " " ];
-jQuery.ready.then = readyList.then;
+ return pattern ||
+ ( pattern = new RegExp( "(^|" + whitespace + ")" + className +
+ "(" + whitespace + "|$)" ) ) &&
+ classCache( className, function( elem ) {
+ return pattern.test(
+ typeof elem.className === "string" && elem.className ||
+ typeof elem.getAttribute !== "undefined" &&
+ elem.getAttribute( "class" ) ||
+ ""
+ );
+ } );
+ },
-// The ready event handler and self cleanup method
-function completed() {
- document.removeEventListener( "DOMContentLoaded", completed );
- window.removeEventListener( "load", completed );
- jQuery.ready();
-}
+ ATTR: function( name, operator, check ) {
+ return function( elem ) {
+ var result = jQuery.attr( elem, name );
-// Catch cases where $(document).ready() is called
-// after the browser event has already occurred.
-// Support: IE <=9 - 10 only
-// Older IE sometimes signals "interactive" too soon
-if ( document.readyState === "complete" ||
- ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
+ if ( result == null ) {
+ return operator === "!=";
+ }
+ if ( !operator ) {
+ return true;
+ }
- // Handle it asynchronously to allow scripts the opportunity to delay ready
- window.setTimeout( jQuery.ready );
+ result += "";
-} else {
+ if ( operator === "=" ) {
+ return result === check;
+ }
+ if ( operator === "!=" ) {
+ return result !== check;
+ }
+ if ( operator === "^=" ) {
+ return check && result.indexOf( check ) === 0;
+ }
+ if ( operator === "*=" ) {
+ return check && result.indexOf( check ) > -1;
+ }
+ if ( operator === "$=" ) {
+ return check && result.slice( -check.length ) === check;
+ }
+ if ( operator === "~=" ) {
+ return ( " " + result.replace( rwhitespace, " " ) + " " )
+ .indexOf( check ) > -1;
+ }
+ if ( operator === "|=" ) {
+ return result === check || result.slice( 0, check.length + 1 ) === check + "-";
+ }
- // Use the handy event callback
- document.addEventListener( "DOMContentLoaded", completed );
+ return false;
+ };
+ },
- // A fallback to window.onload, that will always work
- window.addEventListener( "load", completed );
-}
+ CHILD: function( type, what, _argument, first, last ) {
+ var simple = type.slice( 0, 3 ) !== "nth",
+ forward = type.slice( -4 ) !== "last",
+ ofType = what === "of-type";
+ return first === 1 && last === 0 ?
+ // Shortcut for :nth-*(n)
+ function( elem ) {
+ return !!elem.parentNode;
+ } :
+ function( elem, _context, xml ) {
+ var cache, outerCache, node, nodeIndex, start,
+ dir = simple !== forward ? "nextSibling" : "previousSibling",
+ parent = elem.parentNode,
+ name = ofType && elem.nodeName.toLowerCase(),
+ useCache = !xml && !ofType,
+ diff = false;
-// Multifunctional method to get and set values of a collection
-// The value/s can optionally be executed if it's a function
-var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
- var i = 0,
- len = elems.length,
- bulk = key == null;
+ if ( parent ) {
- // Sets many values
- if ( toType( key ) === "object" ) {
- chainable = true;
- for ( i in key ) {
- access( elems, fn, i, key[ i ], true, emptyGet, raw );
- }
+ // :(first|last|only)-(child|of-type)
+ if ( simple ) {
+ while ( dir ) {
+ node = elem;
+ while ( ( node = node[ dir ] ) ) {
+ if ( ofType ?
+ nodeName( node, name ) :
+ node.nodeType === 1 ) {
- // Sets one value
- } else if ( value !== undefined ) {
- chainable = true;
+ return false;
+ }
+ }
- if ( !isFunction( value ) ) {
- raw = true;
- }
+ // Reverse direction for :only-* (if we haven't yet done so)
+ start = dir = type === "only" && !start && "nextSibling";
+ }
+ return true;
+ }
- if ( bulk ) {
+ start = [ forward ? parent.firstChild : parent.lastChild ];
- // Bulk operations run against the entire set
- if ( raw ) {
- fn.call( elems, value );
- fn = null;
+ // non-xml :nth-child(...) stores cache data on `parent`
+ if ( forward && useCache ) {
- // ...except when executing function values
- } else {
- bulk = fn;
- fn = function( elem, _key, value ) {
- return bulk.call( jQuery( elem ), value );
- };
- }
- }
+ // Seek `elem` from a previously-cached index
+ outerCache = parent[ jQuery.expando ] ||
+ ( parent[ jQuery.expando ] = {} );
+ cache = outerCache[ type ] || [];
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+ diff = nodeIndex && cache[ 2 ];
+ node = nodeIndex && parent.childNodes[ nodeIndex ];
- if ( fn ) {
- for ( ; i < len; i++ ) {
- fn(
- elems[ i ], key, raw ?
- value :
- value.call( elems[ i ], i, fn( elems[ i ], key ) )
- );
- }
- }
- }
+ while ( ( node = ++nodeIndex && node && node[ dir ] ||
- if ( chainable ) {
- return elems;
- }
+ // Fallback to seeking `elem` from the start
+ ( diff = nodeIndex = 0 ) || start.pop() ) ) {
- // Gets
- if ( bulk ) {
- return fn.call( elems );
- }
+ // When found, cache indexes on `parent` and break
+ if ( node.nodeType === 1 && ++diff && node === elem ) {
+ outerCache[ type ] = [ dirruns, nodeIndex, diff ];
+ break;
+ }
+ }
- return len ? fn( elems[ 0 ], key ) : emptyGet;
-};
+ } else {
+ // Use previously-cached element index if available
+ if ( useCache ) {
+ outerCache = elem[ jQuery.expando ] ||
+ ( elem[ jQuery.expando ] = {} );
+ cache = outerCache[ type ] || [];
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+ diff = nodeIndex;
+ }
-// Matches dashed string for camelizing
-var rmsPrefix = /^-ms-/,
- rdashAlpha = /-([a-z])/g;
+ // xml :nth-child(...)
+ // or :nth-last-child(...) or :nth(-last)?-of-type(...)
+ if ( diff === false ) {
-// Used by camelCase as callback to replace()
-function fcamelCase( _all, letter ) {
- return letter.toUpperCase();
-}
+ // Use the same loop as above to seek `elem` from the start
+ while ( ( node = ++nodeIndex && node && node[ dir ] ||
+ ( diff = nodeIndex = 0 ) || start.pop() ) ) {
-// Convert dashed to camelCase; used by the css and data modules
-// Support: IE <=9 - 11, Edge 12 - 15
-// Microsoft forgot to hump their vendor prefix (trac-9572)
-function camelCase( string ) {
- return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
-}
-var acceptData = function( owner ) {
+ if ( ( ofType ?
+ nodeName( node, name ) :
+ node.nodeType === 1 ) &&
+ ++diff ) {
- // Accepts only:
- // - Node
- // - Node.ELEMENT_NODE
- // - Node.DOCUMENT_NODE
- // - Object
- // - Any
- return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
-};
+ // Cache the index of each encountered element
+ if ( useCache ) {
+ outerCache = node[ jQuery.expando ] ||
+ ( node[ jQuery.expando ] = {} );
+ outerCache[ type ] = [ dirruns, diff ];
+ }
+ if ( node === elem ) {
+ break;
+ }
+ }
+ }
+ }
+ }
+ // Incorporate the offset, then check against cycle size
+ diff -= last;
+ return diff === first || ( diff % first === 0 && diff / first >= 0 );
+ }
+ };
+ },
+ PSEUDO: function( pseudo, argument ) {
-function Data() {
- this.expando = jQuery.expando + Data.uid++;
-}
+ // pseudo-class names are case-insensitive
+ // https://www.w3.org/TR/selectors/#pseudo-classes
+ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+ // Remember that setFilters inherits from pseudos
+ var fn = jQuery.expr.pseudos[ pseudo ] ||
+ jQuery.expr.setFilters[ pseudo.toLowerCase() ] ||
+ selectorError( "unsupported pseudo: " + pseudo );
-Data.uid = 1;
+ // The user may use createPseudo to indicate that
+ // arguments are needed to create the filter function
+ // just as jQuery does
+ if ( fn[ jQuery.expando ] ) {
+ return fn( argument );
+ }
-Data.prototype = {
+ return fn;
+ }
+ },
- cache: function( owner ) {
+ pseudos: {
- // Check if the owner object already has a cache
- var value = owner[ this.expando ];
+ // Potentially complex pseudos
+ not: markFunction( function( selector ) {
- // If not, create one
- if ( !value ) {
- value = {};
+ // Trim the selector passed to compile
+ // to avoid treating leading and trailing
+ // spaces as combinators
+ var input = [],
+ results = [],
+ matcher = compile( selector.replace( rtrimCSS, "$1" ) );
- // We can accept data for non-element nodes in modern browsers,
- // but we should not, see trac-8335.
- // Always return an empty object.
- if ( acceptData( owner ) ) {
+ return matcher[ jQuery.expando ] ?
+ markFunction( function( seed, matches, _context, xml ) {
+ var elem,
+ unmatched = matcher( seed, null, xml, [] ),
+ i = seed.length;
- // If it is a node unlikely to be stringify-ed or looped over
- // use plain assignment
- if ( owner.nodeType ) {
- owner[ this.expando ] = value;
+ // Match elements unmatched by `matcher`
+ while ( i-- ) {
+ if ( ( elem = unmatched[ i ] ) ) {
+ seed[ i ] = !( matches[ i ] = elem );
+ }
+ }
+ } ) :
+ function( elem, _context, xml ) {
+ input[ 0 ] = elem;
+ matcher( input, null, xml, results );
- // Otherwise secure it in a non-enumerable property
- // configurable must be true to allow the property to be
- // deleted when data is removed
- } else {
- Object.defineProperty( owner, this.expando, {
- value: value,
- configurable: true
- } );
- }
- }
- }
+ // Don't keep the element
+ // (see https://github.com/jquery/sizzle/issues/299)
+ input[ 0 ] = null;
+ return !results.pop();
+ };
+ } ),
- return value;
- },
- set: function( owner, data, value ) {
- var prop,
- cache = this.cache( owner );
+ has: markFunction( function( selector ) {
+ return function( elem ) {
+ return find( selector, elem ).length > 0;
+ };
+ } ),
- // Handle: [ owner, key, value ] args
- // Always use camelCase key (gh-2257)
- if ( typeof data === "string" ) {
- cache[ camelCase( data ) ] = value;
+ contains: markFunction( function( text ) {
+ text = unescapeSelector( text );
+ return function( elem ) {
+ return ( elem.textContent || jQuery.text( elem ) ).indexOf( text ) > -1;
+ };
+ } ),
- // Handle: [ owner, { properties } ] args
- } else {
+ // "Whether an element is represented by a :lang() selector
+ // is based solely on the element's language value
+ // being equal to the identifier C,
+ // or beginning with the identifier C immediately followed by "-".
+ // The matching of C against the element's language value is performed case-insensitively.
+ // The identifier C does not have to be a valid language name."
+ // https://www.w3.org/TR/selectors/#lang-pseudo
+ lang: markFunction( function( lang ) {
- // Copy the properties one-by-one to the cache object
- for ( prop in data ) {
- cache[ camelCase( prop ) ] = data[ prop ];
+ // lang value must be a valid identifier
+ if ( !ridentifier.test( lang || "" ) ) {
+ selectorError( "unsupported lang: " + lang );
}
- }
- return cache;
- },
- get: function( owner, key ) {
- return key === undefined ?
- this.cache( owner ) :
-
- // Always use camelCase key (gh-2257)
- owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
- },
- access: function( owner, key, value ) {
+ lang = unescapeSelector( lang ).toLowerCase();
+ return function( elem ) {
+ var elemLang;
+ do {
+ if ( ( elemLang = documentIsHTML ?
+ elem.lang :
+ elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {
- // In cases where either:
- //
- // 1. No key was specified
- // 2. A string key was specified, but no value provided
- //
- // Take the "read" path and allow the get method to determine
- // which value to return, respectively either:
- //
- // 1. The entire cache object
- // 2. The data stored at the key
- //
- if ( key === undefined ||
- ( ( key && typeof key === "string" ) && value === undefined ) ) {
+ elemLang = elemLang.toLowerCase();
+ return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
+ }
+ } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );
+ return false;
+ };
+ } ),
- return this.get( owner, key );
- }
+ // Miscellaneous
+ target: function( elem ) {
+ var hash = window.location && window.location.hash;
+ return hash && hash.slice( 1 ) === elem.id;
+ },
- // When the key is not a string, or both a key and value
- // are specified, set or extend (existing objects) with either:
- //
- // 1. An object of properties
- // 2. A key and value
- //
- this.set( owner, key, value );
+ root: function( elem ) {
+ return elem === documentElement;
+ },
- // Since the "set" path can have two possible entry points
- // return the expected data based on which path was taken[*]
- return value !== undefined ? value : key;
- },
- remove: function( owner, key ) {
- var i,
- cache = owner[ this.expando ];
+ focus: function( elem ) {
+ return elem === document.activeElement &&
+ document.hasFocus() &&
+ !!( elem.type || elem.href || ~elem.tabIndex );
+ },
- if ( cache === undefined ) {
- return;
- }
+ // Boolean properties
+ enabled: createDisabledPseudo( false ),
+ disabled: createDisabledPseudo( true ),
- if ( key !== undefined ) {
+ checked: function( elem ) {
- // Support array or space separated string of keys
- if ( Array.isArray( key ) ) {
+ // In CSS3, :checked should return both checked and selected elements
+ // https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ return ( nodeName( elem, "input" ) && !!elem.checked ) ||
+ ( nodeName( elem, "option" ) && !!elem.selected );
+ },
- // If key is an array of keys...
- // We always set camelCase keys, so remove that.
- key = key.map( camelCase );
- } else {
- key = camelCase( key );
+ selected: function( elem ) {
- // If a key with the spaces exists, use it.
- // Otherwise, create an array by matching non-whitespace
- key = key in cache ?
- [ key ] :
- ( key.match( rnothtmlwhite ) || [] );
+ // Support: IE <=11+
+ // Accessing the selectedIndex property
+ // forces the browser to treat the default option as
+ // selected when in an optgroup.
+ if ( isIE && elem.parentNode ) {
+ // eslint-disable-next-line no-unused-expressions
+ elem.parentNode.selectedIndex;
}
- i = key.length;
-
- while ( i-- ) {
- delete cache[ key[ i ] ];
- }
- }
+ return elem.selected === true;
+ },
- // Remove the expando if there's no more data
- if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
+ // Contents
+ empty: function( elem ) {
- // Support: Chrome <=35 - 45
- // Webkit & Blink performance suffers when deleting properties
- // from DOM nodes, so set to undefined instead
- // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
- if ( owner.nodeType ) {
- owner[ this.expando ] = undefined;
- } else {
- delete owner[ this.expando ];
+ // https://www.w3.org/TR/selectors/#empty-pseudo
+ // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
+ // but not by others (comment: 8; processing instruction: 7; etc.)
+ // nodeType < 6 works because attributes (2) do not appear as children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ if ( elem.nodeType < 6 ) {
+ return false;
+ }
}
- }
- },
- hasData: function( owner ) {
- var cache = owner[ this.expando ];
- return cache !== undefined && !jQuery.isEmptyObject( cache );
- }
-};
-var dataPriv = new Data();
-
-var dataUser = new Data();
+ return true;
+ },
+ parent: function( elem ) {
+ return !jQuery.expr.pseudos.empty( elem );
+ },
+ // Element/input types
+ header: function( elem ) {
+ return rheader.test( elem.nodeName );
+ },
-// Implementation Summary
-//
-// 1. Enforce API surface and semantic compatibility with 1.9.x branch
-// 2. Improve the module's maintainability by reducing the storage
-// paths to a single mechanism.
-// 3. Use the same single mechanism to support "private" and "user" data.
-// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
-// 5. Avoid exposing implementation details on user objects (eg. expando properties)
-// 6. Provide a clear path for implementation upgrade to WeakMap in 2014
+ input: function( elem ) {
+ return rinputs.test( elem.nodeName );
+ },
-var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
- rmultiDash = /[A-Z]/g;
+ button: function( elem ) {
+ return nodeName( elem, "input" ) && elem.type === "button" ||
+ nodeName( elem, "button" );
+ },
-function getData( data ) {
- if ( data === "true" ) {
- return true;
- }
+ text: function( elem ) {
+ return nodeName( elem, "input" ) && elem.type === "text";
+ },
- if ( data === "false" ) {
- return false;
- }
+ // Position-in-collection
+ first: createPositionalPseudo( function() {
+ return [ 0 ];
+ } ),
- if ( data === "null" ) {
- return null;
- }
+ last: createPositionalPseudo( function( _matchIndexes, length ) {
+ return [ length - 1 ];
+ } ),
- // Only convert to a number if it doesn't change the string
- if ( data === +data + "" ) {
- return +data;
- }
+ eq: createPositionalPseudo( function( _matchIndexes, length, argument ) {
+ return [ argument < 0 ? argument + length : argument ];
+ } ),
- if ( rbrace.test( data ) ) {
- return JSON.parse( data );
- }
+ even: createPositionalPseudo( function( matchIndexes, length ) {
+ var i = 0;
+ for ( ; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ } ),
- return data;
-}
+ odd: createPositionalPseudo( function( matchIndexes, length ) {
+ var i = 1;
+ for ( ; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ } ),
-function dataAttr( elem, key, data ) {
- var name;
+ lt: createPositionalPseudo( function( matchIndexes, length, argument ) {
+ var i;
- // If nothing was found internally, try to fetch any
- // data from the HTML5 data-* attribute
- if ( data === undefined && elem.nodeType === 1 ) {
- name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
- data = elem.getAttribute( name );
+ if ( argument < 0 ) {
+ i = argument + length;
+ } else if ( argument > length ) {
+ i = length;
+ } else {
+ i = argument;
+ }
- if ( typeof data === "string" ) {
- try {
- data = getData( data );
- } catch ( e ) {}
+ for ( ; --i >= 0; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ } ),
- // Make sure we set the data so it isn't changed later
- dataUser.set( elem, key, data );
- } else {
- data = undefined;
- }
+ gt: createPositionalPseudo( function( matchIndexes, length, argument ) {
+ var i = argument < 0 ? argument + length : argument;
+ for ( ; ++i < length; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ } )
}
- return data;
+};
+
+jQuery.expr.pseudos.nth = jQuery.expr.pseudos.eq;
+
+// Add button/input type pseudos
+for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+ jQuery.expr.pseudos[ i ] = createInputPseudo( i );
+}
+for ( i in { submit: true, reset: true } ) {
+ jQuery.expr.pseudos[ i ] = createButtonPseudo( i );
}
-jQuery.extend( {
- hasData: function( elem ) {
- return dataUser.hasData( elem ) || dataPriv.hasData( elem );
- },
+// Easy API for creating new setFilters
+function setFilters() {}
+setFilters.prototype = jQuery.expr.pseudos;
+jQuery.expr.setFilters = new setFilters();
- data: function( elem, name, data ) {
- return dataUser.access( elem, name, data );
- },
+function addCombinator( matcher, combinator, base ) {
+ var dir = combinator.dir,
+ skip = combinator.next,
+ key = skip || dir,
+ checkNonElements = base && key === "parentNode",
+ doneName = done++;
- removeData: function( elem, name ) {
- dataUser.remove( elem, name );
- },
+ return combinator.first ?
- // TODO: Now that all calls to _data and _removeData have been replaced
- // with direct calls to dataPriv methods, these can be deprecated.
- _data: function( elem, name, data ) {
- return dataPriv.access( elem, name, data );
- },
+ // Check against closest ancestor/preceding element
+ function( elem, context, xml ) {
+ while ( ( elem = elem[ dir ] ) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ return matcher( elem, context, xml );
+ }
+ }
+ return false;
+ } :
- _removeData: function( elem, name ) {
- dataPriv.remove( elem, name );
- }
-} );
+ // Check against all ancestor/preceding elements
+ function( elem, context, xml ) {
+ var oldCache, outerCache,
+ newCache = [ dirruns, doneName ];
-jQuery.fn.extend( {
- data: function( key, value ) {
- var i, name, data,
- elem = this[ 0 ],
- attrs = elem && elem.attributes;
+ // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
+ if ( xml ) {
+ while ( ( elem = elem[ dir ] ) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ if ( matcher( elem, context, xml ) ) {
+ return true;
+ }
+ }
+ }
+ } else {
+ while ( ( elem = elem[ dir ] ) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ outerCache = elem[ jQuery.expando ] || ( elem[ jQuery.expando ] = {} );
- // Gets all values
- if ( key === undefined ) {
- if ( this.length ) {
- data = dataUser.get( elem );
+ if ( skip && nodeName( elem, skip ) ) {
+ elem = elem[ dir ] || elem;
+ } else if ( ( oldCache = outerCache[ key ] ) &&
+ oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
- if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
- i = attrs.length;
- while ( i-- ) {
+ // Assign to newCache so results back-propagate to previous elements
+ return ( newCache[ 2 ] = oldCache[ 2 ] );
+ } else {
- // Support: IE 11 only
- // The attrs elements can be null (trac-14894)
- if ( attrs[ i ] ) {
- name = attrs[ i ].name;
- if ( name.indexOf( "data-" ) === 0 ) {
- name = camelCase( name.slice( 5 ) );
- dataAttr( elem, name, data[ name ] );
+ // Reuse newcache so results back-propagate to previous elements
+ outerCache[ key ] = newCache;
+
+ // A match means we're done; a fail means we have to keep checking
+ if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {
+ return true;
}
}
}
- dataPriv.set( elem, "hasDataAttrs", true );
}
}
+ return false;
+ };
+}
- return data;
- }
-
- // Sets multiple values
- if ( typeof key === "object" ) {
- return this.each( function() {
- dataUser.set( this, key );
- } );
- }
+function elementMatcher( matchers ) {
+ return matchers.length > 1 ?
+ function( elem, context, xml ) {
+ var i = matchers.length;
+ while ( i-- ) {
+ if ( !matchers[ i ]( elem, context, xml ) ) {
+ return false;
+ }
+ }
+ return true;
+ } :
+ matchers[ 0 ];
+}
- return access( this, function( value ) {
- var data;
+function multipleContexts( selector, contexts, results ) {
+ var i = 0,
+ len = contexts.length;
+ for ( ; i < len; i++ ) {
+ find( selector, contexts[ i ], results );
+ }
+ return results;
+}
- // The calling jQuery object (element matches) is not empty
- // (and therefore has an element appears at this[ 0 ]) and the
- // `value` parameter was not undefined. An empty jQuery object
- // will result in `undefined` for elem = this[ 0 ] which will
- // throw an exception if an attempt to read a data cache is made.
- if ( elem && value === undefined ) {
+function condense( unmatched, map, filter, context, xml ) {
+ var elem,
+ newUnmatched = [],
+ i = 0,
+ len = unmatched.length,
+ mapped = map != null;
- // Attempt to get data from the cache
- // The key will always be camelCased in Data
- data = dataUser.get( elem, key );
- if ( data !== undefined ) {
- return data;
+ for ( ; i < len; i++ ) {
+ if ( ( elem = unmatched[ i ] ) ) {
+ if ( !filter || filter( elem, context, xml ) ) {
+ newUnmatched.push( elem );
+ if ( mapped ) {
+ map.push( i );
}
+ }
+ }
+ }
- // Attempt to "discover" the data in
- // HTML5 custom data-* attrs
- data = dataAttr( elem, key );
- if ( data !== undefined ) {
- return data;
- }
+ return newUnmatched;
+}
- // We tried really hard, but the data doesn't exist.
- return;
- }
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+ if ( postFilter && !postFilter[ jQuery.expando ] ) {
+ postFilter = setMatcher( postFilter );
+ }
+ if ( postFinder && !postFinder[ jQuery.expando ] ) {
+ postFinder = setMatcher( postFinder, postSelector );
+ }
+ return markFunction( function( seed, results, context, xml ) {
+ var temp, i, elem, matcherOut,
+ preMap = [],
+ postMap = [],
+ preexisting = results.length,
+
+ // Get initial elements from seed or context
+ elems = seed ||
+ multipleContexts( selector || "*",
+ context.nodeType ? [ context ] : context, [] ),
+
+ // Prefilter to get matcher input, preserving a map for seed-results synchronization
+ matcherIn = preFilter && ( seed || !selector ) ?
+ condense( elems, preMap, preFilter, context, xml ) :
+ elems;
- // Set the data...
- this.each( function() {
+ if ( matcher ) {
- // We always store the camelCased key
- dataUser.set( this, key, value );
- } );
- }, null, value, arguments.length > 1, null, true );
- },
+ // If we have a postFinder, or filtered seed, or non-seed postFilter
+ // or preexisting results,
+ matcherOut = postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
- removeData: function( key ) {
- return this.each( function() {
- dataUser.remove( this, key );
- } );
- }
-} );
+ // ...intermediate processing is necessary
+ [] :
+ // ...otherwise use results directly
+ results;
-jQuery.extend( {
- queue: function( elem, type, data ) {
- var queue;
+ // Find primary matches
+ matcher( matcherIn, matcherOut, context, xml );
+ } else {
+ matcherOut = matcherIn;
+ }
- if ( elem ) {
- type = ( type || "fx" ) + "queue";
- queue = dataPriv.get( elem, type );
+ // Apply postFilter
+ if ( postFilter ) {
+ temp = condense( matcherOut, postMap );
+ postFilter( temp, [], context, xml );
- // Speed up dequeue by getting out quickly if this is just a lookup
- if ( data ) {
- if ( !queue || Array.isArray( data ) ) {
- queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
- } else {
- queue.push( data );
+ // Un-match failing elements by moving them back to matcherIn
+ i = temp.length;
+ while ( i-- ) {
+ if ( ( elem = temp[ i ] ) ) {
+ matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );
}
}
- return queue || [];
}
- },
- dequeue: function( elem, type ) {
- type = type || "fx";
+ if ( seed ) {
+ if ( postFinder || preFilter ) {
+ if ( postFinder ) {
- var queue = jQuery.queue( elem, type ),
- startLength = queue.length,
- fn = queue.shift(),
- hooks = jQuery._queueHooks( elem, type ),
- next = function() {
- jQuery.dequeue( elem, type );
- };
+ // Get the final matcherOut by condensing this intermediate into postFinder contexts
+ temp = [];
+ i = matcherOut.length;
+ while ( i-- ) {
+ if ( ( elem = matcherOut[ i ] ) ) {
- // If the fx queue is dequeued, always remove the progress sentinel
- if ( fn === "inprogress" ) {
- fn = queue.shift();
- startLength--;
- }
+ // Restore matcherIn since elem is not yet a final match
+ temp.push( ( matcherIn[ i ] = elem ) );
+ }
+ }
+ postFinder( null, ( matcherOut = [] ), temp, xml );
+ }
- if ( fn ) {
+ // Move matched elements from seed to results to keep them synchronized
+ i = matcherOut.length;
+ while ( i-- ) {
+ if ( ( elem = matcherOut[ i ] ) &&
+ ( temp = postFinder ? indexOf.call( seed, elem ) : preMap[ i ] ) > -1 ) {
- // Add a progress sentinel to prevent the fx queue from being
- // automatically dequeued
- if ( type === "fx" ) {
- queue.unshift( "inprogress" );
+ seed[ temp ] = !( results[ temp ] = elem );
+ }
+ }
}
- // Clear up the last queue stop function
- delete hooks.stop;
- fn.call( elem, next, hooks );
- }
-
- if ( !startLength && hooks ) {
- hooks.empty.fire();
+ // Add elements to results, through postFinder if defined
+ } else {
+ matcherOut = condense(
+ matcherOut === results ?
+ matcherOut.splice( preexisting, matcherOut.length ) :
+ matcherOut
+ );
+ if ( postFinder ) {
+ postFinder( null, results, matcherOut, xml );
+ } else {
+ push.apply( results, matcherOut );
+ }
}
- },
-
- // Not public - generate a queueHooks object, or return the current one
- _queueHooks: function( elem, type ) {
- var key = type + "queueHooks";
- return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
- empty: jQuery.Callbacks( "once memory" ).add( function() {
- dataPriv.remove( elem, [ type + "queue", key ] );
- } )
- } );
- }
-} );
+ } );
+}
-jQuery.fn.extend( {
- queue: function( type, data ) {
- var setter = 2;
+function matcherFromTokens( tokens ) {
+ var checkContext, matcher, j,
+ len = tokens.length,
+ leadingRelative = jQuery.expr.relative[ tokens[ 0 ].type ],
+ implicitRelative = leadingRelative || jQuery.expr.relative[ " " ],
+ i = leadingRelative ? 1 : 0,
- if ( typeof type !== "string" ) {
- data = type;
- type = "fx";
- setter--;
- }
+ // The foundational matcher ensures that elements are reachable from top-level context(s)
+ matchContext = addCombinator( function( elem ) {
+ return elem === checkContext;
+ }, implicitRelative, true ),
+ matchAnyContext = addCombinator( function( elem ) {
+ return indexOf.call( checkContext, elem ) > -1;
+ }, implicitRelative, true ),
+ matchers = [ function( elem, context, xml ) {
- if ( arguments.length < setter ) {
- return jQuery.queue( this[ 0 ], type );
- }
+ // Support: IE 11+
+ // IE sometimes throws a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ var ret = ( !leadingRelative && ( xml || context != outermostContext ) ) || (
+ ( checkContext = context ).nodeType ?
+ matchContext( elem, context, xml ) :
+ matchAnyContext( elem, context, xml ) );
- return data === undefined ?
- this :
- this.each( function() {
- var queue = jQuery.queue( this, type, data );
+ // Avoid hanging onto element
+ // (see https://github.com/jquery/sizzle/issues/299)
+ checkContext = null;
+ return ret;
+ } ];
- // Ensure a hooks for this queue
- jQuery._queueHooks( this, type );
+ for ( ; i < len; i++ ) {
+ if ( ( matcher = jQuery.expr.relative[ tokens[ i ].type ] ) ) {
+ matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
+ } else {
+ matcher = jQuery.expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );
- if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
- jQuery.dequeue( this, type );
- }
- } );
- },
- dequeue: function( type ) {
- return this.each( function() {
- jQuery.dequeue( this, type );
- } );
- },
- clearQueue: function( type ) {
- return this.queue( type || "fx", [] );
- },
+ // Return special upon seeing a positional matcher
+ if ( matcher[ jQuery.expando ] ) {
- // Get a promise resolved when queues of a certain type
- // are emptied (fx is the type by default)
- promise: function( type, obj ) {
- var tmp,
- count = 1,
- defer = jQuery.Deferred(),
- elements = this,
- i = this.length,
- resolve = function() {
- if ( !( --count ) ) {
- defer.resolveWith( elements, [ elements ] );
+ // Find the next relative operator (if any) for proper handling
+ j = ++i;
+ for ( ; j < len; j++ ) {
+ if ( jQuery.expr.relative[ tokens[ j ].type ] ) {
+ break;
+ }
}
- };
-
- if ( typeof type !== "string" ) {
- obj = type;
- type = undefined;
- }
- type = type || "fx";
+ return setMatcher(
+ i > 1 && elementMatcher( matchers ),
+ i > 1 && toSelector(
- while ( i-- ) {
- tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
- if ( tmp && tmp.empty ) {
- count++;
- tmp.empty.add( resolve );
+ // If the preceding token was a descendant combinator, insert an implicit any-element `*`
+ tokens.slice( 0, i - 1 )
+ .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } )
+ ).replace( rtrimCSS, "$1" ),
+ matcher,
+ i < j && matcherFromTokens( tokens.slice( i, j ) ),
+ j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),
+ j < len && toSelector( tokens )
+ );
}
+ matchers.push( matcher );
}
- resolve();
- return defer.promise( obj );
}
-} );
-var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
-var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
+ return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+ var bySet = setMatchers.length > 0,
+ byElement = elementMatchers.length > 0,
+ superMatcher = function( seed, context, xml, results, outermost ) {
+ var elem, j, matcher,
+ matchedCount = 0,
+ i = "0",
+ unmatched = seed && [],
+ setMatched = [],
+ contextBackup = outermostContext,
+ // We must always have either seed elements or outermost context
+ elems = seed || byElement && jQuery.expr.find.TAG( "*", outermost ),
-var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
+ // Use integer dirruns iff this is the outermost matcher
+ dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 );
-var documentElement = document.documentElement;
+ if ( outermost ) {
+ // Support: IE 11+
+ // IE sometimes throws a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ outermostContext = context == document || context || outermost;
+ }
+ // Add elements passing elementMatchers directly to results
+ for ( ; ( elem = elems[ i ] ) != null; i++ ) {
+ if ( byElement && elem ) {
+ j = 0;
- var isAttached = function( elem ) {
- return jQuery.contains( elem.ownerDocument, elem );
- },
- composed = { composed: true };
-
- // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
- // Check attachment across shadow DOM boundaries when possible (gh-3504)
- // Support: iOS 10.0-10.2 only
- // Early iOS 10 versions support `attachShadow` but not `getRootNode`,
- // leading to errors. We need to check for `getRootNode`.
- if ( documentElement.getRootNode ) {
- isAttached = function( elem ) {
- return jQuery.contains( elem.ownerDocument, elem ) ||
- elem.getRootNode( composed ) === elem.ownerDocument;
- };
- }
-var isHiddenWithinTree = function( elem, el ) {
+ // Support: IE 11+
+ // IE sometimes throws a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( !context && elem.ownerDocument != document ) {
+ setDocument( elem );
+ xml = !documentIsHTML;
+ }
+ while ( ( matcher = elementMatchers[ j++ ] ) ) {
+ if ( matcher( elem, context || document, xml ) ) {
+ push.call( results, elem );
+ break;
+ }
+ }
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ }
+ }
- // isHiddenWithinTree might be called from jQuery#filter function;
- // in that case, element will be second argument
- elem = el || elem;
+ // Track unmatched elements for set filters
+ if ( bySet ) {
- // Inline style trumps all
- return elem.style.display === "none" ||
- elem.style.display === "" &&
+ // They will have gone through all possible matchers
+ if ( ( elem = !matcher && elem ) ) {
+ matchedCount--;
+ }
- // Otherwise, check computed style
- // Support: Firefox <=43 - 45
- // Disconnected elements can have computed display: none, so first confirm that elem is
- // in the document.
- isAttached( elem ) &&
+ // Lengthen the array for every element, matched or not
+ if ( seed ) {
+ unmatched.push( elem );
+ }
+ }
+ }
- jQuery.css( elem, "display" ) === "none";
- };
+ // `i` is now the count of elements visited above, and adding it to `matchedCount`
+ // makes the latter nonnegative.
+ matchedCount += i;
+ // Apply set filters to unmatched elements
+ // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
+ // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
+ // no element matchers and no seed.
+ // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
+ // case, which will result in a "00" `matchedCount` that differs from `i` but is also
+ // numerically zero.
+ if ( bySet && i !== matchedCount ) {
+ j = 0;
+ while ( ( matcher = setMatchers[ j++ ] ) ) {
+ matcher( unmatched, setMatched, context, xml );
+ }
+ if ( seed ) {
-function adjustCSS( elem, prop, valueParts, tween ) {
- var adjusted, scale,
- maxIterations = 20,
- currentValue = tween ?
- function() {
- return tween.cur();
- } :
- function() {
- return jQuery.css( elem, prop, "" );
- },
- initial = currentValue(),
- unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
+ // Reintegrate element matches to eliminate the need for sorting
+ if ( matchedCount > 0 ) {
+ while ( i-- ) {
+ if ( !( unmatched[ i ] || setMatched[ i ] ) ) {
+ setMatched[ i ] = pop.call( results );
+ }
+ }
+ }
- // Starting value computation is required for potential unit mismatches
- initialInUnit = elem.nodeType &&
- ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
- rcssNum.exec( jQuery.css( elem, prop ) );
+ // Discard index placeholder values to get only actual matches
+ setMatched = condense( setMatched );
+ }
- if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
+ // Add matches to results
+ push.apply( results, setMatched );
+
+ // Seedless set matches succeeding multiple successful matchers stipulate sorting
+ if ( outermost && !seed && setMatched.length > 0 &&
+ ( matchedCount + setMatchers.length ) > 1 ) {
+
+ jQuery.uniqueSort( results );
+ }
+ }
+
+ // Override manipulation of globals by nested matchers
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ outermostContext = contextBackup;
+ }
- // Support: Firefox <=54
- // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
- initial = initial / 2;
+ return unmatched;
+ };
- // Trust units reported by jQuery.css
- unit = unit || initialInUnit[ 3 ];
+ return bySet ?
+ markFunction( superMatcher ) :
+ superMatcher;
+}
- // Iteratively approximate from a nonzero starting point
- initialInUnit = +initial || 1;
+function compile( selector, match /* Internal Use Only */ ) {
+ var i,
+ setMatchers = [],
+ elementMatchers = [],
+ cached = compilerCache[ selector + " " ];
- while ( maxIterations-- ) {
+ if ( !cached ) {
- // Evaluate and update our best guess (doubling guesses that zero out).
- // Finish if the scale equals or crosses 1 (making the old*new product non-positive).
- jQuery.style( elem, prop, initialInUnit + unit );
- if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
- maxIterations = 0;
+ // Generate a function of recursive functions that can be used to check each element
+ if ( !match ) {
+ match = tokenize( selector );
+ }
+ i = match.length;
+ while ( i-- ) {
+ cached = matcherFromTokens( match[ i ] );
+ if ( cached[ jQuery.expando ] ) {
+ setMatchers.push( cached );
+ } else {
+ elementMatchers.push( cached );
}
- initialInUnit = initialInUnit / scale;
-
}
- initialInUnit = initialInUnit * 2;
- jQuery.style( elem, prop, initialInUnit + unit );
+ // Cache the compiled function
+ cached = compilerCache( selector,
+ matcherFromGroupMatchers( elementMatchers, setMatchers ) );
- // Make sure we update the tween properties later on
- valueParts = valueParts || [];
+ // Save selector and tokenization
+ cached.selector = selector;
}
+ return cached;
+}
- if ( valueParts ) {
- initialInUnit = +initialInUnit || +initial || 0;
+/**
+ * A low-level selection function that works with jQuery's compiled
+ * selector functions
+ * @param {String|Function} selector A selector or a pre-compiled
+ * selector function built with jQuery selector compile
+ * @param {Element} context
+ * @param {Array} [results]
+ * @param {Array} [seed] A set of elements to match against
+ */
+function select( selector, context, results, seed ) {
+ var i, tokens, token, type, find,
+ compiled = typeof selector === "function" && selector,
+ match = !seed && tokenize( ( selector = compiled.selector || selector ) );
- // Apply relative offset (+=/-=) if specified
- adjusted = valueParts[ 1 ] ?
- initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
- +valueParts[ 2 ];
- if ( tween ) {
- tween.unit = unit;
- tween.start = initialInUnit;
- tween.end = adjusted;
- }
- }
- return adjusted;
-}
+ results = results || [];
+ // Try to minimize operations if there is only one selector in the list and no seed
+ // (the latter of which guarantees us context)
+ if ( match.length === 1 ) {
-var defaultDisplayMap = {};
+ // Reduce context if the leading compound selector is an ID
+ tokens = match[ 0 ] = match[ 0 ].slice( 0 );
+ if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&
+ context.nodeType === 9 && documentIsHTML &&
+ jQuery.expr.relative[ tokens[ 1 ].type ] ) {
-function getDefaultDisplay( elem ) {
- var temp,
- doc = elem.ownerDocument,
- nodeName = elem.nodeName,
- display = defaultDisplayMap[ nodeName ];
+ context = ( jQuery.expr.find.ID(
+ unescapeSelector( token.matches[ 0 ] ),
+ context
+ ) || [] )[ 0 ];
+ if ( !context ) {
+ return results;
- if ( display ) {
- return display;
- }
+ // Precompiled matchers will still verify ancestry, so step up a level
+ } else if ( compiled ) {
+ context = context.parentNode;
+ }
- temp = doc.body.appendChild( doc.createElement( nodeName ) );
- display = jQuery.css( temp, "display" );
+ selector = selector.slice( tokens.shift().value.length );
+ }
- temp.parentNode.removeChild( temp );
+ // Fetch a seed set for right-to-left matching
+ i = matchExpr.needsContext.test( selector ) ? 0 : tokens.length;
+ while ( i-- ) {
+ token = tokens[ i ];
- if ( display === "none" ) {
- display = "block";
+ // Abort if we hit a combinator
+ if ( jQuery.expr.relative[ ( type = token.type ) ] ) {
+ break;
+ }
+ if ( ( find = jQuery.expr.find[ type ] ) ) {
+
+ // Search, expanding context for leading sibling combinators
+ if ( ( seed = find(
+ unescapeSelector( token.matches[ 0 ] ),
+ rsibling.test( tokens[ 0 ].type ) &&
+ testContext( context.parentNode ) || context
+ ) ) ) {
+
+ // If seed is empty or no tokens remain, we can return early
+ tokens.splice( i, 1 );
+ selector = seed.length && toSelector( tokens );
+ if ( !selector ) {
+ push.apply( results, seed );
+ return results;
+ }
+
+ break;
+ }
+ }
+ }
}
- defaultDisplayMap[ nodeName ] = display;
- return display;
+ // Compile and execute a filtering function if one is not provided
+ // Provide `match` to avoid retokenization if we modified the selector above
+ ( compiled || compile( selector, match ) )(
+ seed,
+ context,
+ !documentIsHTML,
+ results,
+ !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
+ );
+ return results;
}
-function showHide( elements, show ) {
- var display, elem,
- values = [],
- index = 0,
- length = elements.length;
+// Initialize against the default document
+setDocument();
- // Determine new display value for elements that need to change
- for ( ; index < length; index++ ) {
- elem = elements[ index ];
- if ( !elem.style ) {
- continue;
- }
+jQuery.find = find;
- display = elem.style.display;
- if ( show ) {
+// These have always been private, but they used to be documented as part of
+// Sizzle so let's maintain them for now for backwards compatibility purposes.
+find.compile = compile;
+find.select = select;
+find.setDocument = setDocument;
+find.tokenize = tokenize;
- // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
- // check is required in this first loop unless we have a nonempty display value (either
- // inline or about-to-be-restored)
- if ( display === "none" ) {
- values[ index ] = dataPriv.get( elem, "display" ) || null;
- if ( !values[ index ] ) {
- elem.style.display = "";
- }
- }
- if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
- values[ index ] = getDefaultDisplay( elem );
- }
- } else {
- if ( display !== "none" ) {
- values[ index ] = "none";
+function dir( elem, dir, until ) {
+ var matched = [],
+ truncate = until !== undefined;
- // Remember what we're overwriting
- dataPriv.set( elem, "display", display );
+ while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
+ if ( elem.nodeType === 1 ) {
+ if ( truncate && jQuery( elem ).is( until ) ) {
+ break;
}
+ matched.push( elem );
}
}
+ return matched;
+}
- // Set the display of the elements in a second loop to avoid constant reflow
- for ( index = 0; index < length; index++ ) {
- if ( values[ index ] != null ) {
- elements[ index ].style.display = values[ index ];
+function siblings( n, elem ) {
+ var matched = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ matched.push( n );
}
}
- return elements;
+ return matched;
}
-jQuery.fn.extend( {
- show: function() {
- return showHide( this, true );
- },
- hide: function() {
- return showHide( this );
- },
- toggle: function( state ) {
- if ( typeof state === "boolean" ) {
- return state ? this.show() : this.hide();
- }
-
- return this.each( function() {
- if ( isHiddenWithinTree( this ) ) {
- jQuery( this ).show();
- } else {
- jQuery( this ).hide();
- }
- } );
- }
-} );
-var rcheckableType = ( /^(?:checkbox|radio)$/i );
+var rneedsContext = jQuery.expr.match.needsContext;
-var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i );
+// rsingleTag matches a string consisting of a single HTML element with no attributes
+// and captures the element's name
+var rsingleTag = /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;
-var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
+function isObviousHtml( input ) {
+ return input[ 0 ] === "<" &&
+ input[ input.length - 1 ] === ">" &&
+ input.length >= 3;
+}
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, not ) {
+ if ( typeof qualifier === "function" ) {
+ return jQuery.grep( elements, function( elem, i ) {
+ return !!qualifier.call( elem, i, elem ) !== not;
+ } );
+ }
+ // Single element
+ if ( qualifier.nodeType ) {
+ return jQuery.grep( elements, function( elem ) {
+ return ( elem === qualifier ) !== not;
+ } );
+ }
-( function() {
- var fragment = document.createDocumentFragment(),
- div = fragment.appendChild( document.createElement( "div" ) ),
- input = document.createElement( "input" );
+ // Arraylike of elements (jQuery, arguments, Array)
+ if ( typeof qualifier !== "string" ) {
+ return jQuery.grep( elements, function( elem ) {
+ return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
+ } );
+ }
- // Support: Android 4.0 - 4.3 only
- // Check state lost if the name is set (trac-11217)
- // Support: Windows Web Apps (WWA)
- // `name` and `type` must use .setAttribute for WWA (trac-14901)
- input.setAttribute( "type", "radio" );
- input.setAttribute( "checked", "checked" );
- input.setAttribute( "name", "t" );
+ // Filtered directly for both simple and complex selectors
+ return jQuery.filter( qualifier, elements, not );
+}
- div.appendChild( input );
+jQuery.filter = function( expr, elems, not ) {
+ var elem = elems[ 0 ];
- // Support: Android <=4.1 only
- // Older WebKit doesn't clone checked state correctly in fragments
- support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
- // Support: IE <=11 only
- // Make sure textarea (and checkbox) defaultValue is properly cloned
- div.innerHTML = "";
- support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
+ if ( elems.length === 1 && elem.nodeType === 1 ) {
+ return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
+ }
- // Support: IE <=9 only
- // IE <=9 replaces tags with their contents when inserted outside of
- // the select element.
- div.innerHTML = " ";
- support.option = !!div.lastChild;
-} )();
+ return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+ return elem.nodeType === 1;
+ } ) );
+};
+jQuery.fn.extend( {
+ find: function( selector ) {
+ var i, ret,
+ len = this.length,
+ self = this;
-// We have to close these tags to support XHTML (trac-13200)
-var wrapMap = {
+ if ( typeof selector !== "string" ) {
+ return this.pushStack( jQuery( selector ).filter( function() {
+ for ( i = 0; i < len; i++ ) {
+ if ( jQuery.contains( self[ i ], this ) ) {
+ return true;
+ }
+ }
+ } ) );
+ }
- // XHTML parsers do not magically insert elements in the
- // same way that tag soup parsers do. So we cannot shorten
- // this by omitting or other required elements.
- thead: [ 1, "" ],
- col: [ 2, "" ],
- tr: [ 2, "" ],
- td: [ 3, "" ],
+ ret = this.pushStack( [] );
- _default: [ 0, "", "" ]
-};
+ for ( i = 0; i < len; i++ ) {
+ jQuery.find( selector, self[ i ], ret );
+ }
-wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
-wrapMap.th = wrapMap.td;
+ return len > 1 ? jQuery.uniqueSort( ret ) : ret;
+ },
+ filter: function( selector ) {
+ return this.pushStack( winnow( this, selector || [], false ) );
+ },
+ not: function( selector ) {
+ return this.pushStack( winnow( this, selector || [], true ) );
+ },
+ is: function( selector ) {
+ return !!winnow(
+ this,
-// Support: IE <=9 only
-if ( !support.option ) {
- wrapMap.optgroup = wrapMap.option = [ 1, "", " " ];
-}
+ // If this is a positional/relative selector, check membership in the returned set
+ // so $("p:first").is("p:last") won't return true for a doc with two "p".
+ typeof selector === "string" && rneedsContext.test( selector ) ?
+ jQuery( selector ) :
+ selector || [],
+ false
+ ).length;
+ }
+} );
+// Initialize a jQuery object
-function getAll( context, tag ) {
+// A central reference to the root jQuery(document)
+var rootjQuery,
- // Support: IE <=9 - 11 only
- // Use typeof to avoid zero-argument method invocation on host objects (trac-15151)
- var ret;
+ // A simple way to check for HTML strings
+ // Prioritize #id over to avoid XSS via location.hash (trac-9521)
+ // Strict HTML recognition (trac-11290: must start with <)
+ // Shortcut simple #id case for speed
+ rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
- if ( typeof context.getElementsByTagName !== "undefined" ) {
- ret = context.getElementsByTagName( tag || "*" );
+ init = jQuery.fn.init = function( selector, context ) {
+ var match, elem;
- } else if ( typeof context.querySelectorAll !== "undefined" ) {
- ret = context.querySelectorAll( tag || "*" );
+ // HANDLE: $(""), $(null), $(undefined), $(false)
+ if ( !selector ) {
+ return this;
+ }
- } else {
- ret = [];
- }
+ // HANDLE: $(DOMElement)
+ if ( selector.nodeType ) {
+ this[ 0 ] = selector;
+ this.length = 1;
+ return this;
- if ( tag === undefined || tag && nodeName( context, tag ) ) {
- return jQuery.merge( [ context ], ret );
- }
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( typeof selector === "function" ) {
+ return rootjQuery.ready !== undefined ?
+ rootjQuery.ready( selector ) :
- return ret;
-}
+ // Execute immediately if ready is not present
+ selector( jQuery );
+ } else {
-// Mark scripts as having already been evaluated
-function setGlobalEval( elems, refElements ) {
- var i = 0,
- l = elems.length;
+ // Handle obvious HTML strings
+ match = selector + "";
+ if ( isObviousHtml( match ) ) {
- for ( ; i < l; i++ ) {
- dataPriv.set(
- elems[ i ],
- "globalEval",
- !refElements || dataPriv.get( refElements[ i ], "globalEval" )
- );
- }
-}
+ // Assume that strings that start and end with <> are HTML and skip
+ // the regex check. This also handles browser-supported HTML wrappers
+ // like TrustedHTML.
+ match = [ null, selector, null ];
+ // Handle HTML strings or selectors
+ } else if ( typeof selector === "string" ) {
+ match = rquickExpr.exec( selector );
+ } else {
+ return jQuery.makeArray( selector, this );
+ }
-var rhtml = /<|?\w+;/;
+ // Match html or make sure no context is specified for #id
+ // Note: match[1] may be a string or a TrustedHTML wrapper
+ if ( match && ( match[ 1 ] || !context ) ) {
-function buildFragment( elems, context, scripts, selection, ignored ) {
- var elem, tmp, tag, wrap, attached, j,
- fragment = context.createDocumentFragment(),
- nodes = [],
- i = 0,
- l = elems.length;
+ // HANDLE: $(html) -> $(array)
+ if ( match[ 1 ] ) {
+ context = context instanceof jQuery ? context[ 0 ] : context;
- for ( ; i < l; i++ ) {
- elem = elems[ i ];
+ // Option to run scripts is true for back-compat
+ // Intentionally let the error be thrown if parseHTML is not present
+ jQuery.merge( this, jQuery.parseHTML(
+ match[ 1 ],
+ context && context.nodeType ? context.ownerDocument || context : document$1,
+ true
+ ) );
- if ( elem || elem === 0 ) {
+ // HANDLE: $(html, props)
+ if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
+ for ( match in context ) {
- // Add nodes directly
- if ( toType( elem ) === "object" ) {
+ // Properties of context are called as methods if possible
+ if ( typeof this[ match ] === "function" ) {
+ this[ match ]( context[ match ] );
- // Support: Android <=4.0 only, PhantomJS 1 only
- // push.apply(_, arraylike) throws on ancient WebKit
- jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
+ // ...and otherwise set as attributes
+ } else {
+ this.attr( match, context[ match ] );
+ }
+ }
+ }
- // Convert non-html into a text node
- } else if ( !rhtml.test( elem ) ) {
- nodes.push( context.createTextNode( elem ) );
+ return this;
- // Convert html into DOM nodes
- } else {
- tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
+ // HANDLE: $(#id)
+ } else {
+ elem = document$1.getElementById( match[ 2 ] );
- // Deserialize a standard representation
- tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
- wrap = wrapMap[ tag ] || wrapMap._default;
- tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
+ if ( elem ) {
- // Descend through wrappers to the right content
- j = wrap[ 0 ];
- while ( j-- ) {
- tmp = tmp.lastChild;
+ // Inject the element directly into the jQuery object
+ this[ 0 ] = elem;
+ this.length = 1;
+ }
+ return this;
}
- // Support: Android <=4.0 only, PhantomJS 1 only
- // push.apply(_, arraylike) throws on ancient WebKit
- jQuery.merge( nodes, tmp.childNodes );
-
- // Remember the top-level container
- tmp = fragment.firstChild;
+ // HANDLE: $(expr) & $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return ( context || rootjQuery ).find( selector );
- // Ensure the created nodes are orphaned (trac-12392)
- tmp.textContent = "";
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return this.constructor( context ).find( selector );
}
}
- }
- // Remove wrapper from fragment
- fragment.textContent = "";
+ };
- i = 0;
- while ( ( elem = nodes[ i++ ] ) ) {
+// Give the init function the jQuery prototype for later instantiation
+init.prototype = jQuery.fn;
- // Skip elements already in the context collection (trac-4087)
- if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
- if ( ignored ) {
- ignored.push( elem );
- }
- continue;
- }
+// Initialize central reference
+rootjQuery = jQuery( document$1 );
- attached = isAttached( elem );
+var rparentsprev = /^(?:parents|prev(?:Until|All))/,
- // Append to fragment
- tmp = getAll( fragment.appendChild( elem ), "script" );
+ // Methods guaranteed to produce a unique set when starting from a unique set
+ guaranteedUnique = {
+ children: true,
+ contents: true,
+ next: true,
+ prev: true
+ };
- // Preserve script evaluation history
- if ( attached ) {
- setGlobalEval( tmp );
- }
+jQuery.fn.extend( {
+ has: function( target ) {
+ var targets = jQuery( target, this ),
+ l = targets.length;
- // Capture executables
- if ( scripts ) {
- j = 0;
- while ( ( elem = tmp[ j++ ] ) ) {
- if ( rscriptType.test( elem.type || "" ) ) {
- scripts.push( elem );
+ return this.filter( function() {
+ var i = 0;
+ for ( ; i < l; i++ ) {
+ if ( jQuery.contains( this, targets[ i ] ) ) {
+ return true;
}
}
- }
- }
-
- return fragment;
-}
-
-
-var rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
-
-function returnTrue() {
- return true;
-}
+ } );
+ },
-function returnFalse() {
- return false;
-}
+ closest: function( selectors, context ) {
+ var cur,
+ i = 0,
+ l = this.length,
+ matched = [],
+ targets = typeof selectors !== "string" && jQuery( selectors );
-function on( elem, types, selector, data, fn, one ) {
- var origFn, type;
+ // Positional selectors never match, since there's no _selection_ context
+ if ( !rneedsContext.test( selectors ) ) {
+ for ( ; i < l; i++ ) {
+ for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
- // Types can be a map of types/handlers
- if ( typeof types === "object" ) {
+ // Always skip document fragments
+ if ( cur.nodeType < 11 && ( targets ?
+ targets.index( cur ) > -1 :
- // ( types-Object, selector, data )
- if ( typeof selector !== "string" ) {
+ // Don't pass non-elements to jQuery#find
+ cur.nodeType === 1 &&
+ jQuery.find.matchesSelector( cur, selectors ) ) ) {
- // ( types-Object, data )
- data = data || selector;
- selector = undefined;
- }
- for ( type in types ) {
- on( elem, type, selector, data, types[ type ], one );
+ matched.push( cur );
+ break;
+ }
+ }
+ }
}
- return elem;
- }
- if ( data == null && fn == null ) {
+ return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
+ },
- // ( types, fn )
- fn = selector;
- data = selector = undefined;
- } else if ( fn == null ) {
- if ( typeof selector === "string" ) {
+ // Determine the position of an element within the set
+ index: function( elem ) {
- // ( types, selector, fn )
- fn = data;
- data = undefined;
- } else {
+ // No argument, return index in parent
+ if ( !elem ) {
+ return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
+ }
- // ( types, data, fn )
- fn = data;
- data = selector;
- selector = undefined;
+ // Index in selector
+ if ( typeof elem === "string" ) {
+ return indexOf.call( jQuery( elem ), this[ 0 ] );
}
- }
- if ( fn === false ) {
- fn = returnFalse;
- } else if ( !fn ) {
- return elem;
- }
- if ( one === 1 ) {
- origFn = fn;
- fn = function( event ) {
+ // Locate the position of the desired element
+ return indexOf.call( this,
- // Can use an empty set, since event contains the info
- jQuery().off( event );
- return origFn.apply( this, arguments );
- };
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[ 0 ] : elem
+ );
+ },
- // Use same guid so caller can remove using origFn
- fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
- }
- return elem.each( function() {
- jQuery.event.add( this, types, fn, data, selector );
- } );
-}
+ add: function( selector, context ) {
+ return this.pushStack(
+ jQuery.uniqueSort(
+ jQuery.merge( this.get(), jQuery( selector, context ) )
+ )
+ );
+ },
-/*
- * Helper functions for managing events -- not part of the public interface.
- * Props to Dean Edwards' addEvent library for many of the ideas.
- */
-jQuery.event = {
+ addBack: function( selector ) {
+ return this.add( selector == null ?
+ this.prevObject : this.prevObject.filter( selector )
+ );
+ }
+} );
- global: {},
+function sibling( cur, dir ) {
+ while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
+ return cur;
+}
- add: function( elem, types, handler, data, selector ) {
+jQuery.each( {
+ parent: function( elem ) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents: function( elem ) {
+ return dir( elem, "parentNode" );
+ },
+ parentsUntil: function( elem, _i, until ) {
+ return dir( elem, "parentNode", until );
+ },
+ next: function( elem ) {
+ return sibling( elem, "nextSibling" );
+ },
+ prev: function( elem ) {
+ return sibling( elem, "previousSibling" );
+ },
+ nextAll: function( elem ) {
+ return dir( elem, "nextSibling" );
+ },
+ prevAll: function( elem ) {
+ return dir( elem, "previousSibling" );
+ },
+ nextUntil: function( elem, _i, until ) {
+ return dir( elem, "nextSibling", until );
+ },
+ prevUntil: function( elem, _i, until ) {
+ return dir( elem, "previousSibling", until );
+ },
+ siblings: function( elem ) {
+ return siblings( ( elem.parentNode || {} ).firstChild, elem );
+ },
+ children: function( elem ) {
+ return siblings( elem.firstChild );
+ },
+ contents: function( elem ) {
+ if ( elem.contentDocument != null &&
- var handleObjIn, eventHandle, tmp,
- events, t, handleObj,
- special, handlers, type, namespaces, origType,
- elemData = dataPriv.get( elem );
+ // Support: IE 11+
+ // elements with no `data` attribute has an object
+ // `contentDocument` with a `null` prototype.
+ getProto( elem.contentDocument ) ) {
- // Only attach events to objects that accept data
- if ( !acceptData( elem ) ) {
- return;
+ return elem.contentDocument;
}
- // Caller can pass in an object of custom data in lieu of the handler
- if ( handler.handler ) {
- handleObjIn = handler;
- handler = handleObjIn.handler;
- selector = handleObjIn.selector;
+ // Support: IE 9 - 11+
+ // Treat the template element as a regular one in browsers that
+ // don't support it.
+ if ( nodeName( elem, "template" ) ) {
+ elem = elem.content || elem;
}
- // Ensure that invalid selectors throw exceptions at attach time
- // Evaluate against documentElement in case elem is a non-element node (e.g., document)
- if ( selector ) {
- jQuery.find.matchesSelector( documentElement, selector );
- }
+ return jQuery.merge( [], elem.childNodes );
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function( until, selector ) {
+ var matched = jQuery.map( this, fn, until );
- // Make sure that the handler has a unique ID, used to find/remove it later
- if ( !handler.guid ) {
- handler.guid = jQuery.guid++;
+ if ( name.slice( -5 ) !== "Until" ) {
+ selector = until;
}
- // Init the element's event structure and main handler, if this is the first
- if ( !( events = elemData.events ) ) {
- events = elemData.events = Object.create( null );
+ if ( selector && typeof selector === "string" ) {
+ matched = jQuery.filter( selector, matched );
}
- if ( !( eventHandle = elemData.handle ) ) {
- eventHandle = elemData.handle = function( e ) {
- // Discard the second event of a jQuery.event.trigger() and
- // when an event is called after a page has unloaded
- return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
- jQuery.event.dispatch.apply( elem, arguments ) : undefined;
- };
- }
+ if ( this.length > 1 ) {
- // Handle multiple events separated by a space
- types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
- t = types.length;
- while ( t-- ) {
- tmp = rtypenamespace.exec( types[ t ] ) || [];
- type = origType = tmp[ 1 ];
- namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
+ // Remove duplicates
+ if ( !guaranteedUnique[ name ] ) {
+ jQuery.uniqueSort( matched );
+ }
- // There *must* be a type, no attaching namespace-only handlers
- if ( !type ) {
- continue;
+ // Reverse order for parents* and prev-derivatives
+ if ( rparentsprev.test( name ) ) {
+ matched.reverse();
}
+ }
- // If event changes its type, use the special event handlers for the changed type
- special = jQuery.event.special[ type ] || {};
+ return this.pushStack( matched );
+ };
+} );
- // If selector defined, determine special event api type, otherwise given type
- type = ( selector ? special.delegateType : special.bindType ) || type;
+// Matches dashed string for camelizing
+var rdashAlpha = /-([a-z])/g;
- // Update special based on newly reset type
- special = jQuery.event.special[ type ] || {};
+// Used by camelCase as callback to replace()
+function fcamelCase( _all, letter ) {
+ return letter.toUpperCase();
+}
- // handleObj is passed to all event handlers
- handleObj = jQuery.extend( {
- type: type,
- origType: origType,
- data: data,
- handler: handler,
- guid: handler.guid,
- selector: selector,
- needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
- namespace: namespaces.join( "." )
- }, handleObjIn );
+// Convert dashed to camelCase
+function camelCase( string ) {
+ return string.replace( rdashAlpha, fcamelCase );
+}
- // Init the event handler queue if we're the first
- if ( !( handlers = events[ type ] ) ) {
- handlers = events[ type ] = [];
- handlers.delegateCount = 0;
+/**
+ * Determines whether an object can have data
+ */
+function acceptData( owner ) {
- // Only use addEventListener if the special events handler returns false
- if ( !special.setup ||
- special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+ // Accepts only:
+ // - Node
+ // - Node.ELEMENT_NODE
+ // - Node.DOCUMENT_NODE
+ // - Object
+ // - Any
+ return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
+}
- if ( elem.addEventListener ) {
- elem.addEventListener( type, eventHandle );
- }
+function Data() {
+ this.expando = jQuery.expando + Data.uid++;
+}
+
+Data.uid = 1;
+
+Data.prototype = {
+
+ cache: function( owner ) {
+
+ // Check if the owner object already has a cache
+ var value = owner[ this.expando ];
+
+ // If not, create one
+ if ( !value ) {
+ value = Object.create( null );
+
+ // We can accept data for non-element nodes in modern browsers,
+ // but we should not, see trac-8335.
+ // Always return an empty object.
+ if ( acceptData( owner ) ) {
+
+ // If it is a node unlikely to be stringify-ed or looped over
+ // use plain assignment
+ if ( owner.nodeType ) {
+ owner[ this.expando ] = value;
+
+ // Otherwise secure it in a non-enumerable property
+ // configurable must be true to allow the property to be
+ // deleted when data is removed
+ } else {
+ Object.defineProperty( owner, this.expando, {
+ value: value,
+ configurable: true
+ } );
}
}
+ }
- if ( special.add ) {
- special.add.call( elem, handleObj );
+ return value;
+ },
+ set: function( owner, data, value ) {
+ var prop,
+ cache = this.cache( owner );
- if ( !handleObj.handler.guid ) {
- handleObj.handler.guid = handler.guid;
- }
- }
+ // Handle: [ owner, key, value ] args
+ // Always use camelCase key (gh-2257)
+ if ( typeof data === "string" ) {
+ cache[ camelCase( data ) ] = value;
- // Add to the element's handler list, delegates in front
- if ( selector ) {
- handlers.splice( handlers.delegateCount++, 0, handleObj );
- } else {
- handlers.push( handleObj );
- }
+ // Handle: [ owner, { properties } ] args
+ } else {
- // Keep track of which events have ever been used, for event optimization
- jQuery.event.global[ type ] = true;
+ // Copy the properties one-by-one to the cache object
+ for ( prop in data ) {
+ cache[ camelCase( prop ) ] = data[ prop ];
+ }
}
-
+ return value;
},
+ get: function( owner, key ) {
+ return key === undefined ?
+ this.cache( owner ) :
- // Detach an event or set of events from an element
- remove: function( elem, types, handler, selector, mappedTypes ) {
+ // Always use camelCase key (gh-2257)
+ owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
+ },
+ access: function( owner, key, value ) {
- var j, origCount, tmp,
- events, t, handleObj,
- special, handlers, type, namespaces, origType,
- elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
+ // In cases where either:
+ //
+ // 1. No key was specified
+ // 2. A string key was specified, but no value provided
+ //
+ // Take the "read" path and allow the get method to determine
+ // which value to return, respectively either:
+ //
+ // 1. The entire cache object
+ // 2. The data stored at the key
+ //
+ if ( key === undefined ||
+ ( ( key && typeof key === "string" ) && value === undefined ) ) {
- if ( !elemData || !( events = elemData.events ) ) {
- return;
+ return this.get( owner, key );
}
- // Once for each type.namespace in types; type may be omitted
- types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
- t = types.length;
- while ( t-- ) {
- tmp = rtypenamespace.exec( types[ t ] ) || [];
- type = origType = tmp[ 1 ];
- namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
+ // When the key is not a string, or both a key and value
+ // are specified, set or extend (existing objects) with either:
+ //
+ // 1. An object of properties
+ // 2. A key and value
+ //
+ this.set( owner, key, value );
- // Unbind all events (on this namespace, if provided) for the element
- if ( !type ) {
- for ( type in events ) {
- jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
- }
- continue;
- }
+ // Since the "set" path can have two possible entry points
+ // return the expected data based on which path was taken[*]
+ return value !== undefined ? value : key;
+ },
+ remove: function( owner, key ) {
+ var i,
+ cache = owner[ this.expando ];
- special = jQuery.event.special[ type ] || {};
- type = ( selector ? special.delegateType : special.bindType ) || type;
- handlers = events[ type ] || [];
- tmp = tmp[ 2 ] &&
- new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
+ if ( cache === undefined ) {
+ return;
+ }
- // Remove matching events
- origCount = j = handlers.length;
- while ( j-- ) {
- handleObj = handlers[ j ];
+ if ( key !== undefined ) {
- if ( ( mappedTypes || origType === handleObj.origType ) &&
- ( !handler || handler.guid === handleObj.guid ) &&
- ( !tmp || tmp.test( handleObj.namespace ) ) &&
- ( !selector || selector === handleObj.selector ||
- selector === "**" && handleObj.selector ) ) {
- handlers.splice( j, 1 );
+ // Support array or space separated string of keys
+ if ( Array.isArray( key ) ) {
- if ( handleObj.selector ) {
- handlers.delegateCount--;
- }
- if ( special.remove ) {
- special.remove.call( elem, handleObj );
- }
- }
- }
+ // If key is an array of keys...
+ // We always set camelCase keys, so remove that.
+ key = key.map( camelCase );
+ } else {
+ key = camelCase( key );
- // Remove generic event handler if we removed something and no more handlers exist
- // (avoids potential for endless recursion during removal of special event handlers)
- if ( origCount && !handlers.length ) {
- if ( !special.teardown ||
- special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+ // If a key with the spaces exists, use it.
+ // Otherwise, create an array by matching non-whitespace
+ key = key in cache ?
+ [ key ] :
+ ( key.match( rnothtmlwhite ) || [] );
+ }
- jQuery.removeEvent( elem, type, elemData.handle );
- }
+ i = key.length;
- delete events[ type ];
+ while ( i-- ) {
+ delete cache[ key[ i ] ];
}
}
- // Remove data and the expando if it's no longer used
- if ( jQuery.isEmptyObject( events ) ) {
- dataPriv.remove( elem, "handle events" );
+ // Remove the expando if there's no more data
+ if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
+
+ // Support: Chrome <=35 - 45+
+ // Webkit & Blink performance suffers when deleting properties
+ // from DOM nodes, so set to undefined instead
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
+ if ( owner.nodeType ) {
+ owner[ this.expando ] = undefined;
+ } else {
+ delete owner[ this.expando ];
+ }
}
},
+ hasData: function( owner ) {
+ var cache = owner[ this.expando ];
+ return cache !== undefined && !jQuery.isEmptyObject( cache );
+ }
+};
- dispatch: function( nativeEvent ) {
-
- var i, j, ret, matched, handleObj, handlerQueue,
- args = new Array( arguments.length ),
-
- // Make a writable jQuery.Event from the native event object
- event = jQuery.event.fix( nativeEvent ),
+var dataPriv = new Data();
- handlers = (
- dataPriv.get( this, "events" ) || Object.create( null )
- )[ event.type ] || [],
- special = jQuery.event.special[ event.type ] || {};
+var dataUser = new Data();
- // Use the fix-ed jQuery.Event rather than the (read-only) native event
- args[ 0 ] = event;
+// Implementation Summary
+//
+// 1. Enforce API surface and semantic compatibility with 1.9.x branch
+// 2. Improve the module's maintainability by reducing the storage
+// paths to a single mechanism.
+// 3. Use the same single mechanism to support "private" and "user" data.
+// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
+// 5. Avoid exposing implementation details on user objects (eg. expando properties)
+// 6. Provide a clear path for implementation upgrade to WeakMap in 2014
- for ( i = 1; i < arguments.length; i++ ) {
- args[ i ] = arguments[ i ];
- }
+var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
+ rmultiDash = /[A-Z]/g;
- event.delegateTarget = this;
+function getData( data ) {
+ if ( data === "true" ) {
+ return true;
+ }
- // Call the preDispatch hook for the mapped type, and let it bail if desired
- if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
- return;
- }
+ if ( data === "false" ) {
+ return false;
+ }
- // Determine handlers
- handlerQueue = jQuery.event.handlers.call( this, event, handlers );
+ if ( data === "null" ) {
+ return null;
+ }
- // Run delegates first; they may want to stop propagation beneath us
- i = 0;
- while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
- event.currentTarget = matched.elem;
+ // Only convert to a number if it doesn't change the string
+ if ( data === +data + "" ) {
+ return +data;
+ }
- j = 0;
- while ( ( handleObj = matched.handlers[ j++ ] ) &&
- !event.isImmediatePropagationStopped() ) {
+ if ( rbrace.test( data ) ) {
+ return JSON.parse( data );
+ }
- // If the event is namespaced, then each handler is only invoked if it is
- // specially universal or its namespaces are a superset of the event's.
- if ( !event.rnamespace || handleObj.namespace === false ||
- event.rnamespace.test( handleObj.namespace ) ) {
+ return data;
+}
- event.handleObj = handleObj;
- event.data = handleObj.data;
+function dataAttr( elem, key, data ) {
+ var name;
- ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
- handleObj.handler ).apply( matched.elem, args );
+ // If nothing was found internally, try to fetch any
+ // data from the HTML5 data-* attribute
+ if ( data === undefined && elem.nodeType === 1 ) {
+ name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
+ data = elem.getAttribute( name );
- if ( ret !== undefined ) {
- if ( ( event.result = ret ) === false ) {
- event.preventDefault();
- event.stopPropagation();
- }
- }
- }
- }
- }
+ if ( typeof data === "string" ) {
+ try {
+ data = getData( data );
+ } catch ( e ) {}
- // Call the postDispatch hook for the mapped type
- if ( special.postDispatch ) {
- special.postDispatch.call( this, event );
+ // Make sure we set the data so it isn't changed later
+ dataUser.set( elem, key, data );
+ } else {
+ data = undefined;
}
+ }
+ return data;
+}
- return event.result;
+jQuery.extend( {
+ hasData: function( elem ) {
+ return dataUser.hasData( elem ) || dataPriv.hasData( elem );
},
- handlers: function( event, handlers ) {
- var i, handleObj, sel, matchedHandlers, matchedSelectors,
- handlerQueue = [],
- delegateCount = handlers.delegateCount,
- cur = event.target;
+ data: function( elem, name, data ) {
+ return dataUser.access( elem, name, data );
+ },
- // Find delegate handlers
- if ( delegateCount &&
+ removeData: function( elem, name ) {
+ dataUser.remove( elem, name );
+ },
- // Support: IE <=9
- // Black-hole SVG instance trees (trac-13180)
- cur.nodeType &&
+ // TODO: Now that all calls to _data and _removeData have been replaced
+ // with direct calls to dataPriv methods, these can be deprecated.
+ _data: function( elem, name, data ) {
+ return dataPriv.access( elem, name, data );
+ },
- // Support: Firefox <=42
- // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
- // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
- // Support: IE 11 only
- // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
- !( event.type === "click" && event.button >= 1 ) ) {
+ _removeData: function( elem, name ) {
+ dataPriv.remove( elem, name );
+ }
+} );
- for ( ; cur !== this; cur = cur.parentNode || this ) {
+jQuery.fn.extend( {
+ data: function( key, value ) {
+ var i, name, data,
+ elem = this[ 0 ],
+ attrs = elem && elem.attributes;
- // Don't check non-elements (trac-13208)
- // Don't process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764)
- if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
- matchedHandlers = [];
- matchedSelectors = {};
- for ( i = 0; i < delegateCount; i++ ) {
- handleObj = handlers[ i ];
+ // Gets all values
+ if ( key === undefined ) {
+ if ( this.length ) {
+ data = dataUser.get( elem );
- // Don't conflict with Object.prototype properties (trac-13203)
- sel = handleObj.selector + " ";
+ if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
+ i = attrs.length;
+ while ( i-- ) {
- if ( matchedSelectors[ sel ] === undefined ) {
- matchedSelectors[ sel ] = handleObj.needsContext ?
- jQuery( sel, this ).index( cur ) > -1 :
- jQuery.find( sel, this, null, [ cur ] ).length;
- }
- if ( matchedSelectors[ sel ] ) {
- matchedHandlers.push( handleObj );
+ // Support: IE 11+
+ // The attrs elements can be null (trac-14894)
+ if ( attrs[ i ] ) {
+ name = attrs[ i ].name;
+ if ( name.indexOf( "data-" ) === 0 ) {
+ name = camelCase( name.slice( 5 ) );
+ dataAttr( elem, name, data[ name ] );
+ }
}
}
- if ( matchedHandlers.length ) {
- handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
- }
+ dataPriv.set( elem, "hasDataAttrs", true );
}
}
- }
- // Add the remaining (directly-bound) handlers
- cur = this;
- if ( delegateCount < handlers.length ) {
- handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
+ return data;
}
- return handlerQueue;
- },
-
- addProp: function( name, hook ) {
- Object.defineProperty( jQuery.Event.prototype, name, {
- enumerable: true,
- configurable: true,
-
- get: isFunction( hook ) ?
- function() {
- if ( this.originalEvent ) {
- return hook( this.originalEvent );
- }
- } :
- function() {
- if ( this.originalEvent ) {
- return this.originalEvent[ name ];
- }
- },
-
- set: function( value ) {
- Object.defineProperty( this, name, {
- enumerable: true,
- configurable: true,
- writable: true,
- value: value
- } );
- }
- } );
- },
-
- fix: function( originalEvent ) {
- return originalEvent[ jQuery.expando ] ?
- originalEvent :
- new jQuery.Event( originalEvent );
- },
-
- special: {
- load: {
-
- // Prevent triggered image.load events from bubbling to window.load
- noBubble: true
- },
- click: {
-
- // Utilize native event to ensure correct state for checkable inputs
- setup: function( data ) {
+ // Sets multiple values
+ if ( typeof key === "object" ) {
+ return this.each( function() {
+ dataUser.set( this, key );
+ } );
+ }
- // For mutual compressibility with _default, replace `this` access with a local var.
- // `|| data` is dead code meant only to preserve the variable through minification.
- var el = this || data;
+ return access( this, function( value ) {
+ var data;
- // Claim the first handler
- if ( rcheckableType.test( el.type ) &&
- el.click && nodeName( el, "input" ) ) {
+ // The calling jQuery object (element matches) is not empty
+ // (and therefore has an element appears at this[ 0 ]) and the
+ // `value` parameter was not undefined. An empty jQuery object
+ // will result in `undefined` for elem = this[ 0 ] which will
+ // throw an exception if an attempt to read a data cache is made.
+ if ( elem && value === undefined ) {
- // dataPriv.set( el, "click", ... )
- leverageNative( el, "click", true );
+ // Attempt to get data from the cache
+ // The key will always be camelCased in Data
+ data = dataUser.get( elem, key );
+ if ( data !== undefined ) {
+ return data;
}
- // Return false to allow normal processing in the caller
- return false;
- },
- trigger: function( data ) {
+ // Attempt to "discover" the data in
+ // HTML5 custom data-* attrs
+ data = dataAttr( elem, key );
+ if ( data !== undefined ) {
+ return data;
+ }
- // For mutual compressibility with _default, replace `this` access with a local var.
- // `|| data` is dead code meant only to preserve the variable through minification.
- var el = this || data;
+ // We tried really hard, but the data doesn't exist.
+ return;
+ }
- // Force setup before triggering a click
- if ( rcheckableType.test( el.type ) &&
- el.click && nodeName( el, "input" ) ) {
+ // Set the data...
+ this.each( function() {
- leverageNative( el, "click" );
- }
+ // We always store the camelCased key
+ dataUser.set( this, key, value );
+ } );
+ }, null, value, arguments.length > 1, null, true );
+ },
- // Return non-false to allow normal event-path propagation
- return true;
- },
+ removeData: function( key ) {
+ return this.each( function() {
+ dataUser.remove( this, key );
+ } );
+ }
+} );
- // For cross-browser consistency, suppress native .click() on links
- // Also prevent it if we're currently inside a leveraged native-event stack
- _default: function( event ) {
- var target = event.target;
- return rcheckableType.test( target.type ) &&
- target.click && nodeName( target, "input" ) &&
- dataPriv.get( target, "click" ) ||
- nodeName( target, "a" );
- }
- },
+var rfocusable = /^(?:input|select|textarea|button)$/i,
+ rclickable = /^(?:a|area)$/i;
- beforeunload: {
- postDispatch: function( event ) {
+jQuery.fn.extend( {
+ prop: function( name, value ) {
+ return access( this, jQuery.prop, name, value, arguments.length > 1 );
+ },
- // Support: Firefox 20+
- // Firefox doesn't alert if the returnValue field is not set.
- if ( event.result !== undefined && event.originalEvent ) {
- event.originalEvent.returnValue = event.result;
- }
- }
- }
+ removeProp: function( name ) {
+ return this.each( function() {
+ delete this[ jQuery.propFix[ name ] || name ];
+ } );
}
-};
+} );
-// Ensure the presence of an event listener that handles manually-triggered
-// synthetic events by interrupting progress until reinvoked in response to
-// *native* events that it fires directly, ensuring that state changes have
-// already occurred before other listeners are invoked.
-function leverageNative( el, type, isSetup ) {
+jQuery.extend( {
+ prop: function( elem, name, value ) {
+ var ret, hooks,
+ nType = elem.nodeType;
- // Missing `isSetup` indicates a trigger call, which must force setup through jQuery.event.add
- if ( !isSetup ) {
- if ( dataPriv.get( el, type ) === undefined ) {
- jQuery.event.add( el, type, returnTrue );
+ // Don't get/set properties on text, comment and attribute nodes
+ if ( nType === 3 || nType === 8 || nType === 2 ) {
+ return;
}
- return;
- }
- // Register the controller as a special universal handler for all event namespaces
- dataPriv.set( el, type, false );
- jQuery.event.add( el, type, {
- namespace: false,
- handler: function( event ) {
- var result,
- saved = dataPriv.get( this, type );
+ if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
- if ( ( event.isTrigger & 1 ) && this[ type ] ) {
+ // Fix name and attach hooks
+ name = jQuery.propFix[ name ] || name;
+ hooks = jQuery.propHooks[ name ];
+ }
- // Interrupt processing of the outer synthetic .trigger()ed event
- if ( !saved ) {
+ if ( value !== undefined ) {
+ if ( hooks && "set" in hooks &&
+ ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
+ return ret;
+ }
- // Store arguments for use when handling the inner native event
- // There will always be at least one argument (an event object), so this array
- // will not be confused with a leftover capture object.
- saved = slice.call( arguments );
- dataPriv.set( this, type, saved );
+ return ( elem[ name ] = value );
+ }
- // Trigger the native event and capture its result
- this[ type ]();
- result = dataPriv.get( this, type );
- dataPriv.set( this, type, false );
+ if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
+ return ret;
+ }
- if ( saved !== result ) {
+ return elem[ name ];
+ },
- // Cancel the outer synthetic event
- event.stopImmediatePropagation();
- event.preventDefault();
+ propHooks: {
+ tabIndex: {
+ get: function( elem ) {
- return result;
- }
+ // Support: IE <=9 - 11+
+ // elem.tabIndex doesn't always return the
+ // correct value when it hasn't been explicitly set
+ // Use proper attribute retrieval (trac-12072)
+ var tabindex = elem.getAttribute( "tabindex" );
- // If this is an inner synthetic event for an event with a bubbling surrogate
- // (focus or blur), assume that the surrogate already propagated from triggering
- // the native event and prevent that from happening again here.
- // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
- // bubbling surrogate propagates *after* the non-bubbling base), but that seems
- // less bad than duplication.
- } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {
- event.stopPropagation();
+ if ( tabindex ) {
+ return parseInt( tabindex, 10 );
}
- // If this is a native event triggered above, everything is now in order
- // Fire an inner synthetic event with the original arguments
- } else if ( saved ) {
+ if (
+ rfocusable.test( elem.nodeName ) ||
- // ...and capture the result
- dataPriv.set( this, type, jQuery.event.trigger(
- saved[ 0 ],
- saved.slice( 1 ),
- this
- ) );
+ // href-less anchor's `tabIndex` property value is `0` and
+ // the `tabindex` attribute value: `null`. We want `-1`.
+ rclickable.test( elem.nodeName ) && elem.href
+ ) {
+ return 0;
+ }
- // Abort handling of the native event by all jQuery handlers while allowing
- // native handlers on the same element to run. On target, this is achieved
- // by stopping immediate propagation just on the jQuery event. However,
- // the native event is re-wrapped by a jQuery one on each level of the
- // propagation so the only way to stop it for jQuery is to stop it for
- // everyone via native `stopPropagation()`. This is not a problem for
- // focus/blur which don't bubble, but it does also stop click on checkboxes
- // and radios. We accept this limitation.
- event.stopPropagation();
- event.isImmediatePropagationStopped = returnTrue;
+ return -1;
}
}
- } );
-}
-
-jQuery.removeEvent = function( elem, type, handle ) {
+ },
- // This "if" is needed for plain objects
- if ( elem.removeEventListener ) {
- elem.removeEventListener( type, handle );
+ propFix: {
+ "for": "htmlFor",
+ "class": "className"
}
-};
+} );
-jQuery.Event = function( src, props ) {
+// Support: IE <=11+
+// Accessing the selectedIndex property forces the browser to respect
+// setting selected on the option. The getter ensures a default option
+// is selected when in an optgroup. ESLint rule "no-unused-expressions"
+// is disabled for this code since it considers such accessions noop.
+if ( isIE ) {
+ jQuery.propHooks.selected = {
+ get: function( elem ) {
- // Allow instantiation without the 'new' keyword
- if ( !( this instanceof jQuery.Event ) ) {
- return new jQuery.Event( src, props );
- }
+ var parent = elem.parentNode;
+ if ( parent && parent.parentNode ) {
+ // eslint-disable-next-line no-unused-expressions
+ parent.parentNode.selectedIndex;
+ }
+ return null;
+ },
+ set: function( elem ) {
- // Event object
- if ( src && src.type ) {
- this.originalEvent = src;
- this.type = src.type;
- // Events bubbling up the document may have been marked as prevented
- // by a handler lower down the tree; reflect the correct value.
- this.isDefaultPrevented = src.defaultPrevented ||
- src.defaultPrevented === undefined &&
+ var parent = elem.parentNode;
+ if ( parent ) {
+ // eslint-disable-next-line no-unused-expressions
+ parent.selectedIndex;
- // Support: Android <=2.3 only
- src.returnValue === false ?
- returnTrue :
- returnFalse;
+ if ( parent.parentNode ) {
+ // eslint-disable-next-line no-unused-expressions
+ parent.parentNode.selectedIndex;
+ }
+ }
+ }
+ };
+}
- // Create target properties
- // Support: Safari <=6 - 7 only
- // Target should not be a text node (trac-504, trac-13143)
- this.target = ( src.target && src.target.nodeType === 3 ) ?
- src.target.parentNode :
- src.target;
+jQuery.each( [
+ "tabIndex",
+ "readOnly",
+ "maxLength",
+ "cellSpacing",
+ "cellPadding",
+ "rowSpan",
+ "colSpan",
+ "useMap",
+ "frameBorder",
+ "contentEditable"
+], function() {
+ jQuery.propFix[ this.toLowerCase() ] = this;
+} );
- this.currentTarget = src.currentTarget;
- this.relatedTarget = src.relatedTarget;
+// Strip and collapse whitespace according to HTML spec
+// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
+function stripAndCollapse( value ) {
+ var tokens = value.match( rnothtmlwhite ) || [];
+ return tokens.join( " " );
+}
- // Event type
- } else {
- this.type = src;
- }
+function getClass( elem ) {
+ return elem.getAttribute && elem.getAttribute( "class" ) || "";
+}
- // Put explicitly provided properties onto the event object
- if ( props ) {
- jQuery.extend( this, props );
+function classesToArray( value ) {
+ if ( Array.isArray( value ) ) {
+ return value;
}
+ if ( typeof value === "string" ) {
+ return value.match( rnothtmlwhite ) || [];
+ }
+ return [];
+}
- // Create a timestamp if incoming event doesn't have one
- this.timeStamp = src && src.timeStamp || Date.now();
+jQuery.fn.extend( {
+ addClass: function( value ) {
+ var classNames, cur, curValue, className, i, finalValue;
- // Mark it as fixed
- this[ jQuery.expando ] = true;
-};
+ if ( typeof value === "function" ) {
+ return this.each( function( j ) {
+ jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
+ } );
+ }
-// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
-// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
-jQuery.Event.prototype = {
- constructor: jQuery.Event,
- isDefaultPrevented: returnFalse,
- isPropagationStopped: returnFalse,
- isImmediatePropagationStopped: returnFalse,
- isSimulated: false,
+ classNames = classesToArray( value );
- preventDefault: function() {
- var e = this.originalEvent;
+ if ( classNames.length ) {
+ return this.each( function() {
+ curValue = getClass( this );
+ cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
- this.isDefaultPrevented = returnTrue;
+ if ( cur ) {
+ for ( i = 0; i < classNames.length; i++ ) {
+ className = classNames[ i ];
+ if ( cur.indexOf( " " + className + " " ) < 0 ) {
+ cur += className + " ";
+ }
+ }
- if ( e && !this.isSimulated ) {
- e.preventDefault();
+ // Only assign if different to avoid unneeded rendering.
+ finalValue = stripAndCollapse( cur );
+ if ( curValue !== finalValue ) {
+ this.setAttribute( "class", finalValue );
+ }
+ }
+ } );
}
+
+ return this;
},
- stopPropagation: function() {
- var e = this.originalEvent;
- this.isPropagationStopped = returnTrue;
+ removeClass: function( value ) {
+ var classNames, cur, curValue, className, i, finalValue;
- if ( e && !this.isSimulated ) {
- e.stopPropagation();
+ if ( typeof value === "function" ) {
+ return this.each( function( j ) {
+ jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
+ } );
}
- },
- stopImmediatePropagation: function() {
- var e = this.originalEvent;
- this.isImmediatePropagationStopped = returnTrue;
-
- if ( e && !this.isSimulated ) {
- e.stopImmediatePropagation();
+ if ( !arguments.length ) {
+ return this.attr( "class", "" );
}
- this.stopPropagation();
- }
-};
+ classNames = classesToArray( value );
-// Includes all common event props including KeyEvent and MouseEvent specific props
-jQuery.each( {
- altKey: true,
- bubbles: true,
- cancelable: true,
- changedTouches: true,
- ctrlKey: true,
- detail: true,
- eventPhase: true,
- metaKey: true,
- pageX: true,
- pageY: true,
- shiftKey: true,
- view: true,
- "char": true,
- code: true,
- charCode: true,
- key: true,
- keyCode: true,
- button: true,
- buttons: true,
- clientX: true,
- clientY: true,
- offsetX: true,
- offsetY: true,
- pointerId: true,
- pointerType: true,
- screenX: true,
- screenY: true,
- targetTouches: true,
- toElement: true,
- touches: true,
- which: true
-}, jQuery.event.addProp );
+ if ( classNames.length ) {
+ return this.each( function() {
+ curValue = getClass( this );
+
+ // This expression is here for better compressibility (see addClass)
+ cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
+
+ if ( cur ) {
+ for ( i = 0; i < classNames.length; i++ ) {
+ className = classNames[ i ];
+
+ // Remove *all* instances
+ while ( cur.indexOf( " " + className + " " ) > -1 ) {
+ cur = cur.replace( " " + className + " ", " " );
+ }
+ }
+
+ // Only assign if different to avoid unneeded rendering.
+ finalValue = stripAndCollapse( cur );
+ if ( curValue !== finalValue ) {
+ this.setAttribute( "class", finalValue );
+ }
+ }
+ } );
+ }
-jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) {
+ return this;
+ },
- function focusMappedHandler( nativeEvent ) {
- if ( document.documentMode ) {
+ toggleClass: function( value, stateVal ) {
+ var classNames, className, i, self;
- // Support: IE 11+
- // Attach a single focusin/focusout handler on the document while someone wants
- // focus/blur. This is because the former are synchronous in IE while the latter
- // are async. In other browsers, all those handlers are invoked synchronously.
+ if ( typeof value === "function" ) {
+ return this.each( function( i ) {
+ jQuery( this ).toggleClass(
+ value.call( this, i, getClass( this ), stateVal ),
+ stateVal
+ );
+ } );
+ }
+
+ if ( typeof stateVal === "boolean" ) {
+ return stateVal ? this.addClass( value ) : this.removeClass( value );
+ }
- // `handle` from private data would already wrap the event, but we need
- // to change the `type` here.
- var handle = dataPriv.get( this, "handle" ),
- event = jQuery.event.fix( nativeEvent );
- event.type = nativeEvent.type === "focusin" ? "focus" : "blur";
- event.isSimulated = true;
+ classNames = classesToArray( value );
- // First, handle focusin/focusout
- handle( nativeEvent );
+ if ( classNames.length ) {
+ return this.each( function() {
- // ...then, handle focus/blur
- //
- // focus/blur don't bubble while focusin/focusout do; simulate the former by only
- // invoking the handler at the lower level.
- if ( event.target === event.currentTarget ) {
+ // Toggle individual class names
+ self = jQuery( this );
- // The setup part calls `leverageNative`, which, in turn, calls
- // `jQuery.event.add`, so event handle will already have been set
- // by this point.
- handle( event );
- }
- } else {
+ for ( i = 0; i < classNames.length; i++ ) {
+ className = classNames[ i ];
- // For non-IE browsers, attach a single capturing handler on the document
- // while someone wants focusin/focusout.
- jQuery.event.simulate( delegateType, nativeEvent.target,
- jQuery.event.fix( nativeEvent ) );
+ // Check each className given, space separated list
+ if ( self.hasClass( className ) ) {
+ self.removeClass( className );
+ } else {
+ self.addClass( className );
+ }
+ }
+ } );
}
- }
- jQuery.event.special[ type ] = {
+ return this;
+ },
- // Utilize native event if possible so blur/focus sequence is correct
- setup: function() {
+ hasClass: function( selector ) {
+ var className, elem,
+ i = 0;
+
+ className = " " + selector + " ";
+ while ( ( elem = this[ i++ ] ) ) {
+ if ( elem.nodeType === 1 &&
+ ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
+ return true;
+ }
+ }
- var attaches;
+ return false;
+ }
+} );
- // Claim the first handler
- // dataPriv.set( this, "focus", ... )
- // dataPriv.set( this, "blur", ... )
- leverageNative( this, type, true );
+jQuery.fn.extend( {
+ val: function( value ) {
+ var hooks, ret, valueIsFunction,
+ elem = this[ 0 ];
- if ( document.documentMode ) {
+ if ( !arguments.length ) {
+ if ( elem ) {
+ hooks = jQuery.valHooks[ elem.type ] ||
+ jQuery.valHooks[ elem.nodeName.toLowerCase() ];
- // Support: IE 9 - 11+
- // We use the same native handler for focusin & focus (and focusout & blur)
- // so we need to coordinate setup & teardown parts between those events.
- // Use `delegateType` as the key as `type` is already used by `leverageNative`.
- attaches = dataPriv.get( this, delegateType );
- if ( !attaches ) {
- this.addEventListener( delegateType, focusMappedHandler );
+ if ( hooks &&
+ "get" in hooks &&
+ ( ret = hooks.get( elem, "value" ) ) !== undefined
+ ) {
+ return ret;
}
- dataPriv.set( this, delegateType, ( attaches || 0 ) + 1 );
- } else {
- // Return false to allow normal processing in the caller
- return false;
+ ret = elem.value;
+
+ // Handle cases where value is null/undef or number
+ return ret == null ? "" : ret;
}
- },
- trigger: function() {
- // Force setup before trigger
- leverageNative( this, type );
+ return;
+ }
- // Return non-false to allow normal event-path propagation
- return true;
- },
+ valueIsFunction = typeof value === "function";
- teardown: function() {
- var attaches;
+ return this.each( function( i ) {
+ var val;
- if ( document.documentMode ) {
- attaches = dataPriv.get( this, delegateType ) - 1;
- if ( !attaches ) {
- this.removeEventListener( delegateType, focusMappedHandler );
- dataPriv.remove( this, delegateType );
- } else {
- dataPriv.set( this, delegateType, attaches );
- }
+ if ( this.nodeType !== 1 ) {
+ return;
+ }
+
+ if ( valueIsFunction ) {
+ val = value.call( this, i, jQuery( this ).val() );
} else {
+ val = value;
+ }
- // Return false to indicate standard teardown should be applied
- return false;
+ // Treat null/undefined as ""; convert numbers to string
+ if ( val == null ) {
+ val = "";
+
+ } else if ( typeof val === "number" ) {
+ val += "";
+
+ } else if ( Array.isArray( val ) ) {
+ val = jQuery.map( val, function( value ) {
+ return value == null ? "" : value + "";
+ } );
}
- },
- // Suppress native focus or blur if we're currently inside
- // a leveraged native-event stack
- _default: function( event ) {
- return dataPriv.get( event.target, type );
- },
+ hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
- delegateType: delegateType
- };
+ // If set returns undefined, fall back to normal setting
+ if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
+ this.value = val;
+ }
+ } );
+ }
+} );
- // Support: Firefox <=44
- // Firefox doesn't have focus(in | out) events
- // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
- //
- // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
- // focus(in | out) events fire after focus & blur events,
- // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
- // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
- //
- // Support: IE 9 - 11+
- // To preserve relative focusin/focus & focusout/blur event order guaranteed on the 3.x branch,
- // attach a single handler for both events in IE.
- jQuery.event.special[ delegateType ] = {
- setup: function() {
+jQuery.extend( {
+ valHooks: {
+ select: {
+ get: function( elem ) {
+ var value, option, i,
+ options = elem.options,
+ index = elem.selectedIndex,
+ one = elem.type === "select-one",
+ values = one ? null : [],
+ max = one ? index + 1 : options.length;
- // Handle: regular nodes (via `this.ownerDocument`), window
- // (via `this.document`) & document (via `this`).
- var doc = this.ownerDocument || this.document || this,
- dataHolder = document.documentMode ? this : doc,
- attaches = dataPriv.get( dataHolder, delegateType );
+ if ( index < 0 ) {
+ i = max;
- // Support: IE 9 - 11+
- // We use the same native handler for focusin & focus (and focusout & blur)
- // so we need to coordinate setup & teardown parts between those events.
- // Use `delegateType` as the key as `type` is already used by `leverageNative`.
- if ( !attaches ) {
- if ( document.documentMode ) {
- this.addEventListener( delegateType, focusMappedHandler );
} else {
- doc.addEventListener( type, focusMappedHandler, true );
+ i = one ? index : 0;
}
- }
- dataPriv.set( dataHolder, delegateType, ( attaches || 0 ) + 1 );
- },
- teardown: function() {
- var doc = this.ownerDocument || this.document || this,
- dataHolder = document.documentMode ? this : doc,
- attaches = dataPriv.get( dataHolder, delegateType ) - 1;
- if ( !attaches ) {
- if ( document.documentMode ) {
- this.removeEventListener( delegateType, focusMappedHandler );
- } else {
- doc.removeEventListener( type, focusMappedHandler, true );
+ // Loop through all the selected options
+ for ( ; i < max; i++ ) {
+ option = options[ i ];
+
+ if ( option.selected &&
+
+ // Don't return options that are disabled or in a disabled optgroup
+ !option.disabled &&
+ ( !option.parentNode.disabled ||
+ !nodeName( option.parentNode, "optgroup" ) ) ) {
+
+ // Get the specific value for the option
+ value = jQuery( option ).val();
+
+ // We don't need an array for one selects
+ if ( one ) {
+ return value;
+ }
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
}
- dataPriv.remove( dataHolder, delegateType );
- } else {
- dataPriv.set( dataHolder, delegateType, attaches );
- }
- }
- };
-} );
-// Create mouseenter/leave events using mouseover/out and event-time checks
-// so that event delegation works in jQuery.
-// Do the same for pointerenter/pointerleave and pointerover/pointerout
-//
-// Support: Safari 7 only
-// Safari sends mouseenter too often; see:
-// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
-// for the description of the bug (it existed in older Chrome versions as well).
-jQuery.each( {
- mouseenter: "mouseover",
- mouseleave: "mouseout",
- pointerenter: "pointerover",
- pointerleave: "pointerout"
-}, function( orig, fix ) {
- jQuery.event.special[ orig ] = {
- delegateType: fix,
- bindType: fix,
+ return values;
+ },
- handle: function( event ) {
- var ret,
- target = this,
- related = event.relatedTarget,
- handleObj = event.handleObj;
+ set: function( elem, value ) {
+ var optionSet, option,
+ options = elem.options,
+ values = jQuery.makeArray( value ),
+ i = options.length;
- // For mouseenter/leave call the handler if related is outside the target.
- // NB: No relatedTarget if the mouse left/entered the browser window
- if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
- event.type = handleObj.origType;
- ret = handleObj.handler.apply( this, arguments );
- event.type = fix;
+ while ( i-- ) {
+ option = options[ i ];
+
+ if ( ( option.selected =
+ jQuery.inArray( jQuery( option ).val(), values ) > -1
+ ) ) {
+ optionSet = true;
+ }
+ }
+
+ // Force browsers to behave consistently when non-matching value is set
+ if ( !optionSet ) {
+ elem.selectedIndex = -1;
+ }
+ return values;
}
- return ret;
}
- };
+ }
} );
-jQuery.fn.extend( {
+if ( isIE ) {
+ jQuery.valHooks.option = {
+ get: function( elem ) {
- on: function( types, selector, data, fn ) {
- return on( this, types, selector, data, fn );
- },
- one: function( types, selector, data, fn ) {
- return on( this, types, selector, data, fn, 1 );
- },
- off: function( types, selector, fn ) {
- var handleObj, type;
- if ( types && types.preventDefault && types.handleObj ) {
+ var val = elem.getAttribute( "value" );
+ return val != null ?
+ val :
- // ( event ) dispatched jQuery.Event
- handleObj = types.handleObj;
- jQuery( types.delegateTarget ).off(
- handleObj.namespace ?
- handleObj.origType + "." + handleObj.namespace :
- handleObj.origType,
- handleObj.selector,
- handleObj.handler
- );
- return this;
+ // Support: IE <=10 - 11+
+ // option.text throws exceptions (trac-14686, trac-14858)
+ // Strip and collapse whitespace
+ // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
+ stripAndCollapse( jQuery.text( elem ) );
}
- if ( typeof types === "object" ) {
+ };
+}
- // ( types-object [, selector] )
- for ( type in types ) {
- this.off( type, selector, types[ type ] );
+// Radios and checkboxes getter/setter
+jQuery.each( [ "radio", "checkbox" ], function() {
+ jQuery.valHooks[ this ] = {
+ set: function( elem, value ) {
+ if ( Array.isArray( value ) ) {
+ return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
}
- return this;
}
- if ( selector === false || typeof selector === "function" ) {
+ };
+} );
- // ( types [, fn] )
- fn = selector;
+var rcheckableType = /^(?:checkbox|radio)$/i;
+
+var rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
+
+function returnTrue() {
+ return true;
+}
+
+function returnFalse() {
+ return false;
+}
+
+function on( elem, types, selector, data, fn, one ) {
+ var origFn, type;
+
+ // Types can be a map of types/handlers
+ if ( typeof types === "object" ) {
+
+ // ( types-Object, selector, data )
+ if ( typeof selector !== "string" ) {
+
+ // ( types-Object, data )
+ data = data || selector;
selector = undefined;
}
- if ( fn === false ) {
- fn = returnFalse;
+ for ( type in types ) {
+ on( elem, type, selector, data, types[ type ], one );
}
- return this.each( function() {
- jQuery.event.remove( this, types, fn, selector );
- } );
+ return elem;
}
-} );
+ if ( data == null && fn == null ) {
-var
+ // ( types, fn )
+ fn = selector;
+ data = selector = undefined;
+ } else if ( fn == null ) {
+ if ( typeof selector === "string" ) {
- // Support: IE <=10 - 11, Edge 12 - 13 only
- // In IE/Edge using regex groups here causes severe slowdowns.
- // See https://connect.microsoft.com/IE/feedback/details/1736512/
- rnoInnerhtml = /
+
diff --git a/src/static/templates/admin/users.hbs b/src/static/templates/admin/users.hbs
index 52458012..73f0cbc8 100644
--- a/src/static/templates/admin/users.hbs
+++ b/src/static/templates/admin/users.hbs
@@ -153,7 +153,7 @@
-
+