diff --git a/README.Rmd b/README.Rmd index 819e0773..7e973785 100644 --- a/README.Rmd +++ b/README.Rmd @@ -4,7 +4,9 @@ output: github_document -```{r, child='index.md'} + + +```{r, child='pkgdown/index.md'} ``` diff --git a/README.md b/README.md index c91a7888..37ff818b 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,36 @@ +--- +output: github_document +--- + + + # Mendelian randomization with GWAS summary data - [![R-CMD-check](https://github.com/MRCIEU/TwoSampleMR/actions/workflows/check-full.yaml/badge.svg)](https://github.com/MRCIEU/TwoSampleMR/actions/workflows/check-full.yaml) -[![Lifecycle: -experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html) -[![DOI](https://zenodo.org/badge/49515156.svg)](https://zenodo.org/badge/latestdoi/49515156) -[![Codecov test -coverage](https://codecov.io/gh/MRCIEU/TwoSampleMR/branch/master/graph/badge.svg)](https://app.codecov.io/gh/MRCIEU/TwoSampleMR?branch=master) -[![TwoSampleMR status -badge](https://mrcieu.r-universe.dev/badges/TwoSampleMR)](https://mrcieu.r-universe.dev/TwoSampleMR) +[![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html) [![DOI](https://zenodo.org/badge/49515156.svg)](https://zenodo.org/badge/latestdoi/49515156) +[![Codecov test coverage](https://codecov.io/gh/MRCIEU/TwoSampleMR/branch/master/graph/badge.svg)](https://app.codecov.io/gh/MRCIEU/TwoSampleMR?branch=master) +[![TwoSampleMR status badge](https://mrcieu.r-universe.dev/badges/TwoSampleMR)](https://mrcieu.r-universe.dev/TwoSampleMR) -A package for performing Mendelian randomization using GWAS summary -data. It uses the [IEU OpenGWAS database](https://gwas.mrcieu.ac.uk/) to -obtain data automatically, and a wide range of methods to run the -analysis. +A package for performing Mendelian randomization using GWAS summary data. It uses the [IEU OpenGWAS database](https://gwas.mrcieu.ac.uk/) to obtain data automatically, and a wide range of methods to run the analysis. -## January 2020 major update +## January 2020 major update -**We have made substantial changes to the package, database and -reference panels.** For full details of the changes, please visit - +**We have made substantial changes to the package, database and reference panels.** For full details of the changes, please visit ## Installation -Users running Windows and macOS, to install the latest version of -TwoSampleMR please install from our MRC IEU r-universe +Users running Windows and macOS, to install the latest version of TwoSampleMR please install from our MRC IEU r-universe -``` r +```r install.packages("TwoSampleMR", repos = c("https://mrcieu.r-universe.dev", "https://cloud.r-project.org")) ``` -Users running Linux or WebR please see the [following -instructions](https://github.com/MRCIEU/mrcieu.r-universe.dev#readme). +Users running Linux or WebR please see the [following instructions](https://github.com/MRCIEU/mrcieu.r-universe.dev#readme). To update the package run the same command again. @@ -47,18 +41,14 @@ install.packages("remotes") remotes::install_github("MRCIEU/TwoSampleMR") ``` -To update the package just run the -`remotes::install_github("MRCIEU/TwoSampleMR")` command again. +To update the package just run the `remotes::install_github("MRCIEU/TwoSampleMR")` command again. ## Docker -A multi-platform docker image containing R with the TwoSampleMR package -pre-installed (for both x86_64 and ARM computers) is available here: - +A multi-platform docker image containing R with the TwoSampleMR package pre-installed (for both x86_64 and ARM computers) is available here: https://hub.docker.com/r/mrcieu/twosamplemr ## Documentation -**Full documentation available here:** - +**Full documentation available here:** https://mrcieu.github.io/TwoSampleMR/ diff --git a/docs/404.html b/docs/404.html new file mode 100644 index 00000000..622eab58 --- /dev/null +++ b/docs/404.html @@ -0,0 +1,102 @@ + + + + + + + +Page not found (404) • TwoSampleMR + + + + + + + + + + + + + + + + Skip to contents + + +
+
+
+ +Content not found. Please use links in the navbar. + +
+
+ + +
+ + + +
+
+ + + + + + + diff --git a/docs/LICENSE-text.html b/docs/LICENSE-text.html new file mode 100644 index 00000000..59891d32 --- /dev/null +++ b/docs/LICENSE-text.html @@ -0,0 +1,72 @@ + +License • TwoSampleMR + Skip to contents + + +
+
+
+ +
YEAR: 2019
+COPYRIGHT HOLDER: Gibran Hemani
+
+ +
+ + +
+ + + +
+ + + + + + + diff --git a/docs/LICENSE.html b/docs/LICENSE.html new file mode 100644 index 00000000..09261b0f --- /dev/null +++ b/docs/LICENSE.html @@ -0,0 +1,76 @@ + +MIT License • TwoSampleMR + Skip to contents + + +
+
+
+ +
+ +

Copyright (c) 2019 Gibran Hemani

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

+

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
+ +
+ + +
+ + + +
+ + + + + + + diff --git a/docs/apple-touch-icon.png b/docs/apple-touch-icon.png new file mode 100644 index 00000000..e9a3df21 Binary files /dev/null and b/docs/apple-touch-icon.png differ diff --git a/docs/articles/exposure.html b/docs/articles/exposure.html new file mode 100644 index 00000000..6b82a835 --- /dev/null +++ b/docs/articles/exposure.html @@ -0,0 +1,691 @@ + + + + + + + +Exposure data • TwoSampleMR + + + + + + + + + + + + + + + Skip to contents + + +
+ + + + +
+
+ + + + +
+

Introduction +

+

A data frame of the instruments for an exposure is required. Each +line has the information for one variant for one exposure. The minimum +information required for MR analysis is the following:

+
    +
  • +SNP - rs ID
  • +
  • +beta - The effect size. If the trait is binary then +log(OR) should be used
  • +
  • +se - The standard error of the effect size
  • +
  • +effect_allele - The allele of the SNP which has the +effect marked in beta +
  • +
+

Other information that is useful for MR can also be provided:

+
    +
  • +other_allele - The non-effect allele
  • +
  • +eaf - The effect allele frequency
  • +
  • +Phenotype - The name of the phenotype for which the SNP +has an effect
  • +
+

You can also provide the following extra information:

+
    +
  • +chr - Physical position of variant (chromosome)
  • +
  • +position - Physical position of variant (position)
  • +
  • +samplesize - Sample size for estimating the effect +size
  • +
  • +ncase - Number of cases
  • +
  • +ncontrol - Number of controls
  • +
  • +pval - The P-value for the SNP’s association with the +exposure
  • +
  • +units - The units in which the effects are +presented
  • +
  • +gene - The gene or other annotation for the the +SNP
  • +
+
+
+

Reading in from a file +

+

The data can be read in from a text file using the +read_exposure_data function. The file must have a header +with column names corresponding to the columns described above.

+
+

Example 1: The default column names are used +

+

An example of a text file with the default column names is provided +as part of the package, the first few rows look like this:

+
Phenotype SNP beta se effect_allele other_allele eaf pval units gene samplesize
+BMI rs10767664 0.19 0.0306122448979592 A T 0.78 5e-26 kg/m2 BDNF 225238
+BMI rs13078807 0.1 0.0204081632653061 G A 0.2 4e-11 kg/m2 CADM2 221431
+BMI rs1514175 0.07 0.0204081632653061 A G 0.43 8e-14 kg/m2 TNNI3K 207641
+BMI rs1558902 0.39 0.0204081632653061 A T 0.42 5e-120 kg/m2 FTO 222476
+BMI rs10968576 0.11 0.0204081632653061 G A 0.31 3e-13 kg/m2 LRRN6C 247166
+BMI rs2241423 0.13 0.0204081632653061 G A 0.78 1e-18 kg/m2 LBXCOR1 227886
+

The exact path to the file will be different on everyone’s computer, +but it can be located like this:

+
+bmi_file <- system.file("extdata", "bmi.txt", package = "TwoSampleMR")
+

You can read the data in like this:

+
+bmi_exp_dat <- read_exposure_data(bmi_file)
+head(bmi_exp_dat)
+#>          SNP beta.exposure se.exposure effect_allele.exposure
+#> 1 rs10767664          0.19  0.03061224                      A
+#> 2 rs13078807          0.10  0.02040816                      G
+#> 3  rs1514175          0.07  0.02040816                      A
+#> 4  rs1558902          0.39  0.02040816                      A
+#> 5 rs10968576          0.11  0.02040816                      G
+#> 6  rs2241423          0.13  0.02040816                      G
+#>   other_allele.exposure eaf.exposure pval.exposure units.exposure gene.exposure
+#> 1                     T         0.78         5e-26          kg/m2          BDNF
+#> 2                     A         0.20         4e-11          kg/m2         CADM2
+#> 3                     G         0.43         8e-14          kg/m2        TNNI3K
+#> 4                     T         0.42        5e-120          kg/m2           FTO
+#> 5                     A         0.31         3e-13          kg/m2        LRRN6C
+#> 6                     A         0.78         1e-18          kg/m2       LBXCOR1
+#>   samplesize.exposure exposure mr_keep.exposure pval_origin.exposure
+#> 1              225238      BMI             TRUE             reported
+#> 2              221431      BMI             TRUE             reported
+#> 3              207641      BMI             TRUE             reported
+#> 4              222476      BMI             TRUE             reported
+#> 5              247166      BMI             TRUE             reported
+#> 6              227886      BMI             TRUE             reported
+#>   units.exposure_dat id.exposure data_source.exposure
+#> 1              kg/m2      ImbABK             textfile
+#> 2              kg/m2      ImbABK             textfile
+#> 3              kg/m2      ImbABK             textfile
+#> 4              kg/m2      ImbABK             textfile
+#> 5              kg/m2      ImbABK             textfile
+#> 6              kg/m2      ImbABK             textfile
+

The output from this function is a new data frame with standardised +column names:

+
    +
  • SNP
  • +
  • exposure
  • +
  • beta.exposure
  • +
  • se.exposure
  • +
  • effect_allele.exposure
  • +
  • other_allele.exposure
  • +
  • eaf.exposure
  • +
  • mr_keep.exposure
  • +
  • pval.exposure
  • +
  • pval_origin.exposure
  • +
  • id.exposure
  • +
  • data_source.exposure
  • +
  • units.exposure
  • +
  • gene.exposure
  • +
  • samplesize.exposure
  • +
+

The function attempts to match the columns to the ones it expects. It +also checks that the data type is as expected.

+

If the required data for MR to be performed is not present (SNP name, +effect size, standard error, effect allele) for a particular SNP, then +the column mr_keep.exposure will be FALSE.

+
+
+

Example 2: The text file has non-default column names +

+

If the text file does not have default column names, this can still +be read in as follows. Here are the first few rows of an example:

+
rsid,effect,SE,a1,a2,a1_freq,p-value,Units,Gene,n
+rs10767664,0.19,0.030612245,A,T,0.78,5.00E-26,kg/m2,BDNF,225238
+rs13078807,0.1,0.020408163,G,A,0.2,4.00E-11,kg/m2,CADM2,221431
+rs1514175,0.07,0.020408163,A,G,0.43,8.00E-14,kg/m2,TNNI3K,207641
+rs1558902,0.39,0.020408163,A,T,0.42,5.00E-120,kg/m2,FTO,222476
+

Note that this is a CSV file, with commas separating fields. The file +is located here:

+
+bmi2_file <- system.file("extdata/bmi.csv", package = "TwoSampleMR")
+

To read in this data:

+
+bmi_exp_dat <- read_exposure_data(
+    filename = bmi2_file,
+    sep = ",",
+    snp_col = "rsid",
+    beta_col = "effect",
+    se_col = "SE",
+    effect_allele_col = "a1",
+    other_allele_col = "a2",
+    eaf_col = "a1_freq",
+    pval_col = "p-value",
+    units_col = "Units",
+    gene_col = "Gene",
+    samplesize_col = "n"
+)
+#> No phenotype name specified, defaulting to 'exposure'.
+head(bmi_exp_dat)
+#>          SNP beta.exposure se.exposure effect_allele.exposure
+#> 1 rs10767664          0.19  0.03061224                      A
+#> 2 rs13078807          0.10  0.02040816                      G
+#> 3  rs1514175          0.07  0.02040816                      A
+#> 4  rs1558902          0.39  0.02040816                      A
+#> 5 rs10968576          0.11  0.02040816                      G
+#> 6  rs2241423          0.13  0.02040816                      G
+#>   other_allele.exposure eaf.exposure pval.exposure units.exposure gene.exposure
+#> 1                     T         0.78         5e-26          kg/m2          BDNF
+#> 2                     A         0.20         4e-11          kg/m2         CADM2
+#> 3                     G         0.43         8e-14          kg/m2        TNNI3K
+#> 4                     T         0.42        5e-120          kg/m2           FTO
+#> 5                     A         0.31         3e-13          kg/m2        LRRN6C
+#> 6                     A         0.78         1e-18          kg/m2       LBXCOR1
+#>   samplesize.exposure exposure mr_keep.exposure pval_origin.exposure
+#> 1              225238 exposure             TRUE             reported
+#> 2              221431 exposure             TRUE             reported
+#> 3              207641 exposure             TRUE             reported
+#> 4              222476 exposure             TRUE             reported
+#> 5              247166 exposure             TRUE             reported
+#> 6              227886 exposure             TRUE             reported
+#>   units.exposure_dat id.exposure data_source.exposure
+#> 1              kg/m2      Ku3B84             textfile
+#> 2              kg/m2      Ku3B84             textfile
+#> 3              kg/m2      Ku3B84             textfile
+#> 4              kg/m2      Ku3B84             textfile
+#> 5              kg/m2      Ku3B84             textfile
+#> 6              kg/m2      Ku3B84             textfile
+

If the Phenotype column is not provided (as is the case +in this example) then it will assume that the phenotype’s name is simply +“exposure”. This is entered in the exposure column. It can +be renamed manually:

+
+bmi_exp_dat$exposure <- "BMI"
+
+
+
+

Using an existing data frame +

+

If the data already exists as a data frame in R then it can be +converted into the correct format using the format_data() +function. For example, here is some randomly created data:

+
+random_df <- data.frame(
+  SNP = c("rs1", "rs2"),
+  beta = c(1, 2),
+  se = c(1, 2),
+  effect_allele = c("A", "T")
+)
+random_df
+#>   SNP beta se effect_allele
+#> 1 rs1    1  1             A
+#> 2 rs2    2  2             T
+

This can be formatted like so:

+
+random_exp_dat <- format_data(random_df, type = "exposure")
+#> No phenotype name specified, defaulting to 'exposure'.
+#> Warning in format_data(random_df, type = "exposure"): The following columns are not present but are helpful for harmonisation
+#> other_alleleeaf
+#> Inferring p-values
+random_exp_dat
+#>   SNP beta.exposure se.exposure effect_allele.exposure exposure
+#> 1 rs1             1           1                      A exposure
+#> 2 rs2             2           2                      T exposure
+#>   mr_keep.exposure pval.exposure pval_origin.exposure id.exposure
+#> 1             TRUE     0.3173105             inferred      4nec1Z
+#> 2             TRUE     0.3173105             inferred      4nec1Z
+#>   other_allele.exposure eaf.exposure
+#> 1                    NA           NA
+#> 2                    NA           NA
+
+
+

Obtaining instruments from existing catalogues +

+

A number of sources of instruments have already been curated and are +available for use. They are provided as data objects in the +MRInstruments package. To install:

+
+remotes::install_github("MRCIEU/MRInstruments")
+

This package contains a number of data.frames, each of which is a +repository of SNP-trait associations. How to access the data frames is +detailed below:

+
+

GWAS catalog +

+

The NHGRI-EBI GWAS catalog contains a catalog of significant +associations obtained from GWASs. This version of the data is filtered +and harmonised to contain associations that have the required data to +perform MR, to ensure that the units used to report effect sizes from a +particular study are all the same, and other data cleaning +operations.

+

To use the GWAS catalog:

+
+library(MRInstruments)
+data(gwas_catalog)
+head(gwas_catalog)
+#>                                                 Phenotype_simple
+#> 1                           Eosinophil percentage of white cells
+#> 2                                              Eosinophil counts
+#> 3 Medication use (agents acting on the renin-angiotensin system)
+#> 4                                       Post bronchodilator FEV1
+#> 5                         DNA methylation variation (age effect)
+#> 6                                         Ankylosing spondylitis
+#>                                                MAPPED_TRAIT_EFO
+#> 1                           eosinophil percentage of leukocytes
+#> 2                                              eosinophil count
+#> 3 Agents acting on the renin-angiotensin system use measurement
+#> 4          forced expiratory volume, response to bronchodilator
+#> 5                                               DNA methylation
+#> 6                                        ankylosing spondylitis
+#>                                                              MAPPED_TRAIT_EFO_URI
+#> 1                                            http://www.ebi.ac.uk/efo/EFO_0007991
+#> 2                                            http://www.ebi.ac.uk/efo/EFO_0004842
+#> 3                                            http://www.ebi.ac.uk/efo/EFO_0009931
+#> 4 http://www.ebi.ac.uk/efo/EFO_0004314, http://purl.obolibrary.org/obo/GO_0097366
+#> 5                                       http://purl.obolibrary.org/obo/GO_0006306
+#> 6                                            http://www.ebi.ac.uk/efo/EFO_0003898
+#>                                                                                                                                                Initial_sample_description
+#> 1                                                                                                                                   172,378 European ancestry individuals
+#> 2                                                                                                                                   172,275 European ancestry individuals
+#> 3                                                                                                      62,752 European ancestry cases, 174,778 European ancestry controls
+#> 4 10,094 European ancestry current and former smoker individuals, 3,260 African American current and former smoker individuals, 178 current and former smoker individuals
+#> 5                                                                                                                                                   Up to 954 individuals
+#> 6                                                    921 Turkish ancestry cases, 907 Turkish ancestry controls, 422 Iranian ancestry cases, 754 Iranian ancestry controls
+#>   Replication_sample_description STUDY.ACCESSION
+#> 1                           <NA>      GCST004600
+#> 2                           <NA>      GCST004606
+#> 3                           <NA>      GCST007930
+#> 4                           <NA>      GCST003262
+#> 5                           <NA>      GCST006660
+#> 6                           <NA>      GCST007844
+#>                                                        Phenotype Phenotype_info
+#> 1                           Eosinophil percentage of white cells               
+#> 2                                              Eosinophil counts               
+#> 3 Medication use (agents acting on the renin-angiotensin system)               
+#> 4                                       Post bronchodilator FEV1               
+#> 5                         DNA methylation variation (age effect)               
+#> 6                                         Ankylosing spondylitis               
+#>   PubmedID   Author Year        SNP chr bp_ens_GRCh38   Region       gene
+#> 1 27863252 Astle WJ 2016  rs1000005  21      33060745 21q22.11 AP000282.2
+#> 2 27863252 Astle WJ 2016  rs1000005  21      33060745 21q22.11 AP000282.2
+#> 3 31015401     Wu Y 2019  rs1000010   3      11562645   3p25.3      VGLL4
+#> 4 26634245  Lutz SM 2015 rs10000225   4     144312789  4q31.21 Intergenic
+#> 5 30348214  Zhang Q 2018 rs10000513   4     160334994   4q32.1         NR
+#> 6 30946743     Li Z 2019 rs10000518   4      11502867  4p15.33     HS3ST1
+#>               Gene_ens effect_allele other_allele        beta          se  pval
+#> 1 AP000282.2,LINC00945             C            G -0.02652552 0.003826531 2e-13
+#> 2 AP000282.2,LINC00945             C            G -0.02481715 0.003571429 7e-12
+#> 3                                  G            A -0.03724189 0.006377551 6e-09
+#> 4           Intergenic             A            T -0.04400000 0.009420188 3e-06
+#> 5                   NR          <NA>         <NA>          NA          NA 4e-08
+#> 6                                  G            A  0.73396926          NA 6e-06
+#>              units      eaf date_added_to_MRBASE
+#> 1    unit decrease 0.589400           2019-08-29
+#> 2    unit decrease 0.589400           2019-08-29
+#> 3    unit decrease 0.351806           2019-08-29
+#> 4 NR unit decrease 0.350000           2019-08-29
+#> 5             <NA>       NA           2019-08-29
+#> 6             <NA>       NA           2019-08-29
+

For example, to obtain instruments for body mass index using the +Speliotes et al 2010 study:

+
+bmi_gwas <-
+  subset(gwas_catalog,
+         grepl("Speliotes", Author) &
+           Phenotype == "Body mass index")
+bmi_exp_dat <- format_data(bmi_gwas)
+
+
+

Metabolites +

+

Independent top hits from GWASs on 121 metabolites in whole blood are +stored in the metab_qtls data object. Use +?metab_qtls to get more information.

+
+data(metab_qtls)
+head(metab_qtls)
+#>   phenotype chromosome  position       SNP effect_allele other_allele      eaf
+#> 1     AcAce          8   9181395 rs2169387             G            A 0.870251
+#> 2     AcAce         11 116648917  rs964184             C            G 0.857715
+#> 3       Ace          6  12042473 rs6933521             C            T 0.120256
+#> 4       Ala          2  27730940 rs1260326             C            T 0.638817
+#> 5       Ala          2  65220910 rs2160387             C            T 0.403170
+#> 6       Ala         12  47201814 rs4554975             G            A 0.644059
+#>        beta       se     pval n_studies     n
+#> 1  0.085630 0.015451 3.61e-08        11 19257
+#> 2 -0.096027 0.014624 6.71e-11        11 19261
+#> 3 -0.091667 0.015885 8.10e-09        14 24742
+#> 4 -0.104582 0.009940 7.40e-26        13 22569
+#> 5 -0.071001 0.009603 1.49e-13        14 24793
+#> 6 -0.069135 0.009598 6.12e-13        14 24792
+

For example, to obtain instruments for Alanine:

+
+ala_exp_dat <- format_metab_qtls(subset(metab_qtls, phenotype == "Ala"))
+
+
+

Proteins +

+

Independent top hits from GWASs on 47 protein levels in whole blood +are stored in the proteomic_qtls data object. Use +?proteomic_qtls to get more information.

+
+data(proteomic_qtls)
+head(proteomic_qtls)
+#>   analyte chr  position        SNP  gene location annotation other_allele
+#> 1   CFHR1   1 196698945 rs12144939   CFH      cis   missense            T
+#> 2    IL6r   1 154425456 rs12126142  IL6R      cis   missense            A
+#> 3   ApoA4  11 116677723  rs1263167 APOA4      cis intergenic            G
+#> 4    SELE   9 136149399   rs507666   ABO    trans   intronic            A
+#> 5 FetuinA   3 186335941  rs2070633  AHSG      cis   missense            T
+#> 6     ACE  17  61566031     rs4343   ACE      cis synonymous            A
+#>   effect_allele   eaf   maf      pval   beta         se
+#> 1             G 0.643 0.357 8.99e-143 -1.108 0.04355258
+#> 2             G 0.608 0.392 1.81e-106  0.850 0.03878364
+#> 3             A 0.803 0.197  2.64e-54 -0.919 0.05922332
+#> 4             G 0.809 0.191  1.01e-52 -0.882 0.05771545
+#> 5             C 0.676 0.324  2.88e-44 -0.629 0.04506925
+#> 6             G 0.508 0.492  6.66e-44  0.493 0.03547679
+

For example, to obtain instruments for the ApoH protein:

+
+apoh_exp_dat <-
+  format_proteomic_qtls(subset(proteomic_qtls, analyte == "ApoH"))
+
+
+

Gene expression levels +

+

Independent top hits from GWASs on 32432 gene identifiers and in 44 +tissues are available from the GTEX study in gtex_eqtl. Use +?gtex_eqtl to get more information.

+
+data(gtex_eqtl)
+head(gtex_eqtl)
+#>                 tissue     gene_name gene_start         SNP snp_position
+#> 1 Adipose Subcutaneous RP4-669L17.10   1:317720   rs2519065     1:787151
+#> 2 Adipose Subcutaneous RP11-206L10.1   1:661611  rs11804171     1:723819
+#> 3 Adipose Subcutaneous RP11-206L10.3   1:677193 rs149110718     1:759227
+#> 4 Adipose Subcutaneous RP11-206L10.2   1:700306 rs148649543     1:752796
+#> 5 Adipose Subcutaneous RP11-206L10.9   1:714150  rs12184279     1:717485
+#> 6 Adipose Subcutaneous RP11-206L10.8   1:736259  rs10454454     1:754954
+#>   effect_allele other_allele      beta        se        pval   n
+#> 1             A            G  0.551788 0.0747180 2.14627e-12 298
+#> 2             A            T -0.917475 0.1150060 4.99967e-14 298
+#> 3             T            C  0.807571 0.1776530 8.44694e-06 298
+#> 4             T            C  0.745393 0.0958531 1.82660e-13 298
+#> 5             A            C  1.927250 0.2247390 9.55098e-16 298
+#> 6             A            G  1.000400 0.1787470 5.61079e-08 298
+

For example, to obtain instruments for the IRAK1BP1 gene expression +levels in subcutaneous adipose tissue:

+
+irak1bp1_exp_dat <-
+  format_gtex_eqtl(subset(
+    gtex_eqtl,
+    gene_name == "IRAK1BP1" & tissue == "Adipose Subcutaneous"
+  ))
+#> Warning in format_data(gtex_eqtl_subset, type = type, phenotype_col = type, : The following columns are not present but are helpful for harmonisation
+#> eaf
+#> Inferring p-values
+
+
+

DNA methylation levels +

+

Independent top hits from GWASs on 0 DNA methylation levels in whole +blood across 5 time points are available from the ARIES study in +aries_mqtl. Use ?aries_mqtl to get more +information.

+
+data(aries_mqtl)
+head(aries_mqtl)
+#>          SNP timepoint        cpg    beta        pval         se snp_chr
+#> 1 esv2656832         1 cg21826606  0.3459 1.60408e-26 0.03265336       1
+#> 2 esv2658098         1 cg22681495 -0.6263 1.55765e-66 0.03643240      15
+#> 3 esv2660043         1 cg24276624 -0.5772 3.16370e-26 0.05481823      11
+#> 4 esv2660043         1 cg11157765 -0.5423 1.33928e-22 0.05583777      11
+#> 5 esv2660673         1 cg05832925 -0.5919 2.88011e-50 0.03982467      11
+#> 6 esv2660769         1 cg05859533 -0.6224 1.49085e-58 0.03868158      16
+#>    snp_pos effect_allele other_allele    eaf   sex   age    units
+#> 1 25591901             I            R 0.3974 mixed Birth SD units
+#> 2 86057007             D            R 0.2076 mixed Birth SD units
+#> 3 69982552             D            R 0.1450 mixed Birth SD units
+#> 4 69982552             D            R 0.1450 mixed Birth SD units
+#> 5 74024905             D            R 0.1671 mixed Birth SD units
+#> 6 57725395             D            R 0.2136 mixed Birth SD units
+#>   island_location cpg_chr  cpg_pos    gene gene_location cis_trans
+#> 1         N_Shore       1 25593055                             cis
+#> 2                      15 86058755  AKAP13          Body       cis
+#> 3                      11 69982941    ANO1          Body       cis
+#> 4                      11 69982996    ANO1          Body       cis
+#> 5         S_Shelf      11 74026371                             cis
+#> 6                      16 57727230 CCDC135       TSS1500       cis
+

For example, to obtain instruments for cg25212131 CpG DNA methylation +levels in at birth:

+
+cg25212131_exp_dat <-
+  format_aries_mqtl(subset(aries_mqtl, cpg == "cg25212131" &
+                             age == "Birth"))
+
+
+

IEU OpenGWAS database +

+

The IEU OpenGWAS database contains the entire summary statistics for +thousands of GWASs. You can browse them here: https://gwas.mrcieu.ac.uk/

+

You can use this database to define the instruments for a particular +exposure. You can also use this database to obtain the effects for +constructing polygenic risk scores using different p-value +thresholds.

+

You can check the status of the API:

+
+ieugwasr::api_status()
+

To obtain a list and details about the available GWASs do the +following:

+
+ao <- available_outcomes()
+head(ao)
+

For information about authentication see https://mrcieu.github.io/ieugwasr/articles/guide.html#authentication.

+

The available_outcomes() function returns a table of all +the available studies in the database. Each study has a unique ID. e.g., +You might obtain

+
+head(subset(ao, select = c(trait, id)))
+#>           trait         id
+#> 1 Schizophrenia ieu-b-5103
+#> 2 Schizophrenia ieu-b-5102
+#> 3 Schizophrenia ieu-b-5101
+#> 4 Schizophrenia ieu-b-5100
+#> 5 Schizophrenia ieu-b-5099
+#> 6 Schizophrenia ieu-b-5098
+

To extract instruments for a particular trait using a particular +study, for example to obtain SNPs for body mass index using the Locke et +al. 2015 GIANT study, you specify the study ID as follows:

+
+bmi2014_exp_dat <- extract_instruments(outcomes = 'ieu-a-2')
+
+str(bmi2014_exp_dat)
+#> 'data.frame':    79 obs. of  15 variables:
+#>  $ pval.exposure         : num  2.18e-08 4.57e-11 5.06e-14 5.45e-10 1.88e-28 ...
+#>  $ samplesize.exposure   : num  339152 339065 313621 338768 338123 ...
+#>  $ chr.exposure          : chr  "1" "1" "1" "1" ...
+#>  $ se.exposure           : num  0.003 0.0031 0.0087 0.0029 0.003 0.0037 0.0031 0.003 0.0038 0.003 ...
+#>  $ beta.exposure         : num  -0.0168 0.0201 0.0659 0.0181 0.0331 0.0497 -0.0227 0.0221 0.0209 0.0175 ...
+#>  $ pos.exposure          : int  47684677 78048331 110082886 201784287 72837239 177889480 49589847 96924097 164567689 181550962 ...
+#>  $ id.exposure           : chr  "ieu-a-2" "ieu-a-2" "ieu-a-2" "ieu-a-2" ...
+#>  $ SNP                   : chr  "rs977747" "rs17381664" "rs7550711" "rs2820292" ...
+#>  $ effect_allele.exposure: chr  "G" "C" "T" "C" ...
+#>  $ other_allele.exposure : chr  "T" "T" "C" "A" ...
+#>  $ eaf.exposure          : num  0.5333 0.425 0.0339 0.5083 0.6083 ...
+#>  $ exposure              : chr  "Body mass index || id:ieu-a-2" "Body mass index || id:ieu-a-2" "Body mass index || id:ieu-a-2" "Body mass index || id:ieu-a-2" ...
+#>  $ mr_keep.exposure      : logi  TRUE TRUE TRUE TRUE TRUE TRUE ...
+#>  $ pval_origin.exposure  : chr  "reported" "reported" "reported" "reported" ...
+#>  $ data_source.exposure  : chr  "igd" "igd" "igd" "igd" ...
+

This returns a set of LD clumped SNPs that are GWAS significant for +BMI. You can specify various parameters for this function:

+
    +
  • +p1 = P-value threshold for keeping a SNP
  • +
  • +clump = Whether or not to return independent SNPs only +(default is TRUE)
  • +
  • +r2 = The maximum LD R-square allowed between returned +SNPs
  • +
  • +kb = The distance in which to search for LD R-square +values
  • +
+

By changing changing the p1 parameter it is possible to +obtain SNP effects for constructing polygenic risk scores.

+
+
+
+

Clumping +

+

For standard two sample MR it is important to ensure that the +instruments for the exposure are independent. Once instruments have been +identified for an exposure variable, the IEU OpenGWAS database can be +used to perform clumping.

+

You can provide a list of SNP IDs, the SNPs will be extracted from +1000 genomes data, LD calculated between them, and amongst those SNPs +that have LD R-square above the specified threshold only the SNP with +the lowest P-value will be retained. To do this, use the following +command:

+
+bmi_exp_dat <- clump_data(bmi2014_exp_dat)
+
+str(bmi_exp_dat)
+#> 'data.frame':    30 obs. of  16 variables:
+#>  $ SNP                   : chr  "rs10767664" "rs13078807" "rs1514175" "rs1558902" ...
+#>  $ beta.exposure         : num  0.19 0.1 0.07 0.39 0.11 0.13 0.06 0.09 0.13 0.06 ...
+#>  $ se.exposure           : num  0.0306 0.0204 0.0204 0.0204 0.0204 ...
+#>  $ effect_allele.exposure: chr  "A" "G" "A" "A" ...
+#>  $ other_allele.exposure : chr  "T" "A" "G" "T" ...
+#>  $ eaf.exposure          : num  0.78 0.2 0.43 0.42 0.31 0.78 0.41 0.24 0.21 0.21 ...
+#>  $ pval.exposure         : num  5e-26 4e-11 8e-14 5e-120 3e-13 ...
+#>  $ units.exposure        : chr  "kg/m2" "kg/m2" "kg/m2" "kg/m2" ...
+#>  $ gene.exposure         : chr  "BDNF" "CADM2" "TNNI3K" "FTO" ...
+#>  $ samplesize.exposure   : int  225238 221431 207641 222476 247166 227886 209051 218439 209849 220081 ...
+#>  $ exposure              : chr  "BMI" "BMI" "BMI" "BMI" ...
+#>  $ mr_keep.exposure      : logi  TRUE TRUE TRUE TRUE TRUE TRUE ...
+#>  $ pval_origin.exposure  : chr  "reported" "reported" "reported" "reported" ...
+#>  $ units.exposure_dat    : chr  "kg/m2" "kg/m2" "kg/m2" "kg/m2" ...
+#>  $ id.exposure           : chr  "FXhiAH" "FXhiAH" "FXhiAH" "FXhiAH" ...
+#>  $ data_source.exposure  : chr  "textfile" "textfile" "textfile" "textfile" ...
+

The clump_data() function takes any data frame that has +been formatted to be an exposure data type of data frame. Note that for +the instruments in the MRInstruments package the SNPs are already LD +clumped.

+

Note: The LD reference panel only includes SNPs (no +INDELs). There are five super-populations from which LD can be +calculated, by default European samples are used. Only SNPs with MAF +> 0.01 within-population are available.

+

NOTE: If a variant is dropped from your unclumped +data it could be because it is absent from the reference panel. For more +flexibility, including using your own LD reference data, see here: https://mrcieu.github.io/ieugwasr/

+
+
+
+ + + +
+ + + +
+
+ + + + + + + diff --git a/docs/articles/gwas2020.html b/docs/articles/gwas2020.html new file mode 100644 index 00000000..055e5918 --- /dev/null +++ b/docs/articles/gwas2020.html @@ -0,0 +1,356 @@ + + + + + + + +Major changes to the IEU GWAS resources for 2020 • TwoSampleMR + + + + + + + + + + + + + + + Skip to contents + + +
+ + + + +
+
+ + + +

This document details changes and new features specifically relating +to the TwoSampleMR R package and the GWAS database behind it.

+
+

What has changed +

+
+

Dataset IDs +

+

We have made a new system for naming datasets, and all datasets are +organised into data batches. Either new datasets are uploaded one at a +time in which case they are added to the ieu-a data batch, +or there is a bulk upload in which case a new batch is created. For +example, ukb-a is a bulk upload of the first round of the +Neale lab UKBiobank GWAS, and ukb-b is the IEU GWAS +analysis of the UKBiobank data. In most cases, a dataset is then +numbered arbitrarily within the batch. For example, the Locke et al 2014 +BMI analysis was previously known as 2, and it is now known +as ieu-a-2.

+

There is backward compatibility built into the R packages that access +the data, so if you use an ‘old’ ID, it will automatically translate +that to the new one. But it will give you a warning, and we urge you to +update your scripts to reflect this change.

+
+
+

Authentication +

+

Previously you would automatically be asked to authenticate any query +to the database, through google. Now, we are making authentication +voluntary - something that you do at the start of a session only if you +need access to specific private datasets on the database. For the vast +majority of use cases this is not required.

+

Another change is that the R package that managed the authentication +has updated, and the file tokens generated are slightly different. For +full information on how to deal with this, see here: https://mrcieu.github.io/ieugwasr/articles/guide.html#authentication

+
+
+

UKBiobank data has been curated +

+

We conducted a large GWAS analysis using a pipeline that +systematically analysed every PHESANT phenotype +in UK Biobank. There were previously ~20k traits with complete GWAS +data, but a majority of these were binary traits based on very few +numbers of cases. We have now filtered out unreliable datasets, there +are 2514 traits remaining, with any binary traits removed that had fewer +than 1000 cases. Another issue is the combination of small numbers of +cases and allele frequency - here minor allele count (MAC) for a +particular association could be very small which would lead to high +false positives when using Bolt-LMM. The remaining traits have been +filtered to only retain associations where the MAC > 90.

+

Document detailing this investigation here: https://htmlpreview.github.io/?https://raw.githubusercontent.com/MRCIEU/ukbb-gwas-analysis/master/docs/ldsc_clumped_analysis.html?token=AAOV6TBQXEXEPT7SUXXLWMC6DWP3O

+
+
+

All data is now harmonised +

+

Previously the data were QC’d to remove malformed results and then +deposited as we found them. We are now also pre-harmonising all the +data. This means that all alleles are coded on the forward strand, and +the non-effect allele is always aligned to the human genome reference +sequence B37 (so the effect allele is the non-reference allele). This +does mean that sometimes variants have been removed if they did not map +to the human genome, and for most datasets the effect allele has been +switched for approximately half of all sites. When an effect allele +changes we do of course switch the sign of the effect size, so it should +not impact any MR results.

+
+
+

LD reference panel is now harmonised +

+

We have updated the LD reference panel to be harmonised against human +genome build 37, and as a consequence a few variants have been lost from +the version that was previously used.

+
+
+

Instrument lists are up-to-date +

+

Previously we were pre-clumping the tophits and storing them in the +MRInstruments R package, and there was often a delay in updating the +MRInstruments R package after new datasets were uploaded to the +database. We have moved away from this model. Everything dataset is +pre-clumped, but that is stored in the database. If you request default +clumping values when extracting the tophits of a dataset, it will still +be fast but it is retrieving the data from the server, and not from the +MRInstruments package. You can continue to use the MRInstruments package +for GWAS hits from e.g. GTEx or the EBI GWAS catalog.

+
+
+

dbSNP rs IDs +

+

All rs IDs have been mapped to dbSNP build 144. Therefore, some rs +IDs may have changed, but there is stronger alignment across all +datasets.

+
+
+

Everything is faster +

+

We are using Elasticsearch and Neo4j on an Oracle Cloud +Infrastructure to serve the data. It’s much faster. Interestingly, it +actually gets faster when more people are using it because the cache +gets ‘warmed up’ by more requests.

+
+
+
+

What is new +

+
+

Browse available datasets online +

+

We have a new home for the GWAS summary data: https://gwas.mrcieu.ac.uk/.

+
+
+

Chromosome and position +

+

All variants have been mapped to chromosome and position +(hg19/build37). You can query based on chromosome position coordinates. +This means either a list of <chr:pos> values, or a +list of <chr:pos1-pos2> ranges.

+
+
+

INDELs are retained +

+

Previously we were excluding these, but they are now retained

+
+
+

Multi-allelic variants are retained +

+

Previously we were excluding these, but they are now retained. Be +warned that if you extract a variant that has multiple alleles then you +may get more than one row for that variant.

+
+
+

More data +

+

Automated download from the EBI repository, and an automated upload +system and batch data processing system means that more data can be +added faster to keep the database current.

+
+
+

Error messages are more informative +

+

Previously if a query to the database failed it didn’t give a reason, +hopefully there is more clarity regarding what is happening now. You can +also check the status of the server here: https://api.opengwas.io/api/

+
+
+

Easier programmatic access to the database +

+

We are trying to make it as flexible as possible to access the data. +The TwoSampleMR R package was previously the only programmatic way to +access the data, now we have the following options:

+
    +
  • +ieugwasr R package: +All the TwoSampleMR functions that access the data are done by calling +this package now. It is a simple wrapper around the API that controls +access to the database.
  • +
  • +ieugwaspy python +package: Similar functionality to ieugwasr (Under +construction).
  • +
  • +API: You can use the API +directly, e.g. for building your own services or applications.
  • +
+
+
+

Local LD operations +

+

It is now possible to perform clumping, or create LD matrices, using +your own local LD reference dataset. You can download the one that we +have been using here: https://github.com/mrcieu/gwasglue#reference-datasets, +or create your own plink format dataset e.g. with larger samples or for +different ancestries. See the LD clumping functions in the ieugwasr package for more +details.

+
+
+

Access the data directly +

+

Previously the data was only accessible through the database. Now the +data can be downloaded in “GWAS VCF” format from here https://gwas.mrcieu.ac.uk/. (IEU members can access all +the data on RDSF or bluecrystal4 directly). This means that if you want +to perform very large or numerous operations, you can do it on HPC or +locally in a more performant manner by using the data files directly. +Please see the gwasvcf R +package on how to work with these data.

+
+
+

Connect the data to different analytical tools +

+

Either the data in the database, or the GWAS VCF files, can be +queried and the results translated into the formats for a bunch of +different R packages for MR, colocalisation, fine mapping, etc. Have a +look at the gwasglue R +package, to see what is available and how to do this. It’s still +under construction, but feel free to try it, make suggestions, and +contribute code.

+
+
+
+ + +
+
+

How to request new data +

+

We have setup a github issues page here: https://github.com/MRCIEU/opengwas-requests/issues

+

Please visit here to make a log of new data requests, or to +contribute new data.

+
+
+

Backwards compatibility +

+

To install the new version of TwoSampleMR, perform as normal:

+
+install.packages("remotes")
+remotes::install_github("MRCIEU/TwoSampleMR")
+

To update the package just run the +remotes::install_github("MRCIEU/TwoSampleMR") command +again.

+

We recommend using this new version going forwards but for a limited +time we are enabling backwards compatibility, in case you are in the +middle of analysis or need to reproduce old analysis. In order to use +the legacy version of the package and the database, install using:

+
+install.packages("remotes")
+remotes::install_github("MRCIEU/TwoSampleMR@0.4.26")
+
+
+
+ + + +
+ + + +
+
+ + + + + + + diff --git a/docs/articles/harmonise.html b/docs/articles/harmonise.html new file mode 100644 index 00000000..47f1b06e --- /dev/null +++ b/docs/articles/harmonise.html @@ -0,0 +1,354 @@ + + + + + + + +Harmonise data • TwoSampleMR + + + + + + + + + + + + + + + Skip to contents + + +
+ + + + +
+
+ + + + +
+

Introduction +

+

The exposure data and outcome data are now obtained, e.g.:

+
+bmi_exp_dat <- extract_instruments(outcomes = 'ieu-a-2')
+chd_out_dat <- extract_outcome_data(snps = bmi_exp_dat$SNP, outcomes = 'ieu-a-7')
+

but it is important to harmonise the effects. This means that the +effect of a SNP on the exposure and the effect of that SNP on the +outcome must each correspond to the same allele.

+

Note: The IEU GWAS database contains data that is +already harmonised, meaning that the non-effect allele is aligned to the +human genome reference sequence (build 37). It’s still recommended to +harmonise, but in principle everything should be on the forward strand +and effect alleles always relating to the same allele. Some +discrepancies could arise if there are multi-allelic variants that are +represented as different bi-allelic variants in different studies.

+

To harmonise the exposure and outcome data, do the following:

+
+dat <- harmonise_data(
+    exposure_dat = bmi_exp_dat,
+    outcome_dat = chd_out_dat
+)
+#> Harmonising Body mass index || id:ieu-a-2 (ieu-a-2) and Coronary heart disease || id:ieu-a-7 (ieu-a-7)
+

This creates a new data frame that has the exposure data and outcome +data combined.

+

If there were 3 exposure traits and 3 outcome traits then there will +be 9 sets of harmonisations being performed - harmonising the SNP +effects of exposure trait 1 against outcome trait 1; exposure trait 1 +against outcome trait 2; and so on.

+
+
+

Dealing with strand issues +

+

Recent GWASs typically present the effects of a SNP in reference to +the allele on the forward strand. But as reference panels are updated +the forward strand sometimes changes, and GWASs from a few years ago +aren’t guaranteed to be using forward strand conventions.

+

Some examples are shown below:

+
+

Correct, unambigious +

+
exposure effect = 0.5
+effect allele = A
+other allele = G
+
+outcome effect = 0.05
+effect allele = A
+other allele = G
+

Here the effect allele on the exposure and the outcome is the +same

+
+
+

Incorrect reference, unambigious +

+
exposure effect = 0.5
+effect allele = A
+other allele = G
+
+outcome effect = -0.05
+effect allele = C
+other allele = T
+

Here the outcome GWAS is presenting the effect for the alternate +allele on the reverse strand. We need to flip the outcome effect to 0.05 +to correspond to the same allele as the exposure GWAS on the forward +strand.

+
+
+

Ambiguous +

+
exposure effect = 0.5
+effect allele = A
+other allele = G
+
+outcome effect = -0.05
+effect allele = A
+other allele = C
+

Here the alleles do not correspond for the same SNP, so this SNP will +be discarded from the analysis.

+
+
+

Palindromic SNP, inferrable +

+
exposure effect = 0.5
+effect allele = A
+other allele = T
+effect allele frequency = 0.11
+
+outcome effect = -0.05
+effect allele = A
+other allele = T
+effect allele frequency = 0.91
+

Here the alleles correspond, but it is a palindromic SNP, such that +the alleles on the forward strand are the same as on the reverse strand +(A/T on forward is T/A on the reverse). However, the allele frequency of +the effect allele gives us information - if the outcome effect allele +(A) were on the forward strand we would expect it to have a low allele +frequency, but given it has a high frequency (0.91) we infer that the +outcome GWAS is presenting the effect on the reverse strand for the +alternative allele. We would flip the effect to 0.05 for the outcome +GWAS.

+
+
+

Palindromic SNP, not inferrable +

+
exposure effect = 0.5
+effect allele = A
+other allele = T
+effect allele frequency = 0.50
+
+outcome effect = -0.05
+effect allele = A
+other allele = T
+effect allele frequency = 0.50
+

This is similar to the above, except the allele frequency no longer +gives us information about the strand. We would discard this SNP. This +is done for any palindromic SNPs that have minor allele frequency above +0.42.

+
+
+

Options +

+

There are three options to harmonising the data.

+
    +
  1. Assume all alleles are presented on the forward strand
  2. +
  3. Try to infer the forward strand alleles using allele frequency +information
  4. +
  5. Correct the strand for non-palindromic SNPs, but drop all +palindromic SNPs
  6. +
+

By default, the harmonise_data function uses option 2, +but this can be modified using the action argument, +e.g. harmonise_data(exposure_dat, outcome_dat, action = 3).

+
+
+
+

Drop duplicate exposure-outcome summary sets +

+

After data harmonisation, users may find that their dataset contains +duplicate exposure-outcome summary sets. This can arise, for example, +when a GWAS consortium has released multiple results from separate GWAS +analyses for the same trait. For example, there are multiple GWAS +summary datasets for body mass index and coronary heart disease:

+ +
+ao[ao$trait == "Body mass index", c("trait", "id", "pmid", "author", "sample_size", "nsnp")]
+#>                 trait                 id     pmid                    author
+#> 3958  Body mass index ebi-a-GCST90103751 35051171                   Wong HS
+#> 4015  Body mass index ebi-a-GCST90095039 35399580 Fern<U+00E1>ndez-Rhodes L
+#> 4020  Body mass index ebi-a-GCST90095034 35399580 Fern<U+00E1>ndez-Rhodes L
+#> 6032  Body mass index ebi-a-GCST90029007 29892013                    Loh PR
+#> 6821  Body mass index ebi-a-GCST90025994 34226706                 Barton AR
+#> 7045  Body mass index ebi-a-GCST90018947 34594039                  Sakaue S
+#> 7259  Body mass index ebi-a-GCST90018727 34594039                  Sakaue S
+#> 10738 Body mass index           ieu-a-94 23754948                Randall JC
+#> 12717 Body mass index            ieu-a-2 25673413                  Locke AE
+#> 14254 Body mass index           ieu-a-95 23754948                Randall JC
+#> 16676 Body mass index          ieu-a-974 25673413                  Locke AE
+#> 19343 Body mass index            bbj-a-3 28892062                Ishigaki K
+#> 26475 Body mass index   ebi-a-GCST006368 30108127               Hoffmann TJ
+#> 28065 Body mass index         ieu-b-4815       NA                   Howe LJ
+#> 28419 Body mass index            bbj-a-2 28892062                Ishigaki K
+#> 32371 Body mass index         ieu-b-4816       NA                   Howe LJ
+#> 33869 Body mass index          ieu-a-785 25673413                  Locke AE
+#> 39217 Body mass index   ebi-a-GCST002783 25673413                  Locke AE
+#> 40065 Body mass index            bbj-a-1 28892062                Ishigaki K
+#> 43262 Body mass index   ebi-a-GCST004904 28892062                 Akiyama M
+#> 43743 Body mass index   ebi-a-GCST006802 26961502                   Wood AR
+#> 47894 Body mass index          ieu-a-835 25673413                  Locke AE
+#> 48917 Body mass index   ebi-a-GCST008025 31217584                 Wojcik GL
+#> 49208 Body mass index         ieu-a-1089 26961502                      Wood
+#>       sample_size     nsnp
+#> 3958        21930  6370138
+#> 4015       330793  2401077
+#> 4020        56161  8764141
+#> 6032       532396 11973091
+#> 6821       457756  4238669
+#> 7045       359983 19066885
+#> 7259       163835 12502877
+#> 10738       60586  2736876
+#> 12717      339224  2555511
+#> 14254       73137  2736876
+#> 16676      171977  2494613
+#> 19343       72390  6108953
+#> 26475      315347 27854527
+#> 28065       51852       NA
+#> 28419       85894  6108953
+#> 32371       99998  7191606
+#> 33869      152893  2477659
+#> 39217      236781  2529499
+#> 40065      158284  5961600
+#> 43262      158284  5952516
+#> 43743      119688  8580466
+#> 47894      322154  2554668
+#> 48917       21955 34343880
+#> 49208      120286  8654252
+ao[ao$trait == "Coronary heart disease", c("trait", "id", "pmid", "author", "ncase", "ncontrol", "nsnp")]
+#>                        trait               id     pmid      author ncase
+#> 14897 Coronary heart disease          ieu-a-7 26343387      Nikpay 60801
+#> 23614 Coronary heart disease          ieu-a-9 23202125    Deloukas 63746
+#> 27414 Coronary heart disease ebi-a-GCST000998 21378990 Schunkert H 22233
+#> 38602 Coronary heart disease          ieu-a-8 21378990 Schunkert H 22233
+#> 45294 Coronary heart disease          ieu-a-6 21378988       Peden 15420
+#>       ncontrol    nsnp
+#> 14897   123504 9455779
+#> 23614   130681   79129
+#> 27414    64762 2415020
+#> 38602    64762 2420361
+#> 45294    15062  540233
+

There are therefore multiple potential combinations of body mass +index and coronary heart disease, which would likely lead to duplicate +MR analyses. We recommend that users prune their datasets so that only +the exposure-outcome combination with the highested expected power is +retained. This can be done by selecting the exposure-outcome summary set +with the largest sample size for the outcome, using the power_prune +function:

+
+dat <- power_prune(dat, method = 1, dist.outcome = "binary")
+

This drops the duplicate exposure-outcome sets with the smaller +outcome sample size (number of cases for binary outcomes). Remaining +duplicates are then dropped on the basis of the exposure sample size. +However, if there are a large number of SNPs available to instrument an +exposure, the outcome GWAS with the better SNP coverage may provide +better power than the outcome GWAS with the larger sample size. This can +occur, for example, if the larger outcome GWAS has used a targeted +genotyping array. In such instances, it may be better to prune studies +on the basis of instrument strength (i.e. variation in exposure +explained by the instrumental SNPs) as well as sample size. This can be +done by setting the method argument to 2:

+
+dat <- power_prune(dat, method = 2, dist.outcome = "binary")
+

This procedure drops duplicate exposure-outcome sets on the basis of +instrument strength and sample size, and assumes that the SNP-exposure +effects correspond to a continuous trait with a normal distribution +(i.e. exposure should not be binary). The SNP-outcome effects can +correspond to either a binary or continuous trait (default behaviour is +to assume a binary distribution). If the exposure is binary then method +1 should be used.

+
+
+
+ + + +
+ + + +
+
+ + + + + + + diff --git a/docs/articles/img/twosamplemr_schematic_long-01.png b/docs/articles/img/twosamplemr_schematic_long-01.png new file mode 100644 index 00000000..49e9a368 Binary files /dev/null and b/docs/articles/img/twosamplemr_schematic_long-01.png differ diff --git a/docs/articles/index.html b/docs/articles/index.html new file mode 100644 index 00000000..5517e6f5 --- /dev/null +++ b/docs/articles/index.html @@ -0,0 +1,84 @@ + +Articles • TwoSampleMR + Skip to contents + + +
+
+
+ +
+

Guide

+

The following pages provide detailed illustrations of the TwoSampleMR package.

+ +
Introduction
+
+
Exposure data
+
+
Outcome data
+
+
Harmonise data
+
+
Perform MR
+
+
Major changes to the IEU GWAS resources for 2020
+
+
+
+ + +
+ + + +
+ + + + + + + diff --git a/docs/articles/introduction.html b/docs/articles/introduction.html new file mode 100644 index 00000000..14d8732a --- /dev/null +++ b/docs/articles/introduction.html @@ -0,0 +1,231 @@ + + + + + + + +Introduction • TwoSampleMR + + + + + + + + + + + + + + + Skip to contents + + +
+ + + + +
+
+ + + +
+

Background +

+

Two sample Mendelian randomisation (2SMR) is a method to estimate the +causal effect of an exposure on an outcome using only summary statistics +from genome wide association studies (GWAS). Though conceptually +straightforward, there are a number of steps that are required to +perform the analysis properly, and they can be cumbersome. The +TwoSampleMR package aims to make this easy by combining three important +components

+
    +
  • data management and harmonisation
  • +
  • the statistical routines to estimate the causal effects
  • +
  • connection to a large repository of the actual GWAS summary +statistics needed to perform the analyses.
  • +
+

The general principles (G. Davey Smith and +Ebrahim 2003; George Davey Smith and Hemani 2014), and +statistical methods (Pierce and Burgess 2013; +Bowden, Davey Smith, and Burgess 2015) can be found elsewhere, +here we will just outline how to use the R package.

+

This package uses the ieugwasr package to +connect to the database of thousands of complete GWAS summary data.

+
+
+
+

Installation +

+

To install directly from the GitHub repository do the following:

+
+library(remotes)
+install_github("MRCIEU/TwoSampleMR")
+

If you don’t have the remotes package install it from +CRAN using install.packages("remotes").

+
+
+
+

Overview +

+

The workflow for performing MR is as follows:

+
    +
  1. Select instruments for the exposure (perform LD clumping if +necessary)
  2. +
  3. Extract the instruments from the IEU GWAS database for the outcomes +of interest
  4. +
  5. Harmonise the effect sizes for the instruments on the exposures and +the outcomes to be each for the same reference allele
  6. +
  7. Perform MR analysis, sensitivity analyses, create plots, compile +reports
  8. +
+

A diagrammatic overview is shown here:

+

A diagrammatic overview of performing a two-sample Mendelian randomization analysis

+

A basic analysis, e.g. the causal effect of body mass index on +coronary heart disease, looks like this:

+
+library(TwoSampleMR)
+
+# List available GWASs
+ao <- available_outcomes()
+
+# Get instruments
+exposure_dat <- extract_instruments("ieu-a-2")
+
+# Get effects of instruments on outcome
+outcome_dat <- extract_outcome_data(snps=exposure_dat$SNP, outcomes = "ieu-a-7")
+
+# Harmonise the exposure and outcome data
+dat <- harmonise_data(exposure_dat, outcome_dat)
+
+# Perform MR
+res <- mr(dat)
+

Each step is documented on other pages in the documentation.

+
+
+

Authentication +

+

The statistical methods in TwoSampleMR can be used on any data, but +there are a number of functions that connect to the OpenGWAS database +for data extraction. These OpenGWAS data access functions require +authentication.

+

Authentication is changing The main differences are +that:

+
    +
  1. Authentication is required for most queries to OpenGWAS for everyone +(i.e. no more anonymous usage)
  2. +
  3. We are no longer using Google Oauth2. This has been replaced by a +simple API key system.
  4. +
+

Detailed information is given here: https://mrcieu.github.io/ieugwasr/articles/guide.html#authentication.

+
+
+

References +

+
+
+Bowden, Jack, George Davey Smith, and Stephen Burgess. 2015. +Mendelian randomization with invalid +instruments: effect estimation and bias detection through Egger +regression.” International Journal of +Epidemiology 44 (2): 512–25. https://doi.org/10.1093/ije/dyv080. +
+
+Davey Smith, G., and S. Ebrahim. 2003. ’Mendelian randomization’: can genetic epidemiology +contribute to understanding environmental determinants of +disease? International Journal of Epidemiology +32 (1): 1–22. https://doi.org/10.1093/ije/dyg070. +
+
+Davey Smith, George, and Gibran Hemani. 2014. Mendelian randomization: genetic anchors for causal +inference in epidemiological studies.” Human Molecular +Genetics 23 (R1): R89–98. https://doi.org/10.1093/hmg/ddu328. +
+
+Pierce, Brandon L, and Stephen Burgess. 2013. Efficient design for Mendelian randomization studies: +subsample and 2-sample instrumental variable estimators.” +American Journal of Epidemiology 178 (7): 1177–84. https://doi.org/10.1093/aje/kwt084. +
+
+
+
+
+ + + +
+ + + +
+
+ + + + + + + diff --git a/docs/articles/outcome.html b/docs/articles/outcome.html new file mode 100644 index 00000000..68f02819 --- /dev/null +++ b/docs/articles/outcome.html @@ -0,0 +1,573 @@ + + + + + + + +Outcome data • TwoSampleMR + + + + + + + + + + + + + + + Skip to contents + + +
+ + + + +
+
+ + + + +

Once instruments for the exposure trait have been specified, those +variants need to be extracted from the outcome trait.

+
+

Available studies in IEU GWAS database +

+

The IEU GWAS database (IGD) contains complete GWAS summary statistics +from a large number of studies. You can browse them here:

+

https://gwas.mrcieu.ac.uk/

+

To obtain details about the available GWASs programmatically do the +following:

+ +
+head(ao)
+#>           id         trait ncase group_name year       author consortium
+#> 1 ieu-b-5103 Schizophrenia  1234     public 2022 Trubetskoy V        PGC
+#> 2 ieu-b-5102 Schizophrenia 52017     public 2022 Trubetskoy V        PGC
+#> 3 ieu-b-5101 Schizophrenia 12305     public 2022 Trubetskoy V        PGC
+#> 4 ieu-b-5100 Schizophrenia 64322     public 2022 Trubetskoy V        PGC
+#> 5 ieu-b-5099 Schizophrenia 76755     public 2022 Trubetskoy V        PGC
+#> 6 ieu-b-5098 Schizophrenia  5998     public 2022 Trubetskoy V        PGC
+#>                 sex     pmid                         population  unit
+#> 1 Males and Females 35396580         Hispanic or Latin American logOR
+#> 2 Males and Females 35396580                           European logOR
+#> 3 Males and Females 35396580                         East Asian logOR
+#> 4 Males and Females 35396580                              Mixed logOR
+#> 5 Males and Females 35396580                              Mixed logOR
+#> 6 Males and Females 35396580 African American or Afro-Caribbean logOR
+#>   sample_size       build ncontrol category subcategory      ontology
+#> 1        4324 HG19/GRCh37     3090  Disease          NA MONDO:0005090
+#> 2      127906 HG19/GRCh37    75889  Disease          NA MONDO:0005090
+#> 3       27363 HG19/GRCh37    15058  Disease          NA MONDO:0005090
+#> 4      155269 HG19/GRCh37    90947  Disease          NA MONDO:0005090
+#> 5      320404 HG19/GRCh37   243649  Disease          NA MONDO:0005090
+#> 6        9824 HG19/GRCh37     3826  Disease          NA MONDO:0005090
+#>                                                                      note mr
+#> 1                                                                    <NA> NA
+#> 2                                                                    <NA> NA
+#> 3                                                                    <NA> NA
+#> 4                            Core - East Asian and European meta analysis NA
+#> 5 Primary - meta analysis of Eur, East Asian, African American and Latino NA
+#> 6                                                                    <NA> NA
+#>   nsnp  doi coverage study_design priority sd
+#> 1   NA <NA>     <NA>         <NA>       NA NA
+#> 2   NA <NA>     <NA>         <NA>       NA NA
+#> 3   NA <NA>     <NA>         <NA>       NA NA
+#> 4   NA <NA>     <NA>         <NA>       NA NA
+#> 5   NA <NA>     <NA>         <NA>       NA NA
+#> 6   NA <NA>     <NA>         <NA>       NA NA
+

For information about authentication see https://mrcieu.github.io/ieugwasr/articles/guide.html#authentication.

+

The available_outcomes function returns a table of all +the available studies in the database. Each study has a unique ID. +e.g.

+
+head(subset(ao, select = c(trait, id)))
+#>           trait         id
+#> 1 Schizophrenia ieu-b-5103
+#> 2 Schizophrenia ieu-b-5102
+#> 3 Schizophrenia ieu-b-5101
+#> 4 Schizophrenia ieu-b-5100
+#> 5 Schizophrenia ieu-b-5099
+#> 6 Schizophrenia ieu-b-5098
+
+
+

Extracting particular SNPs from particular studies +

+

If we want to perform MR of BMI against coronary heart disease, we +need to identify the SNPs that influence the BMI, and then extract those +SNPs from a GWAS on coronary heart disease.

+

Let’s get the Locke et al 2014 instruments for BMI as an example:

+
+bmi_exp_dat <- extract_instruments(outcomes = 'ieu-a-2')
+
+head(bmi_exp_dat)
+#>   pval.exposure samplesize.exposure chr.exposure se.exposure beta.exposure
+#> 1   2.18198e-08              339152            1      0.0030       -0.0168
+#> 2   4.56773e-11              339065            1      0.0031        0.0201
+#> 3   5.05941e-14              313621            1      0.0087        0.0659
+#> 4   5.45205e-10              338768            1      0.0029        0.0181
+#> 5   1.88018e-28              338123            1      0.0030        0.0331
+#> 6   2.28718e-40              339078            1      0.0037        0.0497
+#>   pos.exposure id.exposure        SNP effect_allele.exposure
+#> 1     47684677     ieu-a-2   rs977747                      G
+#> 2     78048331     ieu-a-2 rs17381664                      C
+#> 3    110082886     ieu-a-2  rs7550711                      T
+#> 4    201784287     ieu-a-2  rs2820292                      C
+#> 5     72837239     ieu-a-2  rs7531118                      C
+#> 6    177889480     ieu-a-2   rs543874                      G
+#>   other_allele.exposure eaf.exposure                      exposure
+#> 1                     T       0.5333 Body mass index || id:ieu-a-2
+#> 2                     T       0.4250 Body mass index || id:ieu-a-2
+#> 3                     C       0.0339 Body mass index || id:ieu-a-2
+#> 4                     A       0.5083 Body mass index || id:ieu-a-2
+#> 5                     T       0.6083 Body mass index || id:ieu-a-2
+#> 6                     A       0.2667 Body mass index || id:ieu-a-2
+#>   mr_keep.exposure pval_origin.exposure data_source.exposure
+#> 1             TRUE             reported                  igd
+#> 2             TRUE             reported                  igd
+#> 3             TRUE             reported                  igd
+#> 4             TRUE             reported                  igd
+#> 5             TRUE             reported                  igd
+#> 6             TRUE             reported                  igd
+

We now need to find a suitable GWAS for coronary heart disease. We +can search the available studies:

+
+ao[grepl("heart disease", ao$trait), ]
+#>                                 id
+#> 7958                 finn-b-I9_CHD
+#> 10829                   ukb-b-3983
+#> 12268                ukb-e-I25_AFR
+#> 14221                   ukb-b-2205
+#> 14897                      ieu-a-7
+#> 15028 finn-b-I9_SECONDRIGHT_EXNONE
+#> 16883                   ukb-b-7436
+#> 18046                    ukb-a-534
+#> 18048                ukb-e-I25_CSA
+#> 20207           finn-b-I9_OTHHEART
+#> 22249         finn-b-I9_VHD_EXNONE
+#> 22725          finn-b-I9_PULMHEART
+#> 23614                      ieu-a-9
+#> 24603           finn-b-FG_OTHHEART
+#> 27414             ebi-a-GCST000998
+#> 33264          finn-b-FG_PULMHEART
+#> 35220                 ukb-d-I9_CHD
+#> 35231        finn-b-I9_OTHILLHEART
+#> 36931                   ukb-b-8184
+#> 37302 finn-b-I9_OTHILLHEART_EXNONE
+#> 37894                   ukb-b-1668
+#> 38319                finn-b-I9_IHD
+#> 38448            finn-b-I9_RHEUFEV
+#> 38602                      ieu-a-8
+#> 41994          finn-b-I9_ISCHHEART
+#> 42095                 ukb-d-I9_IHD
+#> 42882        finn-b-I9_SECONDRIGHT
+#> 43747           ukb-d-I9_CHD_NOREV
+#> 45294                      ieu-a-6
+#> 46126                finn-b-I9_VHD
+#> 46689                  ukb-b-16606
+#>                                                                                                                           trait
+#> 7958                                                                                         Major coronary heart disease event
+#> 10829                                                Diagnoses - main ICD10: I25.9 Chronic ischaemic heart disease, unspecified
+#> 12268                                                                                       I25 Chronic ischaemic heart disease
+#> 14221 Diagnoses - secondary ICD10: Z82.4 Family history of ischaemic heart disease and other diseases of the circulatory system
+#> 14897                                                                                                    Coronary heart disease
+#> 15028                                                                      Secondary right heart disease (no controls excluded)
+#> 16883                                                          Diagnoses - secondary ICD10: I25.1 Atherosclerotic heart disease
+#> 18046                                                               Diagnoses - main ICD10: I25 Chronic ischaemic heart disease
+#> 18048                                                                                       I25 Chronic ischaemic heart disease
+#> 20207                                                                                        Other heart diseases (I9_OTHHEART)
+#> 22249                                                   Valvular heart disease including rheumatic fever (no controls excluded)
+#> 22725                                                                Pulmonary heart disease, diseases of pulmonary circulation
+#> 23614                                                                                                    Coronary heart disease
+#> 24603                                                                                        Other heart diseases (FG_OTHHEART)
+#> 27414                                                                                                    Coronary heart disease
+#> 33264                                                                                                   Pulmonary heart disease
+#> 35220                                                                                        Major coronary heart disease event
+#> 35231                                                                                       Other or ill-defined heart diseases
+#> 36931                                           Diagnoses - secondary ICD10: I25.9 Chronic ischaemic heart disease, unspecified
+#> 37302                                                                Other or ill-defined heart diseases (no controls excluded)
+#> 37894                                                               Diagnoses - main ICD10: I25.1 Atherosclerotic heart disease
+#> 38319                                                                                  Ischaemic heart disease, wide definition
+#> 38448                                                                                        Rheumatic fever incl heart disease
+#> 38602                                                                                                    Coronary heart disease
+#> 41994                                                                                                   Ischemic heart diseases
+#> 42095                                                                                  Ischaemic heart disease, wide definition
+#> 42882                                                                                             Secondary right heart disease
+#> 43747                                                           Major coronary heart disease event excluding revascularizations
+#> 45294                                                                                                    Coronary heart disease
+#> 46126                                                                          Valvular heart disease including rheumatic fever
+#> 46689                                         Diagnoses - secondary ICD10: I25.8 Other forms of chronic ischaemic heart disease
+#>       ncase group_name year       author        consortium               sex
+#> 7958  21012     public 2021           NA                NA Males and Females
+#> 10829  1195     public 2018 Ben Elsworth           MRC-IEU Males and Females
+#> 12268   302     public 2020 Pan-UKB team                NA Males and Females
+#> 14221  9330     public 2018 Ben Elsworth           MRC-IEU Males and Females
+#> 14897 60801     public 2015       Nikpay CARDIoGRAMplusC4D Males and Females
+#> 15028   428     public 2021           NA                NA Males and Females
+#> 16883  5771     public 2018 Ben Elsworth           MRC-IEU Males and Females
+#> 18046  8755     public 2017        Neale         Neale Lab Males and Females
+#> 18048  1205     public 2020 Pan-UKB team                NA Males and Females
+#> 20207 62081     public 2021           NA                NA Males and Females
+#> 22249 38209     public 2021           NA                NA Males and Females
+#> 22725  4564     public 2021           NA                NA Males and Females
+#> 23614 63746     public 2013     Deloukas CARDIoGRAMplusC4D Males and Females
+#> 24603 58173     public 2021           NA                NA Males and Females
+#> 27414 22233     public 2011  Schunkert H                NA                NA
+#> 33264  4185     public 2021           NA                NA Males and Females
+#> 35220 10157     public 2018    Neale lab                NA Males and Females
+#> 35231   713     public 2021           NA                NA Males and Females
+#> 36931  5861     public 2018 Ben Elsworth           MRC-IEU Males and Females
+#> 37302   713     public 2021           NA                NA Males and Females
+#> 37894 12171     public 2018 Ben Elsworth           MRC-IEU Males and Females
+#> 38319 31640     public 2021           NA                NA Males and Females
+#> 38448   573     public 2021           NA                NA Males and Females
+#> 38602 22233     public 2011  Schunkert H        CARDIoGRAM Males and Females
+#> 41994 30952     public 2021           NA                NA Males and Females
+#> 42095 20857     public 2018    Neale lab                NA Males and Females
+#> 42882   428     public 2021           NA                NA Males and Females
+#> 43747 10157     public 2018    Neale lab                NA Males and Females
+#> 45294 15420     public 2011        Peden               C4D Males and Females
+#> 46126 38209     public 2021           NA                NA Males and Females
+#> 46689  5738     public 2018 Ben Elsworth           MRC-IEU Males and Females
+#>           pmid                         population     unit sample_size
+#> 7958        NA                           European       NA          NA
+#> 10829       NA                           European       SD      463010
+#> 12268       NA African American or Afro-Caribbean       NA        6636
+#> 14221       NA                           European       SD      463010
+#> 14897 26343387                              Mixed log odds      184305
+#> 15028       NA                           European       NA          NA
+#> 16883       NA                           European       SD      463010
+#> 18046       NA                           European       SD      337199
+#> 18048       NA                        South Asian       NA        8876
+#> 20207       NA                           European       NA          NA
+#> 22249       NA                           European       NA          NA
+#> 22725       NA                           European       NA          NA
+#> 23614 23202125                              Mixed log odds      194427
+#> 24603       NA                           European       NA          NA
+#> 27414 21378990                           European    logOR       86995
+#> 33264       NA                           European       NA          NA
+#> 35220       NA                           European       NA      361194
+#> 35231       NA                           European       NA          NA
+#> 36931       NA                           European       SD      463010
+#> 37302       NA                           European       NA          NA
+#> 37894       NA                           European       SD      463010
+#> 38319       NA                           European       NA          NA
+#> 38448       NA                           European       NA          NA
+#> 38602 21378990                           European log odds       86995
+#> 41994       NA                           European       NA          NA
+#> 42095       NA                           European       NA      361194
+#> 42882       NA                           European       NA          NA
+#> 43747       NA                           European       NA      361194
+#> 45294 21378988                              Mixed log odds       30482
+#> 46126       NA                           European       NA          NA
+#> 46689       NA                           European       SD      463010
+#>             build ncontrol category    subcategory ontology
+#> 7958  HG19/GRCh37   197780   Binary             NA       NA
+#> 10829 HG19/GRCh37   461815   Binary             NA       NA
+#> 12268 HG19/GRCh37     6334   Binary             NA       NA
+#> 14221 HG19/GRCh37   453680   Binary             NA       NA
+#> 14897 HG19/GRCh37   123504  Disease Cardiovascular       NA
+#> 15028 HG19/GRCh37   218364   Binary             NA       NA
+#> 16883 HG19/GRCh37   457239   Binary             NA       NA
+#> 18046 HG19/GRCh37   328444       NA             NA       NA
+#> 18048 HG19/GRCh37     7671   Binary             NA       NA
+#> 20207 HG19/GRCh37   156711   Binary             NA       NA
+#> 22249 HG19/GRCh37   180583   Binary             NA       NA
+#> 22725 HG19/GRCh37   214228   Binary             NA       NA
+#> 23614 HG19/GRCh37   130681  Disease Cardiovascular       NA
+#> 24603 HG19/GRCh37   160619   Binary             NA       NA
+#> 27414 HG19/GRCh37    64762       NA             NA       NA
+#> 33264 HG19/GRCh37   214607   Binary             NA       NA
+#> 35220 HG19/GRCh37   351037   Binary             NA       NA
+#> 35231 HG19/GRCh37   156711   Binary             NA       NA
+#> 36931 HG19/GRCh37   457149   Binary             NA       NA
+#> 37302 HG19/GRCh37   218079   Binary             NA       NA
+#> 37894 HG19/GRCh37   450839   Binary             NA       NA
+#> 38319 HG19/GRCh37   187152   Binary             NA       NA
+#> 38448 HG19/GRCh37   218219   Binary             NA       NA
+#> 38602 HG19/GRCh37    64762  Disease Cardiovascular       NA
+#> 41994 HG19/GRCh37   187840   Binary             NA       NA
+#> 42095 HG19/GRCh37   340337   Binary             NA       NA
+#> 42882 HG19/GRCh37   214228   Binary             NA       NA
+#> 43747 HG19/GRCh37   351037   Binary             NA       NA
+#> 45294 HG19/GRCh37    15062  Disease Cardiovascular       NA
+#> 46126 HG19/GRCh37   156711   Binary             NA       NA
+#> 46689 HG19/GRCh37   457272   Binary             NA       NA
+#>                                                                                       note
+#> 7958                                                                                I9_CHD
+#> 10829 41202#I259: Output from GWAS pipeline using Phesant derived variables from UKBiobank
+#> 12268                                                                                   NA
+#> 14221 41204#Z824: Output from GWAS pipeline using Phesant derived variables from UKBiobank
+#> 14897                                                                                 <NA>
+#> 15028                                                                I9_SECONDRIGHT_EXNONE
+#> 16883 41204#I251: Output from GWAS pipeline using Phesant derived variables from UKBiobank
+#> 18046                                                                                   NA
+#> 18048                                                                                   NA
+#> 20207                                                                          I9_OTHHEART
+#> 22249                                                                        I9_VHD_EXNONE
+#> 22725                                                                         I9_PULMHEART
+#> 23614                                                                                 <NA>
+#> 24603                                                                          FG_OTHHEART
+#> 27414                                                                                   NA
+#> 33264                                                                         FG_PULMHEART
+#> 35220                                                                                   NA
+#> 35231                                                                       I9_OTHILLHEART
+#> 36931 41204#I259: Output from GWAS pipeline using Phesant derived variables from UKBiobank
+#> 37302                                                                I9_OTHILLHEART_EXNONE
+#> 37894 41202#I251: Output from GWAS pipeline using Phesant derived variables from UKBiobank
+#> 38319                                                                               I9_IHD
+#> 38448                                                                           I9_RHEUFEV
+#> 38602                                                                                 <NA>
+#> 41994                                                                         I9_ISCHHEART
+#> 42095                                                                                   NA
+#> 42882                                                                       I9_SECONDRIGHT
+#> 43747                                                                                   NA
+#> 45294                                                                                 <NA>
+#> 46126                                                                               I9_VHD
+#> 46689 41204#I258: Output from GWAS pipeline using Phesant derived variables from UKBiobank
+#>       mr     nsnp  doi coverage study_design priority sd
+#> 7958   1 16380466 <NA>     <NA>         <NA>        0 NA
+#> 10829  1  9851867 <NA>     <NA>         <NA>        1 NA
+#> 12268  1 15478580 <NA>     <NA>         <NA>        0 NA
+#> 14221  1  9851867 <NA>     <NA>         <NA>        1 NA
+#> 14897  1  9455779 <NA>     <NA>         <NA>        1 NA
+#> 15028  1 16380466 <NA>     <NA>         <NA>        0 NA
+#> 16883  1  9851867 <NA>     <NA>         <NA>        1 NA
+#> 18046  1 10894596 <NA>     <NA>         <NA>        1 NA
+#> 18048  1  9811287 <NA>     <NA>         <NA>        0 NA
+#> 20207  1 16380466 <NA>     <NA>         <NA>        0 NA
+#> 22249  1 16380466 <NA>     <NA>         <NA>        0 NA
+#> 22725  1 16380466 <NA>     <NA>         <NA>        0 NA
+#> 23614  1    79129 <NA>     <NA>         <NA>        1 NA
+#> 24603  1 16380466 <NA>     <NA>         <NA>        0 NA
+#> 27414  1  2415020 <NA>     <NA>         <NA>        0 NA
+#> 33264  1 16380466 <NA>     <NA>         <NA>        0 NA
+#> 35220  1 13295130 <NA>     <NA>         <NA>        0 NA
+#> 35231  1 16380177 <NA>     <NA>         <NA>        0 NA
+#> 36931  1  9851867 <NA>     <NA>         <NA>        1 NA
+#> 37302  1 16380466 <NA>     <NA>         <NA>        0 NA
+#> 37894  1  9851867 <NA>     <NA>         <NA>        1 NA
+#> 38319  1 16380466 <NA>     <NA>         <NA>        0 NA
+#> 38448  1 16380466 <NA>     <NA>         <NA>        0 NA
+#> 38602  1  2420361 <NA>     <NA>         <NA>        2 NA
+#> 41994  1 16380466 <NA>     <NA>         <NA>        0 NA
+#> 42095  1 13586589 <NA>     <NA>         <NA>        0 NA
+#> 42882  1 16380459 <NA>     <NA>         <NA>        0 NA
+#> 43747  1 13295130 <NA>     <NA>         <NA>        0 NA
+#> 45294  1   540233 <NA>     <NA>         <NA>        3 NA
+#> 46126  1 16380358 <NA>     <NA>         <NA>        0 NA
+#> 46689  1  9851867 <NA>     <NA>         <NA>        1 NA
+

The most recent CARDIOGRAM GWAS is ID number ieu-a-7. We +can extract the BMI SNPs from this GWAS as follows:

+
+chd_out_dat1 <- extract_outcome_data(
+    snps = bmi_exp_dat$SNP,
+    outcomes = 'ieu-a-7'
+)
+

The extract_outcome_data() function is flexible. The +snps argument only requires an array of rsIDs, and the +outcomes argument can be a vector of outcomes, e.g.

+
+chd_out_dat2 <- extract_outcome_data(
+    snps = c("rs234", "rs17097147"),
+    outcomes = c('ieu-a-2', 'ieu-a-7')
+)
+

will extract the two SNPs from each of the outcomes +ieu-a-2 and ieu-a-7.

+
+
+

LD proxies +

+

By default if a particular requested SNP is not present in the +outcome GWAS then a SNP (proxy) that is in LD with the requested SNP +(target) will be searched for instead. LD proxies are defined using 1000 +genomes European sample data. The effect of the proxy SNP on the outcome +is returned, along with the proxy SNP, the effect allele of the proxy +SNP, and the corresponding allele (in phase) for the target SNP.

+

The parameters for handling LD proxies are as follows:

+
    +
  • +proxies = TRUE or FALSE (TRUE by default)
  • +
  • +rsq = numeric value of minimum rsq to find a proxy. +Default is 0.8, minimum is 0.6
  • +
  • +palindromes = Allow palindromic SNPs? Default is 1 +(yes)
  • +
  • +maf_threshold = If palindromes allowed then what is the +maximum minor allele frequency of palindromes allowed? Default is +0.3.
  • +
+
+
+

Using local GWAS summary data +

+

If you have GWAS summary data that is not present in IEU GWAS +database, this can still be used to perform analysis.

+

Supposing there is a GWAS summary file called “gwas_summary.csv” with +e.g. 2 million rows and it looks like this:

+
rsid,effect,SE,a1,a2,a1_freq,p-value,Units,Gene,n
+rs10767664,0.19,0.030612245,A,T,0.78,5.00E-26,kg/m2,BDNF,225238
+rs13078807,0.1,0.020408163,G,A,0.2,4.00E-11,kg/m2,CADM2,221431
+rs1514175,0.07,0.020408163,A,G,0.43,8.00E-14,kg/m2,TNNI3K,207641
+rs1558902,0.39,0.020408163,A,T,0.42,5.00E-120,kg/m2,FTO,222476
+...
+...
+

To extract the exposure SNPs from this data, we would use the +following command:

+
+outcome_dat <- read_outcome_data(
+    snps = bmi_exp_dat$SNP,
+    filename = "gwas_summary.csv",
+    sep = ",",
+    snp_col = "rsid",
+    beta_col = "effect",
+    se_col = "SE",
+    effect_allele_col = "a1",
+    other_allele_col = "a2",
+    eaf_col = "a1_freq",
+    pval_col = "p-value",
+    units_col = "Units",
+    gene_col = "Gene",
+    samplesize_col = "n"
+)
+

This returns an outcome data frame with only the SNPs that were +requested (if those SNPs were present in the “gwas_summary.csv” +file).

+
+
+

Outcome data format +

+

The extract_outcome_data function returns a table of SNP +effects for the requested SNPs on the requested outcomes. The format of +the data is similar to the exposure data format, except the main columns +are as follows:

+
    +
  • SNP
  • +
  • beta.outcome
  • +
  • se.outcome
  • +
  • samplesize.outcome
  • +
  • ncase.outcome
  • +
  • ncontrol.outcome
  • +
  • pval.outcome
  • +
  • eaf.outcome
  • +
  • effect_allele.outcom
  • +
  • other_allele.outcome
  • +
  • units.outcome
  • +
  • outcome
  • +
  • consortium.outcome
  • +
  • year.outcome
  • +
  • pmid.outcome
  • +
  • id.outcome
  • +
  • originalname.outcome
  • +
  • proxy.outcome
  • +
  • target_snp.outcome
  • +
  • proxy_snp.outcome
  • +
  • target_a1.outcome
  • +
  • target_a2.outcome
  • +
  • proxy_a1.outcome
  • +
  • proxy_a2.outcome
  • +
  • mr_keep.outcome
  • +
  • data_source.outcome
  • +
+
+
+

More advanced use of local data +

+

We have developed a summary data format called “GWAS VCF”, which is +designed to store GWAS results in a strict and performant way. It is +possible to use this format with the TwoSampleMR package. Going down +this avenue also allows you to use LD proxy functionality using your own +LD reference files (or ones that we provide). For more details, see this +package that explains the format and how to query it in R:

+

https://github.com/mrcieu/gwasvcf

+

and this package for how to connect the data to other packages +including TwoSampleMR

+

https://github.com/MRCIEU/gwasglue

+
+
+
+ + + +
+ + + +
+
+ + + + + + + diff --git a/docs/articles/perform_mr.html b/docs/articles/perform_mr.html new file mode 100644 index 00000000..60fa35fe --- /dev/null +++ b/docs/articles/perform_mr.html @@ -0,0 +1,1261 @@ + + + + + + + +Perform MR • TwoSampleMR + + + + + + + + + + + + + + + Skip to contents + + +
+ + + + +
+
+ + + + +
+

Introduction +

+

Let’s continue with the example of BMI on CHD:

+
+bmi_exp_dat <- extract_instruments(outcomes = 'ieu-a-2')
+chd_out_dat <- extract_outcome_data(snps = bmi_exp_dat$SNP, outcomes = 'ieu-a-7')
+
+dat <- harmonise_data(bmi_exp_dat, chd_out_dat)
+#> Harmonising Body mass index || id:ieu-a-2 (ieu-a-2) and Coronary heart disease || id:ieu-a-7 (ieu-a-7)
+

Once the exposure and outcome data are harmonised, we have effects +and standard errors for each instrument SNP available for the exposure +and outcome traits. We can use this information to perform Mendelian +randomisation. To do this, simply run:

+
+res <- mr(dat)
+#> Analysing 'ieu-a-2' on 'ieu-a-7'
+res
+#>   id.exposure id.outcome                              outcome
+#> 1     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
+#> 2     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
+#> 3     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
+#> 4     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
+#> 5     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
+#>                        exposure                    method nsnp         b
+#> 1 Body mass index || id:ieu-a-2                  MR Egger   79 0.5024935
+#> 2 Body mass index || id:ieu-a-2           Weighted median   79 0.3870065
+#> 3 Body mass index || id:ieu-a-2 Inverse variance weighted   79 0.4459091
+#> 4 Body mass index || id:ieu-a-2               Simple mode   79 0.3401554
+#> 5 Body mass index || id:ieu-a-2             Weighted mode   79 0.3790910
+#>           se         pval
+#> 1 0.14396056 8.012590e-04
+#> 2 0.07639889 4.071091e-07
+#> 3 0.05898302 4.032020e-14
+#> 4 0.15001315 2.612742e-02
+#> 5 0.10221374 3.881092e-04
+

This returns a data frame of estimates of the causal effect of the +exposure on the outcome for a range of different MR methods.

+

If there were multiple exposures against multiple outcomes in +dat, the mr() function will perform each MR +method for each combination of exposure-outcome traits.

+
+
+

MR methods +

+

The list of available MR methods can be obtained:

+
+mr_method_list()
+#>                              obj
+#> 1                  mr_wald_ratio
+#> 2               mr_two_sample_ml
+#> 3            mr_egger_regression
+#> 4  mr_egger_regression_bootstrap
+#> 5               mr_simple_median
+#> 6             mr_weighted_median
+#> 7   mr_penalised_weighted_median
+#> 8                         mr_ivw
+#> 9                  mr_ivw_radial
+#> 10                    mr_ivw_mre
+#> 11                     mr_ivw_fe
+#> 12                mr_simple_mode
+#> 13              mr_weighted_mode
+#> 14         mr_weighted_mode_nome
+#> 15           mr_simple_mode_nome
+#> 16                       mr_raps
+#> 17                       mr_sign
+#> 18                        mr_uwr
+#>                                                         name PubmedID
+#> 1                                                 Wald ratio         
+#> 2                                         Maximum likelihood         
+#> 3                                                   MR Egger 26050253
+#> 4                                       MR Egger (bootstrap) 26050253
+#> 5                                              Simple median         
+#> 6                                            Weighted median         
+#> 7                                  Penalised weighted median         
+#> 8                                  Inverse variance weighted         
+#> 9                                                 IVW radial         
+#> 10 Inverse variance weighted (multiplicative random effects)         
+#> 11                 Inverse variance weighted (fixed effects)         
+#> 12                                               Simple mode         
+#> 13                                             Weighted mode         
+#> 14                                      Weighted mode (NOME)         
+#> 15                                        Simple mode (NOME)         
+#> 16                      Robust adjusted profile score (RAPS)         
+#> 17                                     Sign concordance test         
+#> 18                                     Unweighted regression         
+#>                                                    Description use_by_default
+#> 1                                                                        TRUE
+#> 2                                                                       FALSE
+#> 3                                                                        TRUE
+#> 4                                                                       FALSE
+#> 5                                                                       FALSE
+#> 6                                                                        TRUE
+#> 7                                                                       FALSE
+#> 8                                                                        TRUE
+#> 9                                                                       FALSE
+#> 10                                                                      FALSE
+#> 11                                                                      FALSE
+#> 12                                                                       TRUE
+#> 13                                                                       TRUE
+#> 14                                                                      FALSE
+#> 15                                                                      FALSE
+#> 16                                                                      FALSE
+#> 17 Tests for concordance of signs between exposure and outcome          FALSE
+#> 18                                     Doesn't use any weights          FALSE
+#>    heterogeneity_test
+#> 1               FALSE
+#> 2                TRUE
+#> 3                TRUE
+#> 4               FALSE
+#> 5               FALSE
+#> 6               FALSE
+#> 7               FALSE
+#> 8                TRUE
+#> 9                TRUE
+#> 10              FALSE
+#> 11              FALSE
+#> 12              FALSE
+#> 13              FALSE
+#> 14              FALSE
+#> 15              FALSE
+#> 16              FALSE
+#> 17              FALSE
+#> 18               TRUE
+

To perform them, they can be specified in the mr() +function, e.g. to only perform MR Egger regression and Inverse variance +weighted methods,

+
+mr(dat, method_list = c("mr_egger_regression", "mr_ivw"))
+#> Analysing 'ieu-a-2' on 'ieu-a-7'
+#>   id.exposure id.outcome                              outcome
+#> 1     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
+#> 2     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
+#>                        exposure                    method nsnp         b
+#> 1 Body mass index || id:ieu-a-2                  MR Egger   79 0.5024935
+#> 2 Body mass index || id:ieu-a-2 Inverse variance weighted   79 0.4459091
+#>           se        pval
+#> 1 0.14396056 8.01259e-04
+#> 2 0.05898302 4.03202e-14
+

By default, all the methods that are labelled TRUE in +the use_by_default column are used by the mr() +function.

+
+
+
+

Sensitivity analyses +

+
+

Heterogeneity statistics +

+

Some of the MR methods can also perform tests for heterogeneity. To +obtain those statistics:

+
+mr_heterogeneity(dat)
+#>   id.exposure id.outcome                              outcome
+#> 1     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
+#> 2     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
+#>                        exposure                    method        Q Q_df
+#> 1 Body mass index || id:ieu-a-2                  MR Egger 143.3046   77
+#> 2 Body mass index || id:ieu-a-2 Inverse variance weighted 143.6508   78
+#>         Q_pval
+#> 1 6.841585e-06
+#> 2 8.728420e-06
+

As with the mr() function, the +mr_heterogeneity() function can take an argument to only +perform heterogeneity tests using specified methods, e.g.

+
+mr_heterogeneity(dat, method_list = c("mr_egger_regression", "mr_ivw"))
+#>   id.exposure id.outcome                              outcome
+#> 1     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
+#> 2     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
+#>                        exposure                    method        Q Q_df
+#> 1 Body mass index || id:ieu-a-2                  MR Egger 143.3046   77
+#> 2 Body mass index || id:ieu-a-2 Inverse variance weighted 143.6508   78
+#>         Q_pval
+#> 1 6.841585e-06
+#> 2 8.728420e-06
+
+
+

Horizontal pleiotropy +

+

The intercept term in MR Egger regression can be a useful indication +of whether directional horizontal pleiotropy is driving the results of +an MR analysis. This can be obtained as follows:

+
+mr_pleiotropy_test(dat)
+#>   id.exposure id.outcome                              outcome
+#> 1     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
+#>                        exposure egger_intercept          se      pval
+#> 1 Body mass index || id:ieu-a-2    -0.001719304 0.003985962 0.6674266
+
+
+

Single SNP analysis +

+

To obtain the MR estimates using each of the SNPs singly we can do +the following:

+
+res_single <- mr_singlesnp(dat)
+

This returns a data.frame of results that is similar to the output +from mr() except it performs the analysis multiple times +for each exposure-outcome combination - each time using a different +single SNP to perform the analysis.

+

The method used to perform the single SNP MR is the Wald ratio by +default, though this can be changed, e.g. to use the fixed effects meta +analysis method instead:

+
+res_single <- mr_singlesnp(dat, single_method = "mr_meta_fixed")
+

The mr_singlesnp() function calculates the full MR using +all available SNPs as well, and by default it uses the IVW and MR Egger +methods. This can be specified as so:

+
+res_single <- mr_singlesnp(dat, all_method = "mr_two_sample_ml")
+

will perform only the maximum likelihood method for the combined +test.

+
+
+

Leave-one-out analysis +

+

It is possible to perform a leave-one-out analysis, where the MR is +performed again but leaving out each SNP in turn, to identify if a +single SNP is driving the association.

+
+res_loo <- mr_leaveoneout(dat)
+

By default the method used is the inverse variance weighted method, +but this can be changed by using the method argument.

+
+
+
+
+

Plots +

+

There are a few ways to visualise the results, listed below

+
+

Scatter plot +

+

We can depict the relationship of the SNP effects on the exposure +against the SNP effects on the outcome using a scatter plot.

+
+res <- mr(dat)
+#> Analysing 'ieu-a-2' on 'ieu-a-7'
+p1 <- mr_scatter_plot(res, dat)
+

A scatter plot is created for each exposure-outcome test, and stored +in p1 as a list of plots. For example, to plot the first +scatter plot:

+
+p1[[1]]
+

A scatter plot visualising the two-sample data points and the following fitted models; Inverse Variance Weighted, MR-Egger, Simple mode, Weighted median, and Weighted mode.

+

And to see how many plots there are:

+
+length(p1)
+#> [1] 1
+

Lines are drawn for each method used in mr(dat), the +slope of the line corresponding to the estimated causal effect. To limit +which lines are drawn, simply specify the desired methods, e.g. to only +draw MR Egger and IVW:

+
+res <- mr(dat, method_list = c("mr_egger_regression", "mr_ivw"))
+#> Analysing 'ieu-a-2' on 'ieu-a-7'
+p1 <- mr_scatter_plot(res, dat)
+

It is possible to save this plot using the ggsave() +function from the ggplot2 package, e.g. to save as a +pdf

+
+ggsave(p1[[1]], file = "filename.pdf", width = 7, height = 7)
+

or save as a png

+
+ggsave(p1[[1]], file = "filename.png", width = 7, height = 7)
+

See ?ggplot2::ggsave for more info.

+
+
+

Forest plot +

+

Use the mr_forest_plot() function to compare the MR +estimates using the different MR methods against the single SNP +tests.

+
+res_single <- mr_singlesnp(dat)
+p2 <- mr_forest_plot(res_single)
+p2[[1]]
+

A forest plot showing the estimated causal effects using each SNP separately, and the Inverse Variance Weighted and MR-Egger estimates using all the SNPs.

+

Here, the plot shows the causal effect as estimated using each of the +SNPs on their own, and comparing against the causal effect as estimated +using the methods that use all the SNPs.

+

To get plots that use different methods, specify them in the +mr_singlesnp() function:

+
+res_single <- mr_singlesnp(dat, all_method = c("mr_ivw", "mr_two_sample_ml"))
+p2 <- mr_forest_plot(res_single)
+p2[[1]]
+

An alternative forest plot showing the estimated causal effects using each SNP separately, and the Inverse Variance Weighted and Maximum Likelihood estimates using all the SNPs.

+
+
+

Leave-one-out plot +

+

Use the mr_leaveoneout_plot() function to visualise the +leave-one-out analysis:

+
+res_loo <- mr_leaveoneout(dat)
+p3 <- mr_leaveoneout_plot(res_loo)
+p3[[1]]
+

A leave one out plot showing the Inverse Variance Weighted estimate with each SNP omitted.

+

Specify the test to use +e.g. mr_leaveoneout(dat, method = mr_egger_regression) to +use MR-Egger regression.

+
+
+

Funnel plot +

+

Asymmetry in a funnel plot is useful for gauging the reliability of a +particular MR analysis. Funnel plots can be produced using the single +SNP results as follows:

+
+res_single <- mr_singlesnp(dat)
+p4 <- mr_funnel_plot(res_single)
+p4[[1]]
+

A funnel plot showing the causal effect for each SNP and the inverse variance weighted and MR-Egger estimates using all the SNPs.

+
+
+
+

1-to-many forest plot +

+

A 1-to-many MR analysis interrogates the effect of a single exposure +on multiple outcomes or multiple exposures on a single outcome. The +results of this analysis can be visualised using the 1-to-many forest +plot, with or without stratification on a categorical variable. From a +visual point of view, the function works best for 50 or fewer results +and is not really designed to handle more than a 100 results. If your +number of results is much greater than 50, it may be better to split +these across two separate plots. For example, if you have 100 sets of +results you could divide these equally across two plots and then combine +the two plots together in another programme like Powerpoint. The +function assumes the results are already in the right order for +plotting. As such, users are advised to sort their results according to +how they would like them to appear in the plot. Users can use their own +code to do this or they can use the sort_1_to_many() +function.

+
+

Step 1: generate 1-to-many MR results +

+
+exp_dat <- extract_instruments(outcomes = c(2, 100, 1032, 104, 1, 72, 999))
+table(exp_dat$exposure)
+chd_out_dat <- extract_outcome_data(
+  snps = exp_dat$SNP,
+  outcomes = 7
+)
+
+dat2 <- harmonise_data(
+  exposure_dat = exp_dat,
+  outcome_dat = chd_out_dat
+)
+res <- mr(dat2)
+
+
+

Step 2. Make the 1-to-many forest plot +

+
+

Example 1. Effect of multiple risk factors on coronary heart +disease +

+

In this example we wish to plot results from an MR analysis of the +effect of multiple exposures on coronary heart disease, with results +sorted by decreasing effect size (largest effect at the top of the plot) +and with one MR method for each unique exposure-outcome combination. We +will also make the size of each point estimate proportional to its +inverse variance. This is a useful way to draw attention towards the +most reliable results and away from results with very wide confidence +intervals. To specify the size of the point estimate, set the weight +argument to the name of the column in the data with the weight +information.

+
+res <- subset_on_method(res) # default is to subset on either the IVW method (>1 instrumental SNP) or Wald ratio method (1 instrumental SNP).
+res <- sort_1_to_many(res, b = "b", sort_action = 4) # this sorts results by decreasing effect size (largest effect at top of the plot)
+res <- split_exposure(res) # to keep the Y axis label clean we exclude the exposure ID labels from the exposure column
+res$weight <- 1/res$se
+
+min(exp(res$b - 1.96*res$se)) # identify value for 'lo' in forest_plot_1_to_many
+max(exp(res$b + 1.96*res$se)) # identify value for 'up' in forest_plot_1_to_many
+
+forest_plot_1_to_many(
+  res,
+  b = "b",
+  se = "se",
+  exponentiate = TRUE,
+  ao_slc = FALSE,
+  lo = 0.3,
+  up = 2.5,
+  TraitM = "exposure",
+  col1_width = 2,
+  by = NULL,
+  trans = "log2",
+  xlab = "OR for CHD per SD increase in risk factor (95% confidence interval)",
+  weight = "weight"
+)
+

It is also possible to add additional columns and column titles and +to choose the size of the text in the columns:

+
+res$pval<-formatC(res$pval, format = "e", digits = 2)
+forest_plot_1_to_many(
+  res,
+  b = "b",
+  se = "se",
+  exponentiate = TRUE,
+  ao_slc = FALSE,
+  lo = 0.3,
+  up = 2.5,
+  TraitM = "exposure",
+  by = NULL,
+  trans = "log2",
+  xlab = "OR for CHD per SD increase in risk factor (95% CI)",
+  weight = "weight",
+  subheading_size = 11,
+  col1_title = "Risk factor",
+  col1_width = 2.5,
+  col_text_size = 4,
+  addcols = c("nsnp", "pval"),
+  addcol_widths = c(1.0, 1.0),
+  addcol_titles = c("No. SNPs", "P-val")
+)
+

In my own workflow I prefer to to keep the plot free of axis and +column titles and to add them separately in a program like +powerpoint:

+
+forest_plot_1_to_many(
+  res,
+  b = "b",
+  se = "se",
+  exponentiate = TRUE,
+  ao_slc = FALSE,
+  lo = 0.3,
+  up = 3.0,
+  TraitM = "exposure",
+  col1_width = 2.0,
+  by = NULL,
+  trans = "log2",
+  xlab = "",
+  addcols = c("nsnp", "pval"),
+  weight = "weight",
+  col_text_size = 4,
+  addcol_widths = c(0.5, 1.0),
+  addcol_titles = c("", "")
+)
+
+
+

Example 2. MR results for multiple MR methods grouped by multiple +exposures +

+

In this next example we plot the results from an analysis of the +effect of multiple exposures on coronary heart disease using multiple +methods, with results grouped by exposure. We also want the result for +the IVW method to be given priority and to go above the other methods. +We also want the exposure with the largest IVW effect size to go the top +of the plot. We also set the TraitM argument to the column describing +the MR method. This is because we are grouping the results on the +exposures. Normally the row labels would correspond to the exposures but +in this example we want the row names to correspond to the MR +method.

+
+res <- mr(dat2)
+res <- split_exposure(res) # to keep the Y axis label clean we exclude the exposure ID labels from the exposure column
+
+res <-
+  sort_1_to_many(
+    res,
+    group = "exposure",
+    sort_action = 3,
+    priority = "Inverse variance weighted",
+    trait_m = "method"
+  )
+
+forest_plot_1_to_many(
+  res,
+  b = "b",
+  se = "se",
+  exponentiate = TRUE,
+  trans = "log2",
+  ao_slc = FALSE,
+  lo = 0.03,
+  up = 22,
+  col1_width = 2,
+  by = "exposure",
+  TraitM = "method",
+  xlab = "OR for CHD per SD increase in risk factor (95% confidence interval)",
+  subheading_size = 12,
+  col_text_size = 4
+)
+
+
+

Example 3. Stratify results on a grouping variable +

+

In this next example we plot the same results as above but with +results stratified by a grouping variable. We also select one MR method +for each unique exposure-outcome combination and sort the results by +decreasing effect size within each group (i.e. largest effect at the +top).

+
+res <- mr(dat2)
+res <- split_exposure(res)
+res <- subset_on_method(res)
+res$subcategory[res$exposure %in% c("Adiponectin", "Hip circumference", "Waist circumference")] <- "Group 1"
+res$subcategory[is.na(res$subcategory)] <- "Group 2"
+res$weight <- 1/res$se
+res <- sort_1_to_many(res, sort_action = 1, group = "subcategory")
+
+forest_plot_1_to_many(
+  res,
+  b = "b",
+  se = "se",
+  exponentiate = TRUE,
+  trans = "log2",
+  ao_slc = FALSE,
+  lo = 0.3,
+  up = 2.5,
+  TraitM = "exposure",
+  col_text_size = 4,
+  col1_width = 1.5,
+  by = "subcategory",
+  xlab = "OR for CHD per SD increase in risk factor (95% confidence interval)",
+  subheading_size = 14,
+  weight = "weight"
+)
+

In the above example we made up an arbitrary grouping variable called +“subcategory” with values “Group 1” and “Group 2”. Typically, however, +the grouping variable might correspond to something like a trait +ontology (e.g. anthropometric and glycemic traits) or study design +(e.g. MR and observational studies).

+
+
+

Example 4. Effect of BMI on 103 diseases +

+

The plot function works best with 50 or fewer rows and is not really +designed to handle more than a 100. Visualising a single-column forest +plot with 100 results is also quite difficult. If your number of results +is much greater than 50, it is advisable to split the results across two +different plots. In the example below we select BMI as the exposure and +test this against 103 diseases in the IEU GWAS database:

+
+exp_dat <- extract_instruments(outcomes = 2) # extract instruments for BMI
+ao <- available_outcomes()
+ao <- ao[ao$category == "Disease", ] # identify diseases
+ao <- ao[which(ao$ncase > 100), ]
+
+dis_dat <- extract_outcome_data(
+  snps = exp_dat$SNP,
+  outcomes = ao$id
+)
+
+dat3 <- harmonise_data(
+  exposure_dat = exp_dat,
+  outcome_dat = dis_dat
+)
+
+res <- mr(dat3, method_list = c("mr_wald_ratio", "mr_ivw"))
+res <- split_outcome(res) # to keep the Y axis label clean we exclude the exposure ID labels from the exposure column
+
+res <- sort_1_to_many(res, b = "b", sort_action = 4) # this sorts results by decreasing effect size (largest effect at top of the plot)
+

MR results for 103 diseases can be difficult to visualise in a +single-column forest plot. In my own workflow I would split these across +two plots and then join them together in a separate program, such as +Powerpoint, and do further refinements there. I typically save my plots +using the pdf() graphics device. In this particular example +the disease labels probably require some cleaning up (some are a bit +long) or alternatively the column text size could be made smaller. It is +also possible to change the colour of the plot and the shape of the +point estimates. Type ?forest_plot_1_to_many for further +details.

+
+res1 <- res[1:52, ]
+res2 <- res[53:103, ]
+
+plot1 <- forest_plot_1_to_many(
+  res1,
+  b = "b",
+  se = "se",
+  exponentiate = TRUE,
+  trans = "log2",
+  ao_slc = FALSE,
+  lo = 0.004,
+  up = 461,
+  col1_width = 2,
+  TraitM = "outcome",
+  col_text_size = 3,
+  xlab = ""
+)
+
+plot2 <- forest_plot_1_to_many(
+  res2,
+  b = "b",
+  se = "se",
+  exponentiate = TRUE,
+  trans = "log2",
+  ao_slc = FALSE,
+  lo = 0.004,
+  up = 461,
+  col1_width = 2,
+  TraitM = "outcome",
+  subheading_size = 11,
+  col_text_size = 3,
+  xlab = ""
+)
+
+plot1
+plot2
+
+pdf("plot1.pdf", height = 10, width = 8)
+plot1
+dev.off()
+
+
+
+
+
+

MR.RAPS: Many weak instruments analysis +

+

MR.RAPS (Robust Adjusted Profile Score) is a recently proposed method +that considers the measurement error in SNP-exposure effects, is +unbiased when there are many (e.g. hundreds of) weak instruments, and is +robust to systematic and idiosyncratic pleiotropy. See the arXiv preprint for more +detail about the statistical methodology.

+

MR.RAPS is implemented in the R package mr.raps that is +available on CRAN. It can be directly called from TwoSampleMR by

+
+res <- mr(dat, method_list = c("mr_raps"))
+

MR.RAPS comes with two main options: over.dispersion +(whether the method should consider systematic pleiotropy) and +loss.function (either "l2", +"huber", or "tukey"). The latter two loss +functions are robust to idiosyncratic pleiotropy. The default option is +over.dispersion = TRUE and +loss.function = "tukey". To change these options, modify +the parameters argument of mr() by (for +example)

+
+res <-
+  mr(
+    dat,
+    method_list = c("mr_raps"),
+    parameters = list(over.dispersion = FALSE, loss.function = "l2")
+  )
+
+
+
+

Reports +

+

A report can be generated that performs all MR analyses, sensitivity +analyses, and plots, and presents them in a single self-contained html +web page, word document, or pdf document.

+
+mr_report(dat)
+

By default this produces a html file in the current working +directory, but see the help pages on how to modify this.

+

This function will create a separate report file for every +exposure-outcome combination that is present in the dat +object.

+
+
+
+

MR Steiger directionality test +

+

This is an implementation of the method described here:

+

Hemani +G, Tilling K, Davey Smith G. Orienting the causal relationship +between imprecisely measured traits using GWAS summary data. +PLoS Genetics. 2017. 13(11): e1007081.

+

In MR it is assumed that the instruments influence the exposure first +and then the outcome through the exposure. But sometimes this is +difficult to evaluate, for example is a cis-acting SNP influencing gene +expression levels or DNA methylation levels first? The causal direction +between the hypothesised exposure and outcomes can be tested using the +Steiger test (Hemani, Tilling, and Davey Smith +2017). For example:

+
+out <- directionality_test(dat)
+#> r.exposure and/or r.outcome not present.
+#> Calculating approximate SNP-exposure and/or SNP-outcome correlations, assuming all are quantitative traits. Please pre-calculate r.exposure and/or r.outcome using get_r_from_lor() for any binary traits
+knitr::kable(out)
+ ++++++++++ + + + + + + + + + + + + + + + + + + + + +
id.exposureid.outcomeexposureoutcomesnp_r2.exposuresnp_r2.outcomecorrect_causal_directionsteiger_pval
ieu-a-2ieu-a-7Body mass index || id:ieu-a-2Coronary heart disease || id:ieu-a-70.01580820.0013505TRUE0
+

It calculates the variance explained in the exposure and the outcome +by the instrumenting SNPs, and tests if the variance in the outcome is +less than the exposure.

+

This test is, like many others, liable to give inaccurate causal +directions under some measurement error parameters in the exposure and +the outcome (e.g. if the outcome has much lower measurement precision +then its proportion of variance explained will be underestimated). +Sensitivity can be applied to evaluate the extent to which the inferred +causal direction is liable to measurement error, in two ways.

+
    +
  1. Provide estimates of measurement error for the exposure and the +outcome, and obtain an adjusted estimate of the causal direction
  2. +
  3. For all possible values of measurement error, identify the +proportion of the parameter space which supports the inferred causal +direction
  4. +
+

These tests are obtained using:

+
+mr_steiger(
+  p_exp = dat$pval.exposure,
+  p_out = dat$pval.outcome,
+  n_exp = dat$samplesize.exposure,
+  n_out = dat$samplesize.outcome,
+  r_xxo = 1,
+  r_yyo = 1,
+  r_exp=0
+)
+
+
+
+

Multivariable MR +

+

When SNPs instrument multiple potential exposures, for example in the +case of different lipid fractions, one method for overcoming this +problem is to estimate the influence of each lipid conditioning on the +effects of the SNPs on the other lipids. Multivariable MR can be +performed using the R package as follows. Practically speaking, this is +the process that needs to occur from the perspective of generating the +data in the correct format:

+
    +
  1. Get instruments for each exposure
  2. +
  3. Combine these into a set of all instruments
  4. +
  5. Clump these to avoid the possibility that e.g. a variant for +exposure 1 is in LD with a variant for exposure 2
  6. +
  7. Re-extract all the final clumped SNPs from (3) from all of the +exposures
  8. +
  9. Harmonise them all to be on the same effect allele
  10. +
  11. Use the multivariable MR method against these harmonised data
  12. +
+

Example - The GWAS IDs for HDL, LDL and total cholesterol are +ieu-a-299, ieu-a-300 and +ieu-a-302. The GWAS ID for coronary heart disease (CHD) is +ieu-a-7. In this example we will estimate the multivariable +effects of HDL, LDL and total cholesterol on CHD.

+
+id_exposure <- c("ieu-a-299", "ieu-a-300", "ieu-a-302")
+id_outcome <- "ieu-a-7"
+

First obtain the instruments for each lipid fraction. This entails +obtaining a combined set of SNPs including all instruments, and getting +those SNPs for each lipid fraction. Therefore, if there are e.g. 20 +instruments for each of 3 lipid fractions, but combined there are 30 +unique SNPs, then we need to extract each of the 30 SNPs from each lipid +fraction (exposure).

+
+mv_exposure_dat <- mv_extract_exposures(id_exposure)
+

Next, also extract those SNPs from the outcome.

+
+mv_outcome_dat <- extract_outcome_data(exposure_dat$SNP, id_outcome)
+

Once the data has been obtained, harmonise so that all are on the +same reference allele.

+
+mvdat <- mv_harmonise_data(mv_exposure_dat, mv_outcome_dat)
+#> Harmonising HDL cholesterol || id:ieu-a-299 (ieu-a-299) and Coronary heart disease || id:ieu-a-7 (ieu-a-7)
+

Finally, perform the multivariable MR analysis

+
+res <- mv_multiple(mvdat)
+

This generates a table of results.

+
+

Note about MV methods +

+

There are several different ways in which this analysis can be +formulated. e.g. consider 3 exposures against one outcome, one +could:

+
    +
  1. Fit all exposures together or fit one exposure at a time against the +residuals of the outcome that has been adjusted for the other outcomes. +The former is recommended by default in this R package through the +mv_multiple() function but the latter was how MV MR was +originally described by Burgess et al 2015 and can be done with +mv_residual().
  2. +
  3. Fitting all instruments for all exposures (default) or only fitting +the instruments for each exposure sequentially
  4. +
  5. Forcing the slopes through the origin (default) or allowing an +intercept term.
  6. +
+

With these three different parameters there are eight different ways +to do MV analysis. We recommend the default settings as described +above.

+
+
+

Note about visualisation +

+

Plots can be generated using the plots = TRUE argument +for mv_multiple() and mv_residual().

+

The current plots being generated are not necessarily adequate +because while they show the slope through the raw points, they do not +demonstrate that the raw points might be effectively different between +plots because they are conditional on the other exposures.

+
+
+

Using your own summary data +

+

If you want to perform analysis with your local summary data +(i.e. not in the OpenGWAS database) then use then look up the +mv_extract_exposures_local() function instead of the +mv_extract_exposures() function.

+
+
+
+
+

MR estimates when instruments are correlated +

+

In the examples shown so far it is assumed that instruments are +independent (i.e. they are not in linkage disequilibrium, LD). This is +to avoid ‘double counting’ effects. An alternative approach is to +estimate the MR effects accounting for the correlation between +variants.

+

The TwoSampleMR package has not implemented this yet, but the MendelianRandomization +R package by Olena Yavorska and Stephen Burgess does have this +functionality. We can use the TwoSampleMR package to extract, format and +harmonise data, and then convert to the format required by the +MendelianRandomization package. The IEU GWAS database server has the +individual level genetic data for ~500 Europeans in 1000 genomes data, +and can obtain the LD matrix for a set of SNPs using these data. For +example:

+
+snplist <- c("rs234", "rs1205")
+ld_mat <- ld_matrix(snplist)
+
+ld_mat
+#>            rs234_A_G rs1205_T_C
+#> rs234_A_G  1.0000000  0.0797023
+#> rs1205_T_C 0.0797023  1.0000000
+

Here ld_matrix() returns the LD correlation values (not +R2) for each pair of variants present in the 1000 genomes +data set.

+
+dat <- harmonise_data(
+  exposure_dat = bmi_exp_dat,
+  outcome_dat = chd_out_dat
+)
+#> Harmonising Body mass index || id:ieu-a-2 (ieu-a-2) and Coronary heart disease || id:ieu-a-7 (ieu-a-7)
+

Convert to the MRInput format for the +MendelianRandomization package:

+
+dat2 <- dat_to_MRInput(dat)
+#> Converting:
+#>  - exposure: Body mass index || id:ieu-a-2
+#>  - outcome: Coronary heart disease || id:ieu-a-7
+

This produces a list of MRInput objects that can be used +with the MendelianRandomization functions, e.g.

+
+MendelianRandomization::mr_ivw(dat2[[1]])
+#> 
+#> Inverse-variance weighted method
+#> (variants uncorrelated, random-effect model)
+#> 
+#> Number of Variants : 79 
+#> 
+#> ------------------------------------------------------------------
+#>  Method Estimate Std Error 95% CI       p-value
+#>     IVW    0.446     0.059 0.330, 0.562   0.000
+#> ------------------------------------------------------------------
+#> Residual standard error =  1.357 
+#> Heterogeneity test statistic (Cochran's Q) = 143.6508 on 78 degrees of freedom, (p-value = 0.0000). I^2 = 45.7%. 
+#> F statistic = 65.6.
+

Alternatively, convert to the MRInput format but also +obtaining the LD matrix for the instruments

+
+dat2 <- try(dat_to_MRInput(dat, get_correlation = TRUE))
+#> Converting:
+#>  - exposure: Body mass index || id:ieu-a-2
+#>  - outcome: Coronary heart disease || id:ieu-a-7
+#>  - obtaining LD matrix
+#> Please look at vignettes for options on running this locally if you need to run many instances of this command.
+#> Warning in ieugwasr::ld_matrix(variants = snps, with_alleles = with_alleles, : The following variants are not present in the LD reference panel
+#> rs2033529
+if (class(dat2) != "try-error") MendelianRandomization::mr_ivw(dat2[[1]], correl = TRUE)
+#> 
+#> Inverse-variance weighted method
+#> (variants correlated, random-effect model)
+#> 
+#> Number of Variants : 78 
+#> 
+#> ------------------------------------------------------------------
+#>  Method Estimate Std Error 95% CI       p-value
+#>     IVW    0.441     0.056 0.331, 0.551   0.000
+#> ------------------------------------------------------------------
+#> Residual standard error =  1.414 
+#> Heterogeneity test statistic (Cochran's Q) = 153.8519 on 77 degrees of freedom, (p-value = 0.0000). I^2 = 50.0%. 
+#> F statistic = 80.3. 
+#> 
+#> (Estimates with correlated variants are sensitive to the signs in the correlation matrix
+#>  - please ensure that your correlations are expressed with respect to the same effect alleles as your summarized association estimates.)
+
+
+
+

MR-MoE: Using a mixture of experts machine learning approach +

+

We recently developed MR-MoE, a method to choose the most appropriate +amongst several MR tests using a machine learning algorithm. Note that +the method is still under review, but full details are described here: +https://doi.org/10.1101/173682.

+

MR-MoE operates by taking a set of harmonised data, inferring some +characteristics about the dataset, and using those characteristics to +predict how well each of the different MR methods will perform on the +dataset, in terms of maximising power while minimising false discovery +rates.

+

In order to run the analysis you must download an RData object that +contains the trained random forests that are used to predict the +efficacy of each method. This can be downloaded from here:

+

dropbox.com/s/5la7y38od95swcf

+

Caution: this is a large file (approx 167Mb)

+

Once downloaded, read in the object and use the mr_moe() +function to perform the analysis. An example is shown here, estimating +the causal effect of BMI on coronary heart disease:

+
+# Extact instruments for BMI
+exposure_dat <- extract_instruments("ieu-a-2")
+
+# Get corresponding effects for CHD
+outcome_dat <- extract_outcome_data(exposure_dat$SNP, "ieu-a-7")
+
+# Harmonise
+dat <- harmonise_data(exposure_dat, outcome_dat)
+
+# Load the downloaded RData object. This loads the rf object
+load("rf.rdata")
+
+# Obtain estimates from all methods, and generate data metrics
+res_all <- mr_wrapper(dat)
+
+# MR-MoE - predict the performance of each method
+res_moe <- mr_moe(res_all, rf)
+

The function does the following:

+
    +
  1. Performs MR using each of 11 MR methods
  2. +
  3. Applies Steiger filtering or heterogeneity filtering or both to +remove SNPs that do not have substantially larger R2 with the +exposure than the outcome. Note - for binary traits ensure number of +cases, number of controls, and allele frequencies are available for each +SNP. For continuous traits make sure the p-value and sample size is +available. The function infers if a trait is binary or continuous based +on the units.exposure and units.outcome columns - binary traits must +have those values set to ‘log odds’
  4. +
  5. Performs the 14 MR methods again but using the subset of SNPs that +survive Steiger filtering
  6. +
  7. Generates meta data about the summary data to predict the most +reliable of the 28 methods applied.
  8. +
+

For every exposure / outcome combination in the dat +object, the MR-MoE method is applied. The function returns a list which +is as long as the number of exposure / outcome combinations. In this +case, it will be of length 1, containing the result for BMI on CHD.

+

The result object itself is a list with the following elements:

+
    +
  • +estimates (results from each MR)
  • +
  • +heterogeneity (results from heterogeneity for different +filtering approaches)
  • +
  • +directional_pleiotropy (egger intercepts)
  • +
  • +info (metrics used to generate MOE)
  • +
+

Looking at the estimates, we see that there is a column +called MOE which is the predicted AUROC curve performance +of each method.

+
+
+
+

Post MR results management +

+

The TwoSampleMR package also provides the following functions for +managing or editing MR results.

+
+

Split outcome names +

+

The outcome column in the output of mr() combines the original +outcome name with the outcome trait ID.

+
+head(res)
+#> $result
+#>   id.exposure                        exposure id.outcome
+#> 1   ieu-a-299 HDL cholesterol || id:ieu-a-299    ieu-a-7
+#> 2   ieu-a-300 LDL cholesterol || id:ieu-a-300    ieu-a-7
+#> 3   ieu-a-302   Triglycerides || id:ieu-a-302    ieu-a-7
+#>                                outcome nsnp           b         se         pval
+#> 1 Coronary heart disease || id:ieu-a-7   79 -0.08919724 0.05970552 1.351879e-01
+#> 2 Coronary heart disease || id:ieu-a-7   68  0.37853543 0.04976846 2.828614e-14
+#> 3 Coronary heart disease || id:ieu-a-7   42  0.13584165 0.06738291 4.380354e-02
+

The outcome column can be split into separate columns for the id and +outcome name using the split_outcome function:

+
+res <- mr(dat)
+#> Analysing 'ieu-a-2' on 'ieu-a-7'
+split_outcome(res)
+#>   id.exposure id.outcome                outcome                      exposure
+#> 1     ieu-a-2    ieu-a-7 Coronary heart disease Body mass index || id:ieu-a-2
+#> 2     ieu-a-2    ieu-a-7 Coronary heart disease Body mass index || id:ieu-a-2
+#> 3     ieu-a-2    ieu-a-7 Coronary heart disease Body mass index || id:ieu-a-2
+#> 4     ieu-a-2    ieu-a-7 Coronary heart disease Body mass index || id:ieu-a-2
+#> 5     ieu-a-2    ieu-a-7 Coronary heart disease Body mass index || id:ieu-a-2
+#>                      method nsnp         b         se         pval
+#> 1                  MR Egger   79 0.5024935 0.14396056 8.012590e-04
+#> 2           Weighted median   79 0.3870065 0.07717818 5.318417e-07
+#> 3 Inverse variance weighted   79 0.4459091 0.05898302 4.032020e-14
+#> 4               Simple mode   79 0.3401554 0.15276076 2.885059e-02
+#> 5             Weighted mode   79 0.3790910 0.10761091 7.173381e-04
+
+
+

Split exposure names +

+

Similarly to the outcome column, the exposure column in the output of +mr() combines the original exposure name with the exposure +trait ID. This can be split into separate columns for the id and +exposure name using the split_exposure function.

+
+
+

Generate odds ratios with 95% confidence intervals +

+

Users can convert log odds ratios into odds ratios with 95% +confidence intervals using:

+
+generate_odds_ratios(res)
+#>   id.exposure id.outcome                              outcome
+#> 1     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
+#> 2     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
+#> 3     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
+#> 4     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
+#> 5     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
+#>                        exposure                    method nsnp         b
+#> 1 Body mass index || id:ieu-a-2                  MR Egger   79 0.5024935
+#> 2 Body mass index || id:ieu-a-2           Weighted median   79 0.3870065
+#> 3 Body mass index || id:ieu-a-2 Inverse variance weighted   79 0.4459091
+#> 4 Body mass index || id:ieu-a-2               Simple mode   79 0.3401554
+#> 5 Body mass index || id:ieu-a-2             Weighted mode   79 0.3790910
+#>           se         pval      lo_ci     up_ci       or or_lci95 or_uci95
+#> 1 0.14396056 8.012590e-04 0.22033081 0.7846562 1.652838 1.246489 2.191653
+#> 2 0.07717818 5.318417e-07 0.23573724 0.5382757 1.472566 1.265842 1.713051
+#> 3 0.05898302 4.032020e-14 0.33030238 0.5615158 1.561909 1.391389 1.753328
+#> 4 0.15276076 2.885059e-02 0.04074434 0.6395665 1.405166 1.041586 1.895659
+#> 5 0.10761091 7.173381e-04 0.16817361 0.5900084 1.460956 1.183142 1.804004
+
+
+

Subset on method +

+

It is sometimes useful to subset results on MR method, so that there +is one unique result for each exposure-outcome combination:

+
+subset_on_method(res)
+#>   id.exposure id.outcome                              outcome
+#> 3     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
+#>                        exposure                    method nsnp         b
+#> 3 Body mass index || id:ieu-a-2 Inverse variance weighted   79 0.4459091
+#>           se        pval
+#> 3 0.05898302 4.03202e-14
+

The default is to subset on the IVW method when >1 SNP is +available and to use the Wald ratio method when a single SNP is +available. Users can specify which multi-SNP method to subset on.

+
+
+

Combine all results +

+

It is often useful to combine all results and study level +characterists into a single dataframe or table, e.g. for sharing results +with collaborators or when the user wishes to present all results in a +single table or figure. This can be done using the +combine_all_mrresults() function:

+
+res <- mr(dat)
+het <- mr_heterogeneity(dat)
+plt <- mr_pleiotropy_test(dat)
+sin <- mr_singlesnp(dat)
+all_res <-
+  combine_all_mrresults(
+    res,
+    het,
+    plt,
+    sin,
+    ao_slc = TRUE,
+    Exp = TRUE,
+    split.exposure = FALSE,
+    split.outcome = TRUE
+  )
+head(all_res[, c(
+  "Method",
+  "outcome",
+  "exposure",
+  "nsnp",
+  "b",
+  "se",
+  "pval",
+  "intercept",
+  "intercept_se",
+  "intercept_pval",
+  "Q",
+  "Q_df",
+  "Q_pval",
+  "consortium",
+  "ncase",
+  "ncontrol",
+  "pmid",
+  "population"
+)])
+

This combines all results from mr(), +mr_heterogeneity(), mr_pleiotropy_test() and +mr_singlesnp() into a single dataframe. It also merges the +results with outcome study level characteristics from the +available_outcomes() function, including sample size +characteristics. If requested, it also exponentiates results (e.g. if +the user wants log odds ratio converted into odds ratios with 95 percent +confidence intervals).

+
+
+
+

References +

+
+
+Hemani, Gibran, Kate Tilling, and George Davey Smith. 2017. +“Orienting the Causal Relationship Between Imprecisely Measured +Traits Using GWAS Summary Data.” PLOS Genetics 13 (11): +e1007081. https://doi.org/10.1371/journal.pgen.1007081. +
+
+
+
+
+ + + +
+ + + +
+
+ + + + + + + diff --git a/docs/articles/perform_mr_files/figure-html/unnamed-chunk-18-1.png b/docs/articles/perform_mr_files/figure-html/unnamed-chunk-18-1.png new file mode 100644 index 00000000..b36e16e9 Binary files /dev/null and b/docs/articles/perform_mr_files/figure-html/unnamed-chunk-18-1.png differ diff --git a/docs/articles/perform_mr_files/figure-html/unnamed-chunk-23-1.png b/docs/articles/perform_mr_files/figure-html/unnamed-chunk-23-1.png new file mode 100644 index 00000000..5a2bbcf8 Binary files /dev/null and b/docs/articles/perform_mr_files/figure-html/unnamed-chunk-23-1.png differ diff --git a/docs/articles/perform_mr_files/figure-html/unnamed-chunk-24-1.png b/docs/articles/perform_mr_files/figure-html/unnamed-chunk-24-1.png new file mode 100644 index 00000000..7f4e343c Binary files /dev/null and b/docs/articles/perform_mr_files/figure-html/unnamed-chunk-24-1.png differ diff --git a/docs/articles/perform_mr_files/figure-html/unnamed-chunk-25-1.png b/docs/articles/perform_mr_files/figure-html/unnamed-chunk-25-1.png new file mode 100644 index 00000000..14e634f0 Binary files /dev/null and b/docs/articles/perform_mr_files/figure-html/unnamed-chunk-25-1.png differ diff --git a/docs/articles/perform_mr_files/figure-html/unnamed-chunk-26-1.png b/docs/articles/perform_mr_files/figure-html/unnamed-chunk-26-1.png new file mode 100644 index 00000000..ff2b3b46 Binary files /dev/null and b/docs/articles/perform_mr_files/figure-html/unnamed-chunk-26-1.png differ diff --git a/docs/authors.html b/docs/authors.html new file mode 100644 index 00000000..a615f63d --- /dev/null +++ b/docs/authors.html @@ -0,0 +1,126 @@ + +Authors and Citation • TwoSampleMR + Skip to contents + + +
+
+
+ +
+

Authors

+ +
  • +

    Gibran Hemani. Author, maintainer. +

    +
  • +
  • +

    Philip Haycock. Author. +

    +
  • +
  • +

    Jie Zheng. Author. +

    +
  • +
  • +

    Tom Gaunt. Author. +

    +
  • +
  • +

    Ben Elsworth. Author. +

    +
  • +
  • +

    Tom Palmer. Author. +

    +
  • +
+ +
+

Citation

+

Source: inst/CITATION

+ +

Hemani G, Zheng J, Elsworth B, Wade KH, Baird D, Haberland V, Laurin C, Burgess S, Bowden J, Langdon R, Tan VY, Yarmolinsky J, Shihab HA, Timpson NJ, Evans DM, Relton C, Martin RM, Davey Smith G, Gaunt TR, Haycock PC, The MR-Base Collaboration. The MR-Base platform supports systematic causal inference across the human phenome. eLife 2018;7:e34408. doi: 10.7554/eLife.34408

+
@Article{twosamplemr,
+  author = {G. Hemani and J. Zheng and B. Elsworth and K. Wade and D. Baird and V. Haberland and C. Laurin and S. Burgess and J. Bowden and R. Langdon and V.Y. Tan and J. Yarmolinsky and H.A. Shibab and N.J. Timpson and D.M. Evans and C. Relton and R.M. Martin and G. {Davey Smith} and T.R. Gaunt and P.C. Haycock and {The MR-Base Collaboration}},
+  title = {The MR-Base platform supports systematic causal inference across the human phenome},
+  year = {2018},
+  volume = {7},
+  journal = {eLife},
+  pages = {e34408},
+  url = {https://elifesciences.org/articles/34408},
+  doi = {10.7554/eLife.34408},
+}
+

Hemani G, Tilling K, Davey Smith G (2017) Orienting the causal relationship between imprecisely measured traits using GWAS summary data. PLOS Genetics 13(11): e1007081. https://doi.org/10.1371/journal.pgen.1007081

+
@Article{mrsteiger,
+  author = {G. Hemani and K. Tilling and G. {Davey Smith}},
+  title = {Orienting the causal relationship between imprecisely measured traits using GWAS summary data},
+  journal = {PLoS Genetics},
+  year = {2017},
+  volume = {13},
+  number = {11},
+  pages = {e1007081},
+  doi = {10.1371/journal.pgen.1007081},
+  url = {https://doi.org/10.1371/journal.pgen.1007081},
+}
+
+ +
+ + +
+ + + +
+ + + + + + + diff --git a/docs/deps/bootstrap-5.3.1/bootstrap.bundle.min.js b/docs/deps/bootstrap-5.3.1/bootstrap.bundle.min.js new file mode 100644 index 00000000..e8f21f70 --- /dev/null +++ b/docs/deps/bootstrap-5.3.1/bootstrap.bundle.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v5.3.1 (https://getbootstrap.com/) + * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t=new Map,e={set(e,i,n){t.has(e)||t.set(e,new Map);const s=t.get(e);s.has(i)||0===s.size?s.set(i,n):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(s.keys())[0]}.`)},get:(e,i)=>t.has(e)&&t.get(e).get(i)||null,remove(e,i){if(!t.has(e))return;const n=t.get(e);n.delete(i),0===n.size&&t.delete(e)}},i="transitionend",n=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),s=t=>{t.dispatchEvent(new Event(i))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(n(t)):null,a=t=>{if(!o(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},l=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),c=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?c(t.parentNode):null},h=()=>{},d=t=>{t.offsetHeight},u=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,f=[],p=()=>"rtl"===document.documentElement.dir,m=t=>{var e;e=()=>{const e=u();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(f.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of f)t()})),f.push(e)):e()},g=(t,e=[],i=t)=>"function"==typeof t?t(...e):i,_=(t,e,n=!0)=>{if(!n)return void g(t);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let r=!1;const a=({target:n})=>{n===e&&(r=!0,e.removeEventListener(i,a),g(t))};e.addEventListener(i,a),setTimeout((()=>{r||s(e)}),o)},b=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},v=/[^.]*(?=\..*)\.|.*/,y=/\..*/,w=/::\d+$/,A={};let E=1;const T={mouseenter:"mouseover",mouseleave:"mouseout"},C=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${E++}`||t.uidEvent||E++}function x(t){const e=O(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function k(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function L(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=I(t);return C.has(o)||(o=t),[n,s,o]}function S(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=L(e,i,n);if(e in T){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=x(t),c=l[a]||(l[a]={}),h=k(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=O(r,e.replace(v,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return P(s,{delegateTarget:r}),n.oneOff&&N.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return P(n,{delegateTarget:t}),i.oneOff&&N.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function D(t,e,i,n,s){const o=k(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function $(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&D(t,e,i,r.callable,r.delegationSelector)}function I(t){return t=t.replace(y,""),T[t]||t}const N={on(t,e,i,n){S(t,e,i,n,!1)},one(t,e,i,n){S(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=L(e,i,n),a=r!==e,l=x(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))$(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(w,"");a&&!e.includes(s)||D(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;D(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=u();let s=null,o=!0,r=!0,a=!1;e!==I(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());const l=P(new Event(e,{bubbles:o,cancelable:!0}),i);return a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function P(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}function M(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function j(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const F={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${j(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${j(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=M(t.dataset[n])}return e},getDataAttribute:(t,e)=>M(t.getAttribute(`data-bs-${j(e)}`))};class H{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=o(e)?F.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...o(e)?F.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[n,s]of Object.entries(e)){const e=t[n],r=o(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(r))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${r}" but expected type "${s}".`)}var i}}class W extends H{constructor(t,i){super(),(t=r(t))&&(this._element=t,this._config=this._getConfig(i),e.set(this._element,this.constructor.DATA_KEY,this))}dispose(){e.remove(this._element,this.constructor.DATA_KEY),N.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){_(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return e.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.1"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const B=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return n(e)},z={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!l(t)&&a(t)))},getSelectorFromElement(t){const e=B(t);return e&&z.findOne(e)?e:null},getElementFromSelector(t){const e=B(t);return e?z.findOne(e):null},getMultipleElementsFromSelector(t){const e=B(t);return e?z.find(e):[]}},R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;N.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),l(this))return;const s=z.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))},q=".bs.alert",V=`close${q}`,K=`closed${q}`;class Q extends W{static get NAME(){return"alert"}close(){if(N.trigger(this._element,V).defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),N.trigger(this._element,K),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(Q,"close"),m(Q);const X='[data-bs-toggle="button"]';class Y extends W{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=Y.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}N.on(document,"click.bs.button.data-api",X,(t=>{t.preventDefault();const e=t.target.closest(X);Y.getOrCreateInstance(e).toggle()})),m(Y);const U=".bs.swipe",G=`touchstart${U}`,J=`touchmove${U}`,Z=`touchend${U}`,tt=`pointerdown${U}`,et=`pointerup${U}`,it={endCallback:null,leftCallback:null,rightCallback:null},nt={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class st extends H{constructor(t,e){super(),this._element=t,t&&st.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return it}static get DefaultType(){return nt}static get NAME(){return"swipe"}dispose(){N.off(this._element,U)}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),g(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&g(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(N.on(this._element,tt,(t=>this._start(t))),N.on(this._element,et,(t=>this._end(t))),this._element.classList.add("pointer-event")):(N.on(this._element,G,(t=>this._start(t))),N.on(this._element,J,(t=>this._move(t))),N.on(this._element,Z,(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const ot=".bs.carousel",rt=".data-api",at="next",lt="prev",ct="left",ht="right",dt=`slide${ot}`,ut=`slid${ot}`,ft=`keydown${ot}`,pt=`mouseenter${ot}`,mt=`mouseleave${ot}`,gt=`dragstart${ot}`,_t=`load${ot}${rt}`,bt=`click${ot}${rt}`,vt="carousel",yt="active",wt=".active",At=".carousel-item",Et=wt+At,Tt={ArrowLeft:ht,ArrowRight:ct},Ct={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},Ot={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class xt extends W{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=z.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===vt&&this.cycle()}static get Default(){return Ct}static get DefaultType(){return Ot}static get NAME(){return"carousel"}next(){this._slide(at)}nextWhenVisible(){!document.hidden&&a(this._element)&&this.next()}prev(){this._slide(lt)}pause(){this._isSliding&&s(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?N.one(this._element,ut,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void N.one(this._element,ut,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?at:lt;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&N.on(this._element,ft,(t=>this._keydown(t))),"hover"===this._config.pause&&(N.on(this._element,pt,(()=>this.pause())),N.on(this._element,mt,(()=>this._maybeEnableCycle()))),this._config.touch&&st.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of z.find(".carousel-item img",this._element))N.on(t,gt,(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(ct)),rightCallback:()=>this._slide(this._directionToOrder(ht)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new st(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=Tt[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=z.findOne(wt,this._indicatorsElement);e.classList.remove(yt),e.removeAttribute("aria-current");const i=z.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(yt),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===at,s=e||b(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>N.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r(dt).defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),d(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(yt),i.classList.remove(yt,c,l),this._isSliding=!1,r(ut)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return z.findOne(Et,this._element)}_getItems(){return z.find(At,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return p()?t===ct?lt:at:t===ct?at:lt}_orderToDirection(t){return p()?t===lt?ct:ht:t===lt?ht:ct}static jQueryInterface(t){return this.each((function(){const e=xt.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}N.on(document,bt,"[data-bs-slide], [data-bs-slide-to]",(function(t){const e=z.getElementFromSelector(this);if(!e||!e.classList.contains(vt))return;t.preventDefault();const i=xt.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===F.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),N.on(window,_t,(()=>{const t=z.find('[data-bs-ride="carousel"]');for(const e of t)xt.getOrCreateInstance(e)})),m(xt);const kt=".bs.collapse",Lt=`show${kt}`,St=`shown${kt}`,Dt=`hide${kt}`,$t=`hidden${kt}`,It=`click${kt}.data-api`,Nt="show",Pt="collapse",Mt="collapsing",jt=`:scope .${Pt} .${Pt}`,Ft='[data-bs-toggle="collapse"]',Ht={parent:null,toggle:!0},Wt={parent:"(null|element)",toggle:"boolean"};class Bt extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=z.find(Ft);for(const t of i){const e=z.getSelectorFromElement(t),i=z.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return Ht}static get DefaultType(){return Wt}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>Bt.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(N.trigger(this._element,Lt).defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(Pt),this._element.classList.add(Mt),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Mt),this._element.classList.add(Pt,Nt),this._element.style[e]="",N.trigger(this._element,St)}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(N.trigger(this._element,Dt).defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,d(this._element),this._element.classList.add(Mt),this._element.classList.remove(Pt,Nt);for(const t of this._triggerArray){const e=z.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Mt),this._element.classList.add(Pt),N.trigger(this._element,$t)}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(Nt)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=r(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(Ft);for(const e of t){const t=z.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=z.find(jt,this._config.parent);return z.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=Bt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}N.on(document,It,Ft,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of z.getMultipleElementsFromSelector(this))Bt.getOrCreateInstance(t,{toggle:!1}).toggle()})),m(Bt);var zt="top",Rt="bottom",qt="right",Vt="left",Kt="auto",Qt=[zt,Rt,qt,Vt],Xt="start",Yt="end",Ut="clippingParents",Gt="viewport",Jt="popper",Zt="reference",te=Qt.reduce((function(t,e){return t.concat([e+"-"+Xt,e+"-"+Yt])}),[]),ee=[].concat(Qt,[Kt]).reduce((function(t,e){return t.concat([e,e+"-"+Xt,e+"-"+Yt])}),[]),ie="beforeRead",ne="read",se="afterRead",oe="beforeMain",re="main",ae="afterMain",le="beforeWrite",ce="write",he="afterWrite",de=[ie,ne,se,oe,re,ae,le,ce,he];function ue(t){return t?(t.nodeName||"").toLowerCase():null}function fe(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function pe(t){return t instanceof fe(t).Element||t instanceof Element}function me(t){return t instanceof fe(t).HTMLElement||t instanceof HTMLElement}function ge(t){return"undefined"!=typeof ShadowRoot&&(t instanceof fe(t).ShadowRoot||t instanceof ShadowRoot)}const _e={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];me(s)&&ue(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});me(n)&&ue(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function be(t){return t.split("-")[0]}var ve=Math.max,ye=Math.min,we=Math.round;function Ae(){var t=navigator.userAgentData;return null!=t&&t.brands&&Array.isArray(t.brands)?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function Ee(){return!/^((?!chrome|android).)*safari/i.test(Ae())}function Te(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&me(t)&&(s=t.offsetWidth>0&&we(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&we(n.height)/t.offsetHeight||1);var r=(pe(t)?fe(t):window).visualViewport,a=!Ee()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function Ce(t){var e=Te(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Oe(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&ge(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function xe(t){return fe(t).getComputedStyle(t)}function ke(t){return["table","td","th"].indexOf(ue(t))>=0}function Le(t){return((pe(t)?t.ownerDocument:t.document)||window.document).documentElement}function Se(t){return"html"===ue(t)?t:t.assignedSlot||t.parentNode||(ge(t)?t.host:null)||Le(t)}function De(t){return me(t)&&"fixed"!==xe(t).position?t.offsetParent:null}function $e(t){for(var e=fe(t),i=De(t);i&&ke(i)&&"static"===xe(i).position;)i=De(i);return i&&("html"===ue(i)||"body"===ue(i)&&"static"===xe(i).position)?e:i||function(t){var e=/firefox/i.test(Ae());if(/Trident/i.test(Ae())&&me(t)&&"fixed"===xe(t).position)return null;var i=Se(t);for(ge(i)&&(i=i.host);me(i)&&["html","body"].indexOf(ue(i))<0;){var n=xe(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function Ie(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function Ne(t,e,i){return ve(t,ye(e,i))}function Pe(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function Me(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const je={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=be(i.placement),l=Ie(a),c=[Vt,qt].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return Pe("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:Me(t,Qt))}(s.padding,i),d=Ce(o),u="y"===l?zt:Vt,f="y"===l?Rt:qt,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=$e(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,A=Ne(v,w,y),E=l;i.modifiersData[n]=((e={})[E]=A,e.centerOffset=A-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Oe(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function Fe(t){return t.split("-")[1]}var He={top:"auto",right:"auto",bottom:"auto",left:"auto"};function We(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=t.isFixed,u=r.x,f=void 0===u?0:u,p=r.y,m=void 0===p?0:p,g="function"==typeof h?h({x:f,y:m}):{x:f,y:m};f=g.x,m=g.y;var _=r.hasOwnProperty("x"),b=r.hasOwnProperty("y"),v=Vt,y=zt,w=window;if(c){var A=$e(i),E="clientHeight",T="clientWidth";A===fe(i)&&"static"!==xe(A=Le(i)).position&&"absolute"===a&&(E="scrollHeight",T="scrollWidth"),(s===zt||(s===Vt||s===qt)&&o===Yt)&&(y=Rt,m-=(d&&A===w&&w.visualViewport?w.visualViewport.height:A[E])-n.height,m*=l?1:-1),s!==Vt&&(s!==zt&&s!==Rt||o!==Yt)||(v=qt,f-=(d&&A===w&&w.visualViewport?w.visualViewport.width:A[T])-n.width,f*=l?1:-1)}var C,O=Object.assign({position:a},c&&He),x=!0===h?function(t,e){var i=t.x,n=t.y,s=e.devicePixelRatio||1;return{x:we(i*s)/s||0,y:we(n*s)/s||0}}({x:f,y:m},fe(i)):{x:f,y:m};return f=x.x,m=x.y,l?Object.assign({},O,((C={})[y]=b?"0":"",C[v]=_?"0":"",C.transform=(w.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",C)):Object.assign({},O,((e={})[y]=b?m+"px":"",e[v]=_?f+"px":"",e.transform="",e))}const Be={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:be(e.placement),variation:Fe(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,We(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,We(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var ze={passive:!0};const Re={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=fe(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,ze)})),a&&l.addEventListener("resize",i.update,ze),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,ze)})),a&&l.removeEventListener("resize",i.update,ze)}},data:{}};var qe={left:"right",right:"left",bottom:"top",top:"bottom"};function Ve(t){return t.replace(/left|right|bottom|top/g,(function(t){return qe[t]}))}var Ke={start:"end",end:"start"};function Qe(t){return t.replace(/start|end/g,(function(t){return Ke[t]}))}function Xe(t){var e=fe(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function Ye(t){return Te(Le(t)).left+Xe(t).scrollLeft}function Ue(t){var e=xe(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ge(t){return["html","body","#document"].indexOf(ue(t))>=0?t.ownerDocument.body:me(t)&&Ue(t)?t:Ge(Se(t))}function Je(t,e){var i;void 0===e&&(e=[]);var n=Ge(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=fe(n),r=s?[o].concat(o.visualViewport||[],Ue(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Je(Se(r)))}function Ze(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function ti(t,e,i){return e===Gt?Ze(function(t,e){var i=fe(t),n=Le(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=Ee();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+Ye(t),y:l}}(t,i)):pe(e)?function(t,e){var i=Te(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):Ze(function(t){var e,i=Le(t),n=Xe(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=ve(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=ve(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+Ye(t),l=-n.scrollTop;return"rtl"===xe(s||i).direction&&(a+=ve(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(Le(t)))}function ei(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?be(s):null,r=s?Fe(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case zt:e={x:a,y:i.y-n.height};break;case Rt:e={x:a,y:i.y+i.height};break;case qt:e={x:i.x+i.width,y:l};break;case Vt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?Ie(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case Xt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Yt:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function ii(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.strategy,r=void 0===o?t.strategy:o,a=i.boundary,l=void 0===a?Ut:a,c=i.rootBoundary,h=void 0===c?Gt:c,d=i.elementContext,u=void 0===d?Jt:d,f=i.altBoundary,p=void 0!==f&&f,m=i.padding,g=void 0===m?0:m,_=Pe("number"!=typeof g?g:Me(g,Qt)),b=u===Jt?Zt:Jt,v=t.rects.popper,y=t.elements[p?b:u],w=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=Je(Se(t)),i=["absolute","fixed"].indexOf(xe(t).position)>=0&&me(t)?$e(t):t;return pe(i)?e.filter((function(t){return pe(t)&&Oe(t,i)&&"body"!==ue(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=ti(t,i,n);return e.top=ve(s.top,e.top),e.right=ye(s.right,e.right),e.bottom=ye(s.bottom,e.bottom),e.left=ve(s.left,e.left),e}),ti(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(pe(y)?y:y.contextElement||Le(t.elements.popper),l,h,r),A=Te(t.elements.reference),E=ei({reference:A,element:v,strategy:"absolute",placement:s}),T=Ze(Object.assign({},v,E)),C=u===Jt?T:A,O={top:w.top-C.top+_.top,bottom:C.bottom-w.bottom+_.bottom,left:w.left-C.left+_.left,right:C.right-w.right+_.right},x=t.modifiersData.offset;if(u===Jt&&x){var k=x[s];Object.keys(O).forEach((function(t){var e=[qt,Rt].indexOf(t)>=0?1:-1,i=[zt,Rt].indexOf(t)>=0?"y":"x";O[t]+=k[i]*e}))}return O}function ni(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?ee:l,h=Fe(n),d=h?a?te:te.filter((function(t){return Fe(t)===h})):Qt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=ii(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[be(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const si={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=be(g),b=l||(_!==g&&p?function(t){if(be(t)===Kt)return[];var e=Ve(t);return[Qe(t),e,Qe(e)]}(g):[Ve(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(be(i)===Kt?ni(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,A=new Map,E=!0,T=v[0],C=0;C=0,S=L?"width":"height",D=ii(e,{placement:O,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),$=L?k?qt:Vt:k?Rt:zt;y[S]>w[S]&&($=Ve($));var I=Ve($),N=[];if(o&&N.push(D[x]<=0),a&&N.push(D[$]<=0,D[I]<=0),N.every((function(t){return t}))){T=O,E=!1;break}A.set(O,N)}if(E)for(var P=function(t){var e=v.find((function(e){var i=A.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==P(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function oi(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function ri(t){return[zt,qt,Rt,Vt].some((function(e){return t[e]>=0}))}const ai={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=ii(e,{elementContext:"reference"}),a=ii(e,{altBoundary:!0}),l=oi(r,n),c=oi(a,s,o),h=ri(l),d=ri(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},li={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=ee.reduce((function(t,i){return t[i]=function(t,e,i){var n=be(t),s=[Vt,zt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[Vt,qt].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},ci={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=ei({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},hi={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=ii(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=be(e.placement),b=Fe(e.placement),v=!b,y=Ie(_),w="x"===y?"y":"x",A=e.modifiersData.popperOffsets,E=e.rects.reference,T=e.rects.popper,C="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,O="number"==typeof C?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),x=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,k={x:0,y:0};if(A){if(o){var L,S="y"===y?zt:Vt,D="y"===y?Rt:qt,$="y"===y?"height":"width",I=A[y],N=I+g[S],P=I-g[D],M=f?-T[$]/2:0,j=b===Xt?E[$]:T[$],F=b===Xt?-T[$]:-E[$],H=e.elements.arrow,W=f&&H?Ce(H):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},z=B[S],R=B[D],q=Ne(0,E[$],W[$]),V=v?E[$]/2-M-q-z-O.mainAxis:j-q-z-O.mainAxis,K=v?-E[$]/2+M+q+R+O.mainAxis:F+q+R+O.mainAxis,Q=e.elements.arrow&&$e(e.elements.arrow),X=Q?"y"===y?Q.clientTop||0:Q.clientLeft||0:0,Y=null!=(L=null==x?void 0:x[y])?L:0,U=I+K-Y,G=Ne(f?ye(N,I+V-Y-X):N,I,f?ve(P,U):P);A[y]=G,k[y]=G-I}if(a){var J,Z="x"===y?zt:Vt,tt="x"===y?Rt:qt,et=A[w],it="y"===w?"height":"width",nt=et+g[Z],st=et-g[tt],ot=-1!==[zt,Vt].indexOf(_),rt=null!=(J=null==x?void 0:x[w])?J:0,at=ot?nt:et-E[it]-T[it]-rt+O.altAxis,lt=ot?et+E[it]+T[it]-rt-O.altAxis:st,ct=f&&ot?function(t,e,i){var n=Ne(t,e,i);return n>i?i:n}(at,et,lt):Ne(f?at:nt,et,f?lt:st);A[w]=ct,k[w]=ct-et}e.modifiersData[n]=k}},requiresIfExists:["offset"]};function di(t,e,i){void 0===i&&(i=!1);var n,s,o=me(e),r=me(e)&&function(t){var e=t.getBoundingClientRect(),i=we(e.width)/t.offsetWidth||1,n=we(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=Le(e),l=Te(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==ue(e)||Ue(a))&&(c=(n=e)!==fe(n)&&me(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:Xe(n)),me(e)?((h=Te(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=Ye(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function ui(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var fi={placement:"bottom",modifiers:[],strategy:"absolute"};function pi(){for(var t=arguments.length,e=new Array(t),i=0;iNumber.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(F.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...g(this._config.popperConfig,[t])}}_selectMenuItem({key:t,target:e}){const i=z.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>a(t)));i.length&&b(i,e,t===Ti,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=qi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=z.find(Ni);for(const i of e){const e=qi.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Ei,Ti].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Ii)?this:z.prev(this,Ii)[0]||z.next(this,Ii)[0]||z.findOne(Ii,t.delegateTarget.parentNode),o=qi.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}N.on(document,Si,Ii,qi.dataApiKeydownHandler),N.on(document,Si,Pi,qi.dataApiKeydownHandler),N.on(document,Li,qi.clearMenus),N.on(document,Di,qi.clearMenus),N.on(document,Li,Ii,(function(t){t.preventDefault(),qi.getOrCreateInstance(this).toggle()})),m(qi);const Vi="backdrop",Ki="show",Qi=`mousedown.bs.${Vi}`,Xi={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Yi={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class Ui extends H{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return Xi}static get DefaultType(){return Yi}static get NAME(){return Vi}show(t){if(!this._config.isVisible)return void g(t);this._append();const e=this._getElement();this._config.isAnimated&&d(e),e.classList.add(Ki),this._emulateAnimation((()=>{g(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(Ki),this._emulateAnimation((()=>{this.dispose(),g(t)}))):g(t)}dispose(){this._isAppended&&(N.off(this._element,Qi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=r(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),N.on(t,Qi,(()=>{g(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){_(t,this._getElement(),this._config.isAnimated)}}const Gi=".bs.focustrap",Ji=`focusin${Gi}`,Zi=`keydown.tab${Gi}`,tn="backward",en={autofocus:!0,trapElement:null},nn={autofocus:"boolean",trapElement:"element"};class sn extends H{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return en}static get DefaultType(){return nn}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),N.off(document,Gi),N.on(document,Ji,(t=>this._handleFocusin(t))),N.on(document,Zi,(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,N.off(document,Gi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=z.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===tn?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?tn:"forward")}}const on=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",rn=".sticky-top",an="padding-right",ln="margin-right";class cn{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,an,(e=>e+t)),this._setElementAttributes(on,an,(e=>e+t)),this._setElementAttributes(rn,ln,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,an),this._resetElementAttributes(on,an),this._resetElementAttributes(rn,ln)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&F.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=F.getDataAttribute(t,e);null!==i?(F.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(o(t))e(t);else for(const i of z.find(t,this._element))e(i)}}const hn=".bs.modal",dn=`hide${hn}`,un=`hidePrevented${hn}`,fn=`hidden${hn}`,pn=`show${hn}`,mn=`shown${hn}`,gn=`resize${hn}`,_n=`click.dismiss${hn}`,bn=`mousedown.dismiss${hn}`,vn=`keydown.dismiss${hn}`,yn=`click${hn}.data-api`,wn="modal-open",An="show",En="modal-static",Tn={backdrop:!0,focus:!0,keyboard:!0},Cn={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class On extends W{constructor(t,e){super(t,e),this._dialog=z.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new cn,this._addEventListeners()}static get Default(){return Tn}static get DefaultType(){return Cn}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||N.trigger(this._element,pn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(wn),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(N.trigger(this._element,dn).defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(An),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){N.off(window,hn),N.off(this._dialog,hn),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Ui({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new sn({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=z.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),d(this._element),this._element.classList.add(An),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,N.trigger(this._element,mn,{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){N.on(this._element,vn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),N.on(window,gn,(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),N.on(this._element,bn,(t=>{N.one(this._element,_n,(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(wn),this._resetAdjustments(),this._scrollBar.reset(),N.trigger(this._element,fn)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(N.trigger(this._element,un).defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(En)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(En),this._queueCallback((()=>{this._element.classList.remove(En),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=p()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=p()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=On.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}N.on(document,yn,'[data-bs-toggle="modal"]',(function(t){const e=z.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),N.one(e,pn,(t=>{t.defaultPrevented||N.one(e,fn,(()=>{a(this)&&this.focus()}))}));const i=z.findOne(".modal.show");i&&On.getInstance(i).hide(),On.getOrCreateInstance(e).toggle(this)})),R(On),m(On);const xn=".bs.offcanvas",kn=".data-api",Ln=`load${xn}${kn}`,Sn="show",Dn="showing",$n="hiding",In=".offcanvas.show",Nn=`show${xn}`,Pn=`shown${xn}`,Mn=`hide${xn}`,jn=`hidePrevented${xn}`,Fn=`hidden${xn}`,Hn=`resize${xn}`,Wn=`click${xn}${kn}`,Bn=`keydown.dismiss${xn}`,zn={backdrop:!0,keyboard:!0,scroll:!1},Rn={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class qn extends W{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return zn}static get DefaultType(){return Rn}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||N.trigger(this._element,Nn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new cn).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(Dn),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(Sn),this._element.classList.remove(Dn),N.trigger(this._element,Pn,{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(N.trigger(this._element,Mn).defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add($n),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(Sn,$n),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new cn).reset(),N.trigger(this._element,Fn)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new Ui({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():N.trigger(this._element,jn)}:null})}_initializeFocusTrap(){return new sn({trapElement:this._element})}_addEventListeners(){N.on(this._element,Bn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():N.trigger(this._element,jn))}))}static jQueryInterface(t){return this.each((function(){const e=qn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}N.on(document,Wn,'[data-bs-toggle="offcanvas"]',(function(t){const e=z.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this))return;N.one(e,Fn,(()=>{a(this)&&this.focus()}));const i=z.findOne(In);i&&i!==e&&qn.getInstance(i).hide(),qn.getOrCreateInstance(e).toggle(this)})),N.on(window,Ln,(()=>{for(const t of z.find(In))qn.getOrCreateInstance(t).show()})),N.on(window,Hn,(()=>{for(const t of z.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&qn.getOrCreateInstance(t).hide()})),R(qn),m(qn);const Vn={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Kn=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Qn=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,Xn=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!Kn.has(i)||Boolean(Qn.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Yn={allowList:Vn,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Un={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Gn={entry:"(string|element|function|null)",selector:"(string|element)"};class Jn extends H{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Yn}static get DefaultType(){return Un}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Gn)}_setContent(t,e,i){const n=z.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?o(e)?this._putElementInTemplate(r(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Xn(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return g(t,[this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const Zn=new Set(["sanitize","allowList","sanitizeFn"]),ts="fade",es="show",is=".modal",ns="hide.bs.modal",ss="hover",os="focus",rs={AUTO:"auto",TOP:"top",RIGHT:p()?"left":"right",BOTTOM:"bottom",LEFT:p()?"right":"left"},as={allowList:Vn,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},ls={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class cs extends W{constructor(t,e){if(void 0===vi)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return as}static get DefaultType(){return ls}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),N.off(this._element.closest(is),ns,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=N.trigger(this._element,this.constructor.eventName("show")),e=(c(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),N.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(es),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.on(t,"mouseover",h);this._queueCallback((()=>{N.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!N.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(es),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.off(t,"mouseover",h);this._activeTrigger.click=!1,this._activeTrigger[os]=!1,this._activeTrigger[ss]=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),N.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(ts,es),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(ts),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Jn({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(ts)}_isShown(){return this.tip&&this.tip.classList.contains(es)}_createPopper(t){const e=g(this._config.placement,[this,t,this._element]),i=rs[e.toUpperCase()];return bi(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return g(t,[this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...g(this._config.popperConfig,[e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)N.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===ss?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===ss?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");N.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?os:ss]=!0,e._enter()})),N.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?os:ss]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},N.on(this._element.closest(is),ns,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=F.getDataAttributes(this._element);for(const t of Object.keys(e))Zn.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=cs.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(cs);const hs={...cs.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},ds={...cs.DefaultType,content:"(null|string|element|function)"};class us extends cs{static get Default(){return hs}static get DefaultType(){return ds}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=us.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(us);const fs=".bs.scrollspy",ps=`activate${fs}`,ms=`click${fs}`,gs=`load${fs}.data-api`,_s="active",bs="[href]",vs=".nav-link",ys=`${vs}, .nav-item > ${vs}, .list-group-item`,ws={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},As={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class Es extends W{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return ws}static get DefaultType(){return As}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=r(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(N.off(this._config.target,ms),N.on(this._config.target,ms,bs,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=z.find(bs,this._config.target);for(const e of t){if(!e.hash||l(e))continue;const t=z.findOne(decodeURI(e.hash),this._element);a(t)&&(this._targetLinks.set(decodeURI(e.hash),e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(_s),this._activateParents(t),N.trigger(this._element,ps,{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))z.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(_s);else for(const e of z.parents(t,".nav, .list-group"))for(const t of z.prev(e,ys))t.classList.add(_s)}_clearActiveClass(t){t.classList.remove(_s);const e=z.find(`${bs}.${_s}`,t);for(const t of e)t.classList.remove(_s)}static jQueryInterface(t){return this.each((function(){const e=Es.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(window,gs,(()=>{for(const t of z.find('[data-bs-spy="scroll"]'))Es.getOrCreateInstance(t)})),m(Es);const Ts=".bs.tab",Cs=`hide${Ts}`,Os=`hidden${Ts}`,xs=`show${Ts}`,ks=`shown${Ts}`,Ls=`click${Ts}`,Ss=`keydown${Ts}`,Ds=`load${Ts}`,$s="ArrowLeft",Is="ArrowRight",Ns="ArrowUp",Ps="ArrowDown",Ms="Home",js="End",Fs="active",Hs="fade",Ws="show",Bs=":not(.dropdown-toggle)",zs='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Rs=`.nav-link${Bs}, .list-group-item${Bs}, [role="tab"]${Bs}, ${zs}`,qs=`.${Fs}[data-bs-toggle="tab"], .${Fs}[data-bs-toggle="pill"], .${Fs}[data-bs-toggle="list"]`;class Vs extends W{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),N.on(this._element,Ss,(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?N.trigger(e,Cs,{relatedTarget:t}):null;N.trigger(t,xs,{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Fs),this._activate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),N.trigger(t,ks,{relatedTarget:e})):t.classList.add(Ws)}),t,t.classList.contains(Hs)))}_deactivate(t,e){t&&(t.classList.remove(Fs),t.blur(),this._deactivate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),N.trigger(t,Os,{relatedTarget:e})):t.classList.remove(Ws)}),t,t.classList.contains(Hs)))}_keydown(t){if(![$s,Is,Ns,Ps,Ms,js].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=this._getChildren().filter((t=>!l(t)));let i;if([Ms,js].includes(t.key))i=e[t.key===Ms?0:e.length-1];else{const n=[Is,Ps].includes(t.key);i=b(e,t.target,n,!0)}i&&(i.focus({preventScroll:!0}),Vs.getOrCreateInstance(i).show())}_getChildren(){return z.find(Rs,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=z.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=z.findOne(t,i);s&&s.classList.toggle(n,e)};n(".dropdown-toggle",Fs),n(".dropdown-menu",Ws),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(Fs)}_getInnerElement(t){return t.matches(Rs)?t:z.findOne(Rs,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Vs.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(document,Ls,zs,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this)||Vs.getOrCreateInstance(this).show()})),N.on(window,Ds,(()=>{for(const t of z.find(qs))Vs.getOrCreateInstance(t)})),m(Vs);const Ks=".bs.toast",Qs=`mouseover${Ks}`,Xs=`mouseout${Ks}`,Ys=`focusin${Ks}`,Us=`focusout${Ks}`,Gs=`hide${Ks}`,Js=`hidden${Ks}`,Zs=`show${Ks}`,to=`shown${Ks}`,eo="hide",io="show",no="showing",so={animation:"boolean",autohide:"boolean",delay:"number"},oo={animation:!0,autohide:!0,delay:5e3};class ro extends W{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return oo}static get DefaultType(){return so}static get NAME(){return"toast"}show(){N.trigger(this._element,Zs).defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(eo),d(this._element),this._element.classList.add(io,no),this._queueCallback((()=>{this._element.classList.remove(no),N.trigger(this._element,to),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(N.trigger(this._element,Gs).defaultPrevented||(this._element.classList.add(no),this._queueCallback((()=>{this._element.classList.add(eo),this._element.classList.remove(no,io),N.trigger(this._element,Js)}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(io),super.dispose()}isShown(){return this._element.classList.contains(io)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){N.on(this._element,Qs,(t=>this._onInteraction(t,!0))),N.on(this._element,Xs,(t=>this._onInteraction(t,!1))),N.on(this._element,Ys,(t=>this._onInteraction(t,!0))),N.on(this._element,Us,(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=ro.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(ro),m(ro),{Alert:Q,Button:Y,Carousel:xt,Collapse:Bt,Dropdown:qi,Modal:On,Offcanvas:qn,Popover:us,ScrollSpy:Es,Tab:Vs,Toast:ro,Tooltip:cs}})); +//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/docs/deps/bootstrap-5.3.1/bootstrap.bundle.min.js.map b/docs/deps/bootstrap-5.3.1/bootstrap.bundle.min.js.map new file mode 100644 index 00000000..3863da8b --- /dev/null +++ b/docs/deps/bootstrap-5.3.1/bootstrap.bundle.min.js.map @@ -0,0 +1 @@ +{"version":3,"names":["elementMap","Map","Data","set","element","key","instance","has","instanceMap","get","size","console","error","Array","from","keys","remove","delete","TRANSITION_END","parseSelector","selector","window","CSS","escape","replace","match","id","triggerTransitionEnd","dispatchEvent","Event","isElement","object","jquery","nodeType","getElement","length","document","querySelector","isVisible","getClientRects","elementIsVisible","getComputedStyle","getPropertyValue","closedDetails","closest","summary","parentNode","isDisabled","Node","ELEMENT_NODE","classList","contains","disabled","hasAttribute","getAttribute","findShadowRoot","documentElement","attachShadow","getRootNode","root","ShadowRoot","noop","reflow","offsetHeight","getjQuery","jQuery","body","DOMContentLoadedCallbacks","isRTL","dir","defineJQueryPlugin","plugin","callback","$","name","NAME","JQUERY_NO_CONFLICT","fn","jQueryInterface","Constructor","noConflict","readyState","addEventListener","push","execute","possibleCallback","args","defaultValue","executeAfterTransition","transitionElement","waitForTransition","emulatedDuration","transitionDuration","transitionDelay","floatTransitionDuration","Number","parseFloat","floatTransitionDelay","split","getTransitionDurationFromElement","called","handler","target","removeEventListener","setTimeout","getNextActiveElement","list","activeElement","shouldGetNext","isCycleAllowed","listLength","index","indexOf","Math","max","min","namespaceRegex","stripNameRegex","stripUidRegex","eventRegistry","uidEvent","customEvents","mouseenter","mouseleave","nativeEvents","Set","makeEventUid","uid","getElementEvents","findHandler","events","callable","delegationSelector","Object","values","find","event","normalizeParameters","originalTypeEvent","delegationFunction","isDelegated","typeEvent","getTypeEvent","addHandler","oneOff","wrapFunction","relatedTarget","delegateTarget","call","this","handlers","previousFunction","domElements","querySelectorAll","domElement","hydrateObj","EventHandler","off","type","apply","bootstrapDelegationHandler","bootstrapHandler","removeHandler","Boolean","removeNamespacedHandlers","namespace","storeElementEvent","handlerKey","entries","includes","on","one","inNamespace","isNamespace","startsWith","elementEvent","slice","keyHandlers","trigger","jQueryEvent","bubbles","nativeDispatch","defaultPrevented","isPropagationStopped","isImmediatePropagationStopped","isDefaultPrevented","evt","cancelable","preventDefault","obj","meta","value","_unused","defineProperty","configurable","normalizeData","toString","JSON","parse","decodeURIComponent","normalizeDataKey","chr","toLowerCase","Manipulator","setDataAttribute","setAttribute","removeDataAttribute","removeAttribute","getDataAttributes","attributes","bsKeys","dataset","filter","pureKey","charAt","getDataAttribute","Config","Default","DefaultType","Error","_getConfig","config","_mergeConfigObj","_configAfterMerge","_typeCheckConfig","jsonConfig","constructor","configTypes","property","expectedTypes","valueType","prototype","RegExp","test","TypeError","toUpperCase","BaseComponent","super","_element","_config","DATA_KEY","dispose","EVENT_KEY","propertyName","getOwnPropertyNames","_queueCallback","isAnimated","getInstance","getOrCreateInstance","VERSION","eventName","getSelector","hrefAttribute","trim","SelectorEngine","concat","Element","findOne","children","child","matches","parents","ancestor","prev","previous","previousElementSibling","next","nextElementSibling","focusableChildren","focusables","map","join","el","getSelectorFromElement","getElementFromSelector","getMultipleElementsFromSelector","enableDismissTrigger","component","method","clickEvent","tagName","EVENT_CLOSE","EVENT_CLOSED","Alert","close","_destroyElement","each","data","undefined","SELECTOR_DATA_TOGGLE","Button","toggle","button","EVENT_TOUCHSTART","EVENT_TOUCHMOVE","EVENT_TOUCHEND","EVENT_POINTERDOWN","EVENT_POINTERUP","endCallback","leftCallback","rightCallback","Swipe","isSupported","_deltaX","_supportPointerEvents","PointerEvent","_initEvents","_start","_eventIsPointerPenTouch","clientX","touches","_end","_handleSwipe","_move","absDeltaX","abs","direction","add","pointerType","navigator","maxTouchPoints","DATA_API_KEY","ORDER_NEXT","ORDER_PREV","DIRECTION_LEFT","DIRECTION_RIGHT","EVENT_SLIDE","EVENT_SLID","EVENT_KEYDOWN","EVENT_MOUSEENTER","EVENT_MOUSELEAVE","EVENT_DRAG_START","EVENT_LOAD_DATA_API","EVENT_CLICK_DATA_API","CLASS_NAME_CAROUSEL","CLASS_NAME_ACTIVE","SELECTOR_ACTIVE","SELECTOR_ITEM","SELECTOR_ACTIVE_ITEM","KEY_TO_DIRECTION","ArrowLeft","ArrowRight","interval","keyboard","pause","ride","touch","wrap","Carousel","_interval","_activeElement","_isSliding","touchTimeout","_swipeHelper","_indicatorsElement","_addEventListeners","cycle","_slide","nextWhenVisible","hidden","_clearInterval","_updateInterval","setInterval","_maybeEnableCycle","to","items","_getItems","activeIndex","_getItemIndex","_getActive","order","defaultInterval","_keydown","_addTouchEventListeners","img","swipeConfig","_directionToOrder","endCallBack","clearTimeout","_setActiveIndicatorElement","activeIndicator","newActiveIndicator","elementInterval","parseInt","isNext","nextElement","nextElementIndex","triggerEvent","_orderToDirection","isCycling","directionalClassName","orderClassName","completeCallBack","_isAnimated","clearInterval","carousel","slideIndex","carousels","EVENT_SHOW","EVENT_SHOWN","EVENT_HIDE","EVENT_HIDDEN","CLASS_NAME_SHOW","CLASS_NAME_COLLAPSE","CLASS_NAME_COLLAPSING","CLASS_NAME_DEEPER_CHILDREN","parent","Collapse","_isTransitioning","_triggerArray","toggleList","elem","filterElement","foundElement","_initializeChildren","_addAriaAndCollapsedClass","_isShown","hide","show","activeChildren","_getFirstLevelChildren","activeInstance","dimension","_getDimension","style","scrollSize","complete","getBoundingClientRect","selected","triggerArray","isOpen","top","bottom","right","left","auto","basePlacements","start","end","clippingParents","viewport","popper","reference","variationPlacements","reduce","acc","placement","placements","beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite","modifierPhases","getNodeName","nodeName","getWindow","node","ownerDocument","defaultView","isHTMLElement","HTMLElement","isShadowRoot","applyStyles$1","enabled","phase","_ref","state","elements","forEach","styles","assign","effect","_ref2","initialStyles","position","options","strategy","margin","arrow","hasOwnProperty","attribute","requires","getBasePlacement","round","getUAString","uaData","userAgentData","brands","isArray","item","brand","version","userAgent","isLayoutViewport","includeScale","isFixedStrategy","clientRect","scaleX","scaleY","offsetWidth","width","height","visualViewport","addVisualOffsets","x","offsetLeft","y","offsetTop","getLayoutRect","rootNode","isSameNode","host","isTableElement","getDocumentElement","getParentNode","assignedSlot","getTrueOffsetParent","offsetParent","getOffsetParent","isFirefox","currentNode","css","transform","perspective","contain","willChange","getContainingBlock","getMainAxisFromPlacement","within","mathMax","mathMin","mergePaddingObject","paddingObject","expandToHashMap","hashMap","arrow$1","_state$modifiersData$","arrowElement","popperOffsets","modifiersData","basePlacement","axis","len","padding","rects","toPaddingObject","arrowRect","minProp","maxProp","endDiff","startDiff","arrowOffsetParent","clientSize","clientHeight","clientWidth","centerToReference","center","offset","axisProp","centerOffset","_options$element","requiresIfExists","getVariation","unsetSides","mapToStyles","_Object$assign2","popperRect","variation","offsets","gpuAcceleration","adaptive","roundOffsets","isFixed","_offsets$x","_offsets$y","_ref3","hasX","hasY","sideX","sideY","win","heightProp","widthProp","_Object$assign","commonStyles","_ref4","dpr","devicePixelRatio","roundOffsetsByDPR","computeStyles$1","_ref5","_options$gpuAccelerat","_options$adaptive","_options$roundOffsets","passive","eventListeners","_options$scroll","scroll","_options$resize","resize","scrollParents","scrollParent","update","hash","getOppositePlacement","matched","getOppositeVariationPlacement","getWindowScroll","scrollLeft","pageXOffset","scrollTop","pageYOffset","getWindowScrollBarX","isScrollParent","_getComputedStyle","overflow","overflowX","overflowY","getScrollParent","listScrollParents","_element$ownerDocumen","isBody","updatedList","rectToClientRect","rect","getClientRectFromMixedType","clippingParent","html","layoutViewport","getViewportRect","clientTop","clientLeft","getInnerBoundingClientRect","winScroll","scrollWidth","scrollHeight","getDocumentRect","computeOffsets","commonX","commonY","mainAxis","detectOverflow","_options","_options$placement","_options$strategy","_options$boundary","boundary","_options$rootBoundary","rootBoundary","_options$elementConte","elementContext","_options$altBoundary","altBoundary","_options$padding","altContext","clippingClientRect","mainClippingParents","clipperElement","getClippingParents","firstClippingParent","clippingRect","accRect","getClippingRect","contextElement","referenceClientRect","popperClientRect","elementClientRect","overflowOffsets","offsetData","multiply","computeAutoPlacement","flipVariations","_options$allowedAutoP","allowedAutoPlacements","allPlacements","allowedPlacements","overflows","sort","a","b","flip$1","_skip","_options$mainAxis","checkMainAxis","_options$altAxis","altAxis","checkAltAxis","specifiedFallbackPlacements","fallbackPlacements","_options$flipVariatio","preferredPlacement","oppositePlacement","getExpandedFallbackPlacements","referenceRect","checksMap","makeFallbackChecks","firstFittingPlacement","i","_basePlacement","isStartVariation","isVertical","mainVariationSide","altVariationSide","checks","every","check","_loop","_i","fittingPlacement","reset","getSideOffsets","preventedOffsets","isAnySideFullyClipped","some","side","hide$1","preventOverflow","referenceOverflow","popperAltOverflow","referenceClippingOffsets","popperEscapeOffsets","isReferenceHidden","hasPopperEscaped","offset$1","_options$offset","invertDistance","skidding","distance","distanceAndSkiddingToXY","_data$state$placement","popperOffsets$1","preventOverflow$1","_options$tether","tether","_options$tetherOffset","tetherOffset","isBasePlacement","tetherOffsetValue","normalizedTetherOffsetValue","offsetModifierState","_offsetModifierState$","mainSide","altSide","additive","minLen","maxLen","arrowPaddingObject","arrowPaddingMin","arrowPaddingMax","arrowLen","minOffset","maxOffset","clientOffset","offsetModifierValue","tetherMax","preventedOffset","_offsetModifierState$2","_mainSide","_altSide","_offset","_len","_min","_max","isOriginSide","_offsetModifierValue","_tetherMin","_tetherMax","_preventedOffset","v","withinMaxClamp","getCompositeRect","elementOrVirtualElement","isOffsetParentAnElement","offsetParentIsScaled","isElementScaled","modifiers","visited","result","modifier","dep","depModifier","DEFAULT_OPTIONS","areValidElements","arguments","_key","popperGenerator","generatorOptions","_generatorOptions","_generatorOptions$def","defaultModifiers","_generatorOptions$def2","defaultOptions","pending","orderedModifiers","effectCleanupFns","isDestroyed","setOptions","setOptionsAction","cleanupModifierEffects","merged","orderModifiers","current","existing","m","_ref$options","cleanupFn","forceUpdate","_state$elements","_state$orderedModifie","_state$orderedModifie2","Promise","resolve","then","destroy","onFirstUpdate","createPopper","computeStyles","applyStyles","flip","ARROW_UP_KEY","ARROW_DOWN_KEY","EVENT_KEYDOWN_DATA_API","EVENT_KEYUP_DATA_API","SELECTOR_DATA_TOGGLE_SHOWN","SELECTOR_MENU","PLACEMENT_TOP","PLACEMENT_TOPEND","PLACEMENT_BOTTOM","PLACEMENT_BOTTOMEND","PLACEMENT_RIGHT","PLACEMENT_LEFT","autoClose","display","popperConfig","Dropdown","_popper","_parent","_menu","_inNavbar","_detectNavbar","_createPopper","focus","_completeHide","Popper","referenceElement","_getPopperConfig","_getPlacement","parentDropdown","isEnd","_getOffset","popperData","defaultBsPopperConfig","_selectMenuItem","clearMenus","openToggles","context","composedPath","isMenuTarget","dataApiKeydownHandler","isInput","isEscapeEvent","isUpOrDownEvent","getToggleButton","stopPropagation","EVENT_MOUSEDOWN","className","clickCallback","rootElement","Backdrop","_isAppended","_append","_getElement","_emulateAnimation","backdrop","createElement","append","EVENT_FOCUSIN","EVENT_KEYDOWN_TAB","TAB_NAV_BACKWARD","autofocus","trapElement","FocusTrap","_isActive","_lastTabNavDirection","activate","_handleFocusin","_handleKeydown","deactivate","shiftKey","SELECTOR_FIXED_CONTENT","SELECTOR_STICKY_CONTENT","PROPERTY_PADDING","PROPERTY_MARGIN","ScrollBarHelper","getWidth","documentWidth","innerWidth","_disableOverFlow","_setElementAttributes","calculatedValue","_resetElementAttributes","isOverflowing","_saveInitialAttribute","styleProperty","scrollbarWidth","_applyManipulationCallback","setProperty","actualValue","removeProperty","callBack","sel","EVENT_HIDE_PREVENTED","EVENT_RESIZE","EVENT_CLICK_DISMISS","EVENT_MOUSEDOWN_DISMISS","EVENT_KEYDOWN_DISMISS","CLASS_NAME_OPEN","CLASS_NAME_STATIC","Modal","_dialog","_backdrop","_initializeBackDrop","_focustrap","_initializeFocusTrap","_scrollBar","_adjustDialog","_showElement","_hideModal","handleUpdate","modalBody","transitionComplete","_triggerBackdropTransition","event2","_resetAdjustments","isModalOverflowing","initialOverflowY","isBodyOverflowing","paddingLeft","paddingRight","showEvent","alreadyOpen","CLASS_NAME_SHOWING","CLASS_NAME_HIDING","OPEN_SELECTOR","Offcanvas","blur","completeCallback","DefaultAllowlist","area","br","col","code","div","em","hr","h1","h2","h3","h4","h5","h6","li","ol","p","pre","s","small","span","sub","sup","strong","u","ul","uriAttributes","SAFE_URL_PATTERN","allowedAttribute","allowedAttributeList","attributeName","nodeValue","attributeRegex","regex","allowList","content","extraClass","sanitize","sanitizeFn","template","DefaultContentType","entry","TemplateFactory","getContent","_resolvePossibleFunction","hasContent","changeContent","_checkContent","toHtml","templateWrapper","innerHTML","_maybeSanitize","text","_setContent","arg","templateElement","_putElementInTemplate","textContent","unsafeHtml","sanitizeFunction","createdDocument","DOMParser","parseFromString","elementName","attributeList","allowedAttributes","sanitizeHtml","DISALLOWED_ATTRIBUTES","CLASS_NAME_FADE","SELECTOR_MODAL","EVENT_MODAL_HIDE","TRIGGER_HOVER","TRIGGER_FOCUS","AttachmentMap","AUTO","TOP","RIGHT","BOTTOM","LEFT","animation","container","customClass","delay","title","Tooltip","_isEnabled","_timeout","_isHovered","_activeTrigger","_templateFactory","_newContent","tip","_setListeners","_fixTitle","enable","disable","toggleEnabled","click","_leave","_enter","_hideModalHandler","_disposePopper","_isWithContent","isInTheDom","_getTipElement","_isWithActiveTrigger","_getTitle","_createTipElement","_getContentForTemplate","_getTemplateFactory","tipId","prefix","floor","random","getElementById","getUID","setContent","_initializeOnDelegatedTarget","_getDelegateConfig","attachment","triggers","eventIn","eventOut","_setTimeout","timeout","dataAttributes","dataAttribute","Popover","_getContent","EVENT_ACTIVATE","EVENT_CLICK","SELECTOR_TARGET_LINKS","SELECTOR_NAV_LINKS","SELECTOR_LINK_ITEMS","rootMargin","smoothScroll","threshold","ScrollSpy","_targetLinks","_observableSections","_rootElement","_activeTarget","_observer","_previousScrollData","visibleEntryTop","parentScrollTop","refresh","_initializeTargetsAndObservables","_maybeEnableSmoothScroll","disconnect","_getNewObserver","section","observe","observableSection","scrollTo","behavior","IntersectionObserver","_observerCallback","targetElement","_process","userScrollsDown","isIntersecting","_clearActiveClass","entryIsLowerThanPrevious","targetLinks","anchor","decodeURI","_activateParents","listGroup","activeNodes","spy","ARROW_LEFT_KEY","ARROW_RIGHT_KEY","HOME_KEY","END_KEY","NOT_SELECTOR_DROPDOWN_TOGGLE","SELECTOR_INNER_ELEM","SELECTOR_DATA_TOGGLE_ACTIVE","Tab","_setInitialAttributes","_getChildren","innerElem","_elemIsActive","active","_getActiveElem","hideEvent","_deactivate","_activate","relatedElem","_toggleDropDown","nextActiveElement","preventScroll","_setAttributeIfNotExists","_setInitialAttributesOnChild","_getInnerElement","isActive","outerElem","_getOuterElement","_setInitialAttributesOnTargetPanel","open","EVENT_MOUSEOVER","EVENT_MOUSEOUT","EVENT_FOCUSOUT","CLASS_NAME_HIDE","autohide","Toast","_hasMouseInteraction","_hasKeyboardInteraction","_clearTimeout","_maybeScheduleHide","isShown","_onInteraction","isInteracting"],"sources":["../../js/src/dom/data.js","../../js/src/util/index.js","../../js/src/dom/event-handler.js","../../js/src/dom/manipulator.js","../../js/src/util/config.js","../../js/src/base-component.js","../../js/src/dom/selector-engine.js","../../js/src/util/component-functions.js","../../js/src/alert.js","../../js/src/button.js","../../js/src/util/swipe.js","../../js/src/carousel.js","../../js/src/collapse.js","../../node_modules/@popperjs/core/lib/enums.js","../../node_modules/@popperjs/core/lib/dom-utils/getNodeName.js","../../node_modules/@popperjs/core/lib/dom-utils/getWindow.js","../../node_modules/@popperjs/core/lib/dom-utils/instanceOf.js","../../node_modules/@popperjs/core/lib/modifiers/applyStyles.js","../../node_modules/@popperjs/core/lib/utils/getBasePlacement.js","../../node_modules/@popperjs/core/lib/utils/math.js","../../node_modules/@popperjs/core/lib/utils/userAgent.js","../../node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js","../../node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js","../../node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js","../../node_modules/@popperjs/core/lib/dom-utils/contains.js","../../node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js","../../node_modules/@popperjs/core/lib/dom-utils/isTableElement.js","../../node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js","../../node_modules/@popperjs/core/lib/dom-utils/getParentNode.js","../../node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js","../../node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js","../../node_modules/@popperjs/core/lib/utils/within.js","../../node_modules/@popperjs/core/lib/utils/mergePaddingObject.js","../../node_modules/@popperjs/core/lib/utils/getFreshSideObject.js","../../node_modules/@popperjs/core/lib/utils/expandToHashMap.js","../../node_modules/@popperjs/core/lib/modifiers/arrow.js","../../node_modules/@popperjs/core/lib/utils/getVariation.js","../../node_modules/@popperjs/core/lib/modifiers/computeStyles.js","../../node_modules/@popperjs/core/lib/modifiers/eventListeners.js","../../node_modules/@popperjs/core/lib/utils/getOppositePlacement.js","../../node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js","../../node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js","../../node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js","../../node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js","../../node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js","../../node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js","../../node_modules/@popperjs/core/lib/utils/rectToClientRect.js","../../node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js","../../node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js","../../node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js","../../node_modules/@popperjs/core/lib/utils/computeOffsets.js","../../node_modules/@popperjs/core/lib/utils/detectOverflow.js","../../node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js","../../node_modules/@popperjs/core/lib/modifiers/flip.js","../../node_modules/@popperjs/core/lib/modifiers/hide.js","../../node_modules/@popperjs/core/lib/modifiers/offset.js","../../node_modules/@popperjs/core/lib/modifiers/popperOffsets.js","../../node_modules/@popperjs/core/lib/modifiers/preventOverflow.js","../../node_modules/@popperjs/core/lib/utils/getAltAxis.js","../../node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js","../../node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js","../../node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js","../../node_modules/@popperjs/core/lib/utils/orderModifiers.js","../../node_modules/@popperjs/core/lib/createPopper.js","../../node_modules/@popperjs/core/lib/utils/debounce.js","../../node_modules/@popperjs/core/lib/utils/mergeByName.js","../../node_modules/@popperjs/core/lib/popper-lite.js","../../node_modules/@popperjs/core/lib/popper.js","../../js/src/dropdown.js","../../js/src/util/backdrop.js","../../js/src/util/focustrap.js","../../js/src/util/scrollbar.js","../../js/src/modal.js","../../js/src/offcanvas.js","../../js/src/util/sanitizer.js","../../js/src/util/template-factory.js","../../js/src/tooltip.js","../../js/src/popover.js","../../js/src/scrollspy.js","../../js/src/tab.js","../../js/src/toast.js","../../js/index.umd.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/data.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n/**\n * Constants\n */\n\nconst elementMap = new Map()\n\nexport default {\n set(element, key, instance) {\n if (!elementMap.has(element)) {\n elementMap.set(element, new Map())\n }\n\n const instanceMap = elementMap.get(element)\n\n // make it clear we only want one instance per element\n // can be removed later when multiple key/instances are fine to be used\n if (!instanceMap.has(key) && instanceMap.size !== 0) {\n // eslint-disable-next-line no-console\n console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`)\n return\n }\n\n instanceMap.set(key, instance)\n },\n\n get(element, key) {\n if (elementMap.has(element)) {\n return elementMap.get(element).get(key) || null\n }\n\n return null\n },\n\n remove(element, key) {\n if (!elementMap.has(element)) {\n return\n }\n\n const instanceMap = elementMap.get(element)\n\n instanceMap.delete(key)\n\n // free up element references if there are no instances left for an element\n if (instanceMap.size === 0) {\n elementMap.delete(element)\n }\n }\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap util/index.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst MAX_UID = 1_000_000\nconst MILLISECONDS_MULTIPLIER = 1000\nconst TRANSITION_END = 'transitionend'\n\n/**\n * Properly escape IDs selectors to handle weird IDs\n * @param {string} selector\n * @returns {string}\n */\nconst parseSelector = selector => {\n if (selector && window.CSS && window.CSS.escape) {\n // document.querySelector needs escaping to handle IDs (html5+) containing for instance /\n selector = selector.replace(/#([^\\s\"#']+)/g, (match, id) => `#${CSS.escape(id)}`)\n }\n\n return selector\n}\n\n// Shout-out Angus Croll (https://goo.gl/pxwQGp)\nconst toType = object => {\n if (object === null || object === undefined) {\n return `${object}`\n }\n\n return Object.prototype.toString.call(object).match(/\\s([a-z]+)/i)[1].toLowerCase()\n}\n\n/**\n * Public Util API\n */\n\nconst getUID = prefix => {\n do {\n prefix += Math.floor(Math.random() * MAX_UID)\n } while (document.getElementById(prefix))\n\n return prefix\n}\n\nconst getTransitionDurationFromElement = element => {\n if (!element) {\n return 0\n }\n\n // Get transition-duration of the element\n let { transitionDuration, transitionDelay } = window.getComputedStyle(element)\n\n const floatTransitionDuration = Number.parseFloat(transitionDuration)\n const floatTransitionDelay = Number.parseFloat(transitionDelay)\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0]\n transitionDelay = transitionDelay.split(',')[0]\n\n return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER\n}\n\nconst triggerTransitionEnd = element => {\n element.dispatchEvent(new Event(TRANSITION_END))\n}\n\nconst isElement = object => {\n if (!object || typeof object !== 'object') {\n return false\n }\n\n if (typeof object.jquery !== 'undefined') {\n object = object[0]\n }\n\n return typeof object.nodeType !== 'undefined'\n}\n\nconst getElement = object => {\n // it's a jQuery object or a node element\n if (isElement(object)) {\n return object.jquery ? object[0] : object\n }\n\n if (typeof object === 'string' && object.length > 0) {\n return document.querySelector(parseSelector(object))\n }\n\n return null\n}\n\nconst isVisible = element => {\n if (!isElement(element) || element.getClientRects().length === 0) {\n return false\n }\n\n const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible'\n // Handle `details` element as its content may falsie appear visible when it is closed\n const closedDetails = element.closest('details:not([open])')\n\n if (!closedDetails) {\n return elementIsVisible\n }\n\n if (closedDetails !== element) {\n const summary = element.closest('summary')\n if (summary && summary.parentNode !== closedDetails) {\n return false\n }\n\n if (summary === null) {\n return false\n }\n }\n\n return elementIsVisible\n}\n\nconst isDisabled = element => {\n if (!element || element.nodeType !== Node.ELEMENT_NODE) {\n return true\n }\n\n if (element.classList.contains('disabled')) {\n return true\n }\n\n if (typeof element.disabled !== 'undefined') {\n return element.disabled\n }\n\n return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false'\n}\n\nconst findShadowRoot = element => {\n if (!document.documentElement.attachShadow) {\n return null\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode()\n return root instanceof ShadowRoot ? root : null\n }\n\n if (element instanceof ShadowRoot) {\n return element\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null\n }\n\n return findShadowRoot(element.parentNode)\n}\n\nconst noop = () => {}\n\n/**\n * Trick to restart an element's animation\n *\n * @param {HTMLElement} element\n * @return void\n *\n * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation\n */\nconst reflow = element => {\n element.offsetHeight // eslint-disable-line no-unused-expressions\n}\n\nconst getjQuery = () => {\n if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {\n return window.jQuery\n }\n\n return null\n}\n\nconst DOMContentLoadedCallbacks = []\n\nconst onDOMContentLoaded = callback => {\n if (document.readyState === 'loading') {\n // add listener on the first call when the document is in loading state\n if (!DOMContentLoadedCallbacks.length) {\n document.addEventListener('DOMContentLoaded', () => {\n for (const callback of DOMContentLoadedCallbacks) {\n callback()\n }\n })\n }\n\n DOMContentLoadedCallbacks.push(callback)\n } else {\n callback()\n }\n}\n\nconst isRTL = () => document.documentElement.dir === 'rtl'\n\nconst defineJQueryPlugin = plugin => {\n onDOMContentLoaded(() => {\n const $ = getjQuery()\n /* istanbul ignore if */\n if ($) {\n const name = plugin.NAME\n const JQUERY_NO_CONFLICT = $.fn[name]\n $.fn[name] = plugin.jQueryInterface\n $.fn[name].Constructor = plugin\n $.fn[name].noConflict = () => {\n $.fn[name] = JQUERY_NO_CONFLICT\n return plugin.jQueryInterface\n }\n }\n })\n}\n\nconst execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {\n return typeof possibleCallback === 'function' ? possibleCallback(...args) : defaultValue\n}\n\nconst executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {\n if (!waitForTransition) {\n execute(callback)\n return\n }\n\n const durationPadding = 5\n const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding\n\n let called = false\n\n const handler = ({ target }) => {\n if (target !== transitionElement) {\n return\n }\n\n called = true\n transitionElement.removeEventListener(TRANSITION_END, handler)\n execute(callback)\n }\n\n transitionElement.addEventListener(TRANSITION_END, handler)\n setTimeout(() => {\n if (!called) {\n triggerTransitionEnd(transitionElement)\n }\n }, emulatedDuration)\n}\n\n/**\n * Return the previous/next element of a list.\n *\n * @param {array} list The list of elements\n * @param activeElement The active element\n * @param shouldGetNext Choose to get next or previous element\n * @param isCycleAllowed\n * @return {Element|elem} The proper element\n */\nconst getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {\n const listLength = list.length\n let index = list.indexOf(activeElement)\n\n // if the element does not exist in the list return an element\n // depending on the direction and if cycle is allowed\n if (index === -1) {\n return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0]\n }\n\n index += shouldGetNext ? 1 : -1\n\n if (isCycleAllowed) {\n index = (index + listLength) % listLength\n }\n\n return list[Math.max(0, Math.min(index, listLength - 1))]\n}\n\nexport {\n defineJQueryPlugin,\n execute,\n executeAfterTransition,\n findShadowRoot,\n getElement,\n getjQuery,\n getNextActiveElement,\n getTransitionDurationFromElement,\n getUID,\n isDisabled,\n isElement,\n isRTL,\n isVisible,\n noop,\n onDOMContentLoaded,\n parseSelector,\n reflow,\n triggerTransitionEnd,\n toType\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/event-handler.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { getjQuery } from '../util/index.js'\n\n/**\n * Constants\n */\n\nconst namespaceRegex = /[^.]*(?=\\..*)\\.|.*/\nconst stripNameRegex = /\\..*/\nconst stripUidRegex = /::\\d+$/\nconst eventRegistry = {} // Events storage\nlet uidEvent = 1\nconst customEvents = {\n mouseenter: 'mouseover',\n mouseleave: 'mouseout'\n}\n\nconst nativeEvents = new Set([\n 'click',\n 'dblclick',\n 'mouseup',\n 'mousedown',\n 'contextmenu',\n 'mousewheel',\n 'DOMMouseScroll',\n 'mouseover',\n 'mouseout',\n 'mousemove',\n 'selectstart',\n 'selectend',\n 'keydown',\n 'keypress',\n 'keyup',\n 'orientationchange',\n 'touchstart',\n 'touchmove',\n 'touchend',\n 'touchcancel',\n 'pointerdown',\n 'pointermove',\n 'pointerup',\n 'pointerleave',\n 'pointercancel',\n 'gesturestart',\n 'gesturechange',\n 'gestureend',\n 'focus',\n 'blur',\n 'change',\n 'reset',\n 'select',\n 'submit',\n 'focusin',\n 'focusout',\n 'load',\n 'unload',\n 'beforeunload',\n 'resize',\n 'move',\n 'DOMContentLoaded',\n 'readystatechange',\n 'error',\n 'abort',\n 'scroll'\n])\n\n/**\n * Private methods\n */\n\nfunction makeEventUid(element, uid) {\n return (uid && `${uid}::${uidEvent++}`) || element.uidEvent || uidEvent++\n}\n\nfunction getElementEvents(element) {\n const uid = makeEventUid(element)\n\n element.uidEvent = uid\n eventRegistry[uid] = eventRegistry[uid] || {}\n\n return eventRegistry[uid]\n}\n\nfunction bootstrapHandler(element, fn) {\n return function handler(event) {\n hydrateObj(event, { delegateTarget: element })\n\n if (handler.oneOff) {\n EventHandler.off(element, event.type, fn)\n }\n\n return fn.apply(element, [event])\n }\n}\n\nfunction bootstrapDelegationHandler(element, selector, fn) {\n return function handler(event) {\n const domElements = element.querySelectorAll(selector)\n\n for (let { target } = event; target && target !== this; target = target.parentNode) {\n for (const domElement of domElements) {\n if (domElement !== target) {\n continue\n }\n\n hydrateObj(event, { delegateTarget: target })\n\n if (handler.oneOff) {\n EventHandler.off(element, event.type, selector, fn)\n }\n\n return fn.apply(target, [event])\n }\n }\n }\n}\n\nfunction findHandler(events, callable, delegationSelector = null) {\n return Object.values(events)\n .find(event => event.callable === callable && event.delegationSelector === delegationSelector)\n}\n\nfunction normalizeParameters(originalTypeEvent, handler, delegationFunction) {\n const isDelegated = typeof handler === 'string'\n // TODO: tooltip passes `false` instead of selector, so we need to check\n const callable = isDelegated ? delegationFunction : (handler || delegationFunction)\n let typeEvent = getTypeEvent(originalTypeEvent)\n\n if (!nativeEvents.has(typeEvent)) {\n typeEvent = originalTypeEvent\n }\n\n return [isDelegated, callable, typeEvent]\n}\n\nfunction addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) {\n if (typeof originalTypeEvent !== 'string' || !element) {\n return\n }\n\n let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction)\n\n // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position\n // this prevents the handler from being dispatched the same way as mouseover or mouseout does\n if (originalTypeEvent in customEvents) {\n const wrapFunction = fn => {\n return function (event) {\n if (!event.relatedTarget || (event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget))) {\n return fn.call(this, event)\n }\n }\n }\n\n callable = wrapFunction(callable)\n }\n\n const events = getElementEvents(element)\n const handlers = events[typeEvent] || (events[typeEvent] = {})\n const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null)\n\n if (previousFunction) {\n previousFunction.oneOff = previousFunction.oneOff && oneOff\n\n return\n }\n\n const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, ''))\n const fn = isDelegated ?\n bootstrapDelegationHandler(element, handler, callable) :\n bootstrapHandler(element, callable)\n\n fn.delegationSelector = isDelegated ? handler : null\n fn.callable = callable\n fn.oneOff = oneOff\n fn.uidEvent = uid\n handlers[uid] = fn\n\n element.addEventListener(typeEvent, fn, isDelegated)\n}\n\nfunction removeHandler(element, events, typeEvent, handler, delegationSelector) {\n const fn = findHandler(events[typeEvent], handler, delegationSelector)\n\n if (!fn) {\n return\n }\n\n element.removeEventListener(typeEvent, fn, Boolean(delegationSelector))\n delete events[typeEvent][fn.uidEvent]\n}\n\nfunction removeNamespacedHandlers(element, events, typeEvent, namespace) {\n const storeElementEvent = events[typeEvent] || {}\n\n for (const [handlerKey, event] of Object.entries(storeElementEvent)) {\n if (handlerKey.includes(namespace)) {\n removeHandler(element, events, typeEvent, event.callable, event.delegationSelector)\n }\n }\n}\n\nfunction getTypeEvent(event) {\n // allow to get the native events from namespaced events ('click.bs.button' --> 'click')\n event = event.replace(stripNameRegex, '')\n return customEvents[event] || event\n}\n\nconst EventHandler = {\n on(element, event, handler, delegationFunction) {\n addHandler(element, event, handler, delegationFunction, false)\n },\n\n one(element, event, handler, delegationFunction) {\n addHandler(element, event, handler, delegationFunction, true)\n },\n\n off(element, originalTypeEvent, handler, delegationFunction) {\n if (typeof originalTypeEvent !== 'string' || !element) {\n return\n }\n\n const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction)\n const inNamespace = typeEvent !== originalTypeEvent\n const events = getElementEvents(element)\n const storeElementEvent = events[typeEvent] || {}\n const isNamespace = originalTypeEvent.startsWith('.')\n\n if (typeof callable !== 'undefined') {\n // Simplest case: handler is passed, remove that listener ONLY.\n if (!Object.keys(storeElementEvent).length) {\n return\n }\n\n removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null)\n return\n }\n\n if (isNamespace) {\n for (const elementEvent of Object.keys(events)) {\n removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1))\n }\n }\n\n for (const [keyHandlers, event] of Object.entries(storeElementEvent)) {\n const handlerKey = keyHandlers.replace(stripUidRegex, '')\n\n if (!inNamespace || originalTypeEvent.includes(handlerKey)) {\n removeHandler(element, events, typeEvent, event.callable, event.delegationSelector)\n }\n }\n },\n\n trigger(element, event, args) {\n if (typeof event !== 'string' || !element) {\n return null\n }\n\n const $ = getjQuery()\n const typeEvent = getTypeEvent(event)\n const inNamespace = event !== typeEvent\n\n let jQueryEvent = null\n let bubbles = true\n let nativeDispatch = true\n let defaultPrevented = false\n\n if (inNamespace && $) {\n jQueryEvent = $.Event(event, args)\n\n $(element).trigger(jQueryEvent)\n bubbles = !jQueryEvent.isPropagationStopped()\n nativeDispatch = !jQueryEvent.isImmediatePropagationStopped()\n defaultPrevented = jQueryEvent.isDefaultPrevented()\n }\n\n const evt = hydrateObj(new Event(event, { bubbles, cancelable: true }), args)\n\n if (defaultPrevented) {\n evt.preventDefault()\n }\n\n if (nativeDispatch) {\n element.dispatchEvent(evt)\n }\n\n if (evt.defaultPrevented && jQueryEvent) {\n jQueryEvent.preventDefault()\n }\n\n return evt\n }\n}\n\nfunction hydrateObj(obj, meta = {}) {\n for (const [key, value] of Object.entries(meta)) {\n try {\n obj[key] = value\n } catch {\n Object.defineProperty(obj, key, {\n configurable: true,\n get() {\n return value\n }\n })\n }\n }\n\n return obj\n}\n\nexport default EventHandler\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/manipulator.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nfunction normalizeData(value) {\n if (value === 'true') {\n return true\n }\n\n if (value === 'false') {\n return false\n }\n\n if (value === Number(value).toString()) {\n return Number(value)\n }\n\n if (value === '' || value === 'null') {\n return null\n }\n\n if (typeof value !== 'string') {\n return value\n }\n\n try {\n return JSON.parse(decodeURIComponent(value))\n } catch {\n return value\n }\n}\n\nfunction normalizeDataKey(key) {\n return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`)\n}\n\nconst Manipulator = {\n setDataAttribute(element, key, value) {\n element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value)\n },\n\n removeDataAttribute(element, key) {\n element.removeAttribute(`data-bs-${normalizeDataKey(key)}`)\n },\n\n getDataAttributes(element) {\n if (!element) {\n return {}\n }\n\n const attributes = {}\n const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'))\n\n for (const key of bsKeys) {\n let pureKey = key.replace(/^bs/, '')\n pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length)\n attributes[pureKey] = normalizeData(element.dataset[key])\n }\n\n return attributes\n },\n\n getDataAttribute(element, key) {\n return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`))\n }\n}\n\nexport default Manipulator\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap util/config.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Manipulator from '../dom/manipulator.js'\nimport { isElement, toType } from './index.js'\n\n/**\n * Class definition\n */\n\nclass Config {\n // Getters\n static get Default() {\n return {}\n }\n\n static get DefaultType() {\n return {}\n }\n\n static get NAME() {\n throw new Error('You have to implement the static method \"NAME\", for each component!')\n }\n\n _getConfig(config) {\n config = this._mergeConfigObj(config)\n config = this._configAfterMerge(config)\n this._typeCheckConfig(config)\n return config\n }\n\n _configAfterMerge(config) {\n return config\n }\n\n _mergeConfigObj(config, element) {\n const jsonConfig = isElement(element) ? Manipulator.getDataAttribute(element, 'config') : {} // try to parse\n\n return {\n ...this.constructor.Default,\n ...(typeof jsonConfig === 'object' ? jsonConfig : {}),\n ...(isElement(element) ? Manipulator.getDataAttributes(element) : {}),\n ...(typeof config === 'object' ? config : {})\n }\n }\n\n _typeCheckConfig(config, configTypes = this.constructor.DefaultType) {\n for (const [property, expectedTypes] of Object.entries(configTypes)) {\n const value = config[property]\n const valueType = isElement(value) ? 'element' : toType(value)\n\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new TypeError(\n `${this.constructor.NAME.toUpperCase()}: Option \"${property}\" provided type \"${valueType}\" but expected type \"${expectedTypes}\".`\n )\n }\n }\n }\n}\n\nexport default Config\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap base-component.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Data from './dom/data.js'\nimport EventHandler from './dom/event-handler.js'\nimport Config from './util/config.js'\nimport { executeAfterTransition, getElement } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst VERSION = '5.3.1'\n\n/**\n * Class definition\n */\n\nclass BaseComponent extends Config {\n constructor(element, config) {\n super()\n\n element = getElement(element)\n if (!element) {\n return\n }\n\n this._element = element\n this._config = this._getConfig(config)\n\n Data.set(this._element, this.constructor.DATA_KEY, this)\n }\n\n // Public\n dispose() {\n Data.remove(this._element, this.constructor.DATA_KEY)\n EventHandler.off(this._element, this.constructor.EVENT_KEY)\n\n for (const propertyName of Object.getOwnPropertyNames(this)) {\n this[propertyName] = null\n }\n }\n\n _queueCallback(callback, element, isAnimated = true) {\n executeAfterTransition(callback, element, isAnimated)\n }\n\n _getConfig(config) {\n config = this._mergeConfigObj(config, this._element)\n config = this._configAfterMerge(config)\n this._typeCheckConfig(config)\n return config\n }\n\n // Static\n static getInstance(element) {\n return Data.get(getElement(element), this.DATA_KEY)\n }\n\n static getOrCreateInstance(element, config = {}) {\n return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null)\n }\n\n static get VERSION() {\n return VERSION\n }\n\n static get DATA_KEY() {\n return `bs.${this.NAME}`\n }\n\n static get EVENT_KEY() {\n return `.${this.DATA_KEY}`\n }\n\n static eventName(name) {\n return `${name}${this.EVENT_KEY}`\n }\n}\n\nexport default BaseComponent\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/selector-engine.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { isDisabled, isVisible, parseSelector } from '../util/index.js'\n\nconst getSelector = element => {\n let selector = element.getAttribute('data-bs-target')\n\n if (!selector || selector === '#') {\n let hrefAttribute = element.getAttribute('href')\n\n // The only valid content that could double as a selector are IDs or classes,\n // so everything starting with `#` or `.`. If a \"real\" URL is used as the selector,\n // `document.querySelector` will rightfully complain it is invalid.\n // See https://github.com/twbs/bootstrap/issues/32273\n if (!hrefAttribute || (!hrefAttribute.includes('#') && !hrefAttribute.startsWith('.'))) {\n return null\n }\n\n // Just in case some CMS puts out a full URL with the anchor appended\n if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {\n hrefAttribute = `#${hrefAttribute.split('#')[1]}`\n }\n\n selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null\n }\n\n return parseSelector(selector)\n}\n\nconst SelectorEngine = {\n find(selector, element = document.documentElement) {\n return [].concat(...Element.prototype.querySelectorAll.call(element, selector))\n },\n\n findOne(selector, element = document.documentElement) {\n return Element.prototype.querySelector.call(element, selector)\n },\n\n children(element, selector) {\n return [].concat(...element.children).filter(child => child.matches(selector))\n },\n\n parents(element, selector) {\n const parents = []\n let ancestor = element.parentNode.closest(selector)\n\n while (ancestor) {\n parents.push(ancestor)\n ancestor = ancestor.parentNode.closest(selector)\n }\n\n return parents\n },\n\n prev(element, selector) {\n let previous = element.previousElementSibling\n\n while (previous) {\n if (previous.matches(selector)) {\n return [previous]\n }\n\n previous = previous.previousElementSibling\n }\n\n return []\n },\n // TODO: this is now unused; remove later along with prev()\n next(element, selector) {\n let next = element.nextElementSibling\n\n while (next) {\n if (next.matches(selector)) {\n return [next]\n }\n\n next = next.nextElementSibling\n }\n\n return []\n },\n\n focusableChildren(element) {\n const focusables = [\n 'a',\n 'button',\n 'input',\n 'textarea',\n 'select',\n 'details',\n '[tabindex]',\n '[contenteditable=\"true\"]'\n ].map(selector => `${selector}:not([tabindex^=\"-\"])`).join(',')\n\n return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el))\n },\n\n getSelectorFromElement(element) {\n const selector = getSelector(element)\n\n if (selector) {\n return SelectorEngine.findOne(selector) ? selector : null\n }\n\n return null\n },\n\n getElementFromSelector(element) {\n const selector = getSelector(element)\n\n return selector ? SelectorEngine.findOne(selector) : null\n },\n\n getMultipleElementsFromSelector(element) {\n const selector = getSelector(element)\n\n return selector ? SelectorEngine.find(selector) : []\n }\n}\n\nexport default SelectorEngine\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap util/component-functions.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler.js'\nimport SelectorEngine from '../dom/selector-engine.js'\nimport { isDisabled } from './index.js'\n\nconst enableDismissTrigger = (component, method = 'hide') => {\n const clickEvent = `click.dismiss${component.EVENT_KEY}`\n const name = component.NAME\n\n EventHandler.on(document, clickEvent, `[data-bs-dismiss=\"${name}\"]`, function (event) {\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault()\n }\n\n if (isDisabled(this)) {\n return\n }\n\n const target = SelectorEngine.getElementFromSelector(this) || this.closest(`.${name}`)\n const instance = component.getOrCreateInstance(target)\n\n // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method\n instance[method]()\n })\n}\n\nexport {\n enableDismissTrigger\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport { enableDismissTrigger } from './util/component-functions.js'\nimport { defineJQueryPlugin } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'alert'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * Class definition\n */\n\nclass Alert extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME\n }\n\n // Public\n close() {\n const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE)\n\n if (closeEvent.defaultPrevented) {\n return\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n\n const isAnimated = this._element.classList.contains(CLASS_NAME_FADE)\n this._queueCallback(() => this._destroyElement(), this._element, isAnimated)\n }\n\n // Private\n _destroyElement() {\n this._element.remove()\n EventHandler.trigger(this._element, EVENT_CLOSED)\n this.dispose()\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Alert.getOrCreateInstance(this)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nenableDismissTrigger(Alert, 'close')\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Alert)\n\nexport default Alert\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport { defineJQueryPlugin } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'button'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"button\"]'\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * Class definition\n */\n\nclass Button extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle() {\n // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method\n this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE))\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Button.getOrCreateInstance(this)\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => {\n event.preventDefault()\n\n const button = event.target.closest(SELECTOR_DATA_TOGGLE)\n const data = Button.getOrCreateInstance(button)\n\n data.toggle()\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Button)\n\nexport default Button\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap util/swipe.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler.js'\nimport Config from './config.js'\nimport { execute } from './index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'swipe'\nconst EVENT_KEY = '.bs.swipe'\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY}`\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY}`\nconst POINTER_TYPE_TOUCH = 'touch'\nconst POINTER_TYPE_PEN = 'pen'\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event'\nconst SWIPE_THRESHOLD = 40\n\nconst Default = {\n endCallback: null,\n leftCallback: null,\n rightCallback: null\n}\n\nconst DefaultType = {\n endCallback: '(function|null)',\n leftCallback: '(function|null)',\n rightCallback: '(function|null)'\n}\n\n/**\n * Class definition\n */\n\nclass Swipe extends Config {\n constructor(element, config) {\n super()\n this._element = element\n\n if (!element || !Swipe.isSupported()) {\n return\n }\n\n this._config = this._getConfig(config)\n this._deltaX = 0\n this._supportPointerEvents = Boolean(window.PointerEvent)\n this._initEvents()\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n dispose() {\n EventHandler.off(this._element, EVENT_KEY)\n }\n\n // Private\n _start(event) {\n if (!this._supportPointerEvents) {\n this._deltaX = event.touches[0].clientX\n\n return\n }\n\n if (this._eventIsPointerPenTouch(event)) {\n this._deltaX = event.clientX\n }\n }\n\n _end(event) {\n if (this._eventIsPointerPenTouch(event)) {\n this._deltaX = event.clientX - this._deltaX\n }\n\n this._handleSwipe()\n execute(this._config.endCallback)\n }\n\n _move(event) {\n this._deltaX = event.touches && event.touches.length > 1 ?\n 0 :\n event.touches[0].clientX - this._deltaX\n }\n\n _handleSwipe() {\n const absDeltaX = Math.abs(this._deltaX)\n\n if (absDeltaX <= SWIPE_THRESHOLD) {\n return\n }\n\n const direction = absDeltaX / this._deltaX\n\n this._deltaX = 0\n\n if (!direction) {\n return\n }\n\n execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback)\n }\n\n _initEvents() {\n if (this._supportPointerEvents) {\n EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event))\n EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event))\n\n this._element.classList.add(CLASS_NAME_POINTER_EVENT)\n } else {\n EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event))\n EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event))\n EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event))\n }\n }\n\n _eventIsPointerPenTouch(event) {\n return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)\n }\n\n // Static\n static isSupported() {\n return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0\n }\n}\n\nexport default Swipe\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport Manipulator from './dom/manipulator.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport {\n defineJQueryPlugin,\n getNextActiveElement,\n isRTL,\n isVisible,\n reflow,\n triggerTransitionEnd\n} from './util/index.js'\nimport Swipe from './util/swipe.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'carousel'\nconst DATA_KEY = 'bs.carousel'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst ARROW_LEFT_KEY = 'ArrowLeft'\nconst ARROW_RIGHT_KEY = 'ArrowRight'\nconst TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\n\nconst ORDER_NEXT = 'next'\nconst ORDER_PREV = 'prev'\nconst DIRECTION_LEFT = 'left'\nconst DIRECTION_RIGHT = 'right'\n\nconst EVENT_SLIDE = `slide${EVENT_KEY}`\nconst EVENT_SLID = `slid${EVENT_KEY}`\nconst EVENT_KEYDOWN = `keydown${EVENT_KEY}`\nconst EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`\nconst EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_CAROUSEL = 'carousel'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_SLIDE = 'slide'\nconst CLASS_NAME_END = 'carousel-item-end'\nconst CLASS_NAME_START = 'carousel-item-start'\nconst CLASS_NAME_NEXT = 'carousel-item-next'\nconst CLASS_NAME_PREV = 'carousel-item-prev'\n\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ITEM = '.carousel-item'\nconst SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM\nconst SELECTOR_ITEM_IMG = '.carousel-item img'\nconst SELECTOR_INDICATORS = '.carousel-indicators'\nconst SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]'\nconst SELECTOR_DATA_RIDE = '[data-bs-ride=\"carousel\"]'\n\nconst KEY_TO_DIRECTION = {\n [ARROW_LEFT_KEY]: DIRECTION_RIGHT,\n [ARROW_RIGHT_KEY]: DIRECTION_LEFT\n}\n\nconst Default = {\n interval: 5000,\n keyboard: true,\n pause: 'hover',\n ride: false,\n touch: true,\n wrap: true\n}\n\nconst DefaultType = {\n interval: '(number|boolean)', // TODO:v6 remove boolean support\n keyboard: 'boolean',\n pause: '(string|boolean)',\n ride: '(boolean|string)',\n touch: 'boolean',\n wrap: 'boolean'\n}\n\n/**\n * Class definition\n */\n\nclass Carousel extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n this._interval = null\n this._activeElement = null\n this._isSliding = false\n this.touchTimeout = null\n this._swipeHelper = null\n\n this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element)\n this._addEventListeners()\n\n if (this._config.ride === CLASS_NAME_CAROUSEL) {\n this.cycle()\n }\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n next() {\n this._slide(ORDER_NEXT)\n }\n\n nextWhenVisible() {\n // FIXME TODO use `document.visibilityState`\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden && isVisible(this._element)) {\n this.next()\n }\n }\n\n prev() {\n this._slide(ORDER_PREV)\n }\n\n pause() {\n if (this._isSliding) {\n triggerTransitionEnd(this._element)\n }\n\n this._clearInterval()\n }\n\n cycle() {\n this._clearInterval()\n this._updateInterval()\n\n this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval)\n }\n\n _maybeEnableCycle() {\n if (!this._config.ride) {\n return\n }\n\n if (this._isSliding) {\n EventHandler.one(this._element, EVENT_SLID, () => this.cycle())\n return\n }\n\n this.cycle()\n }\n\n to(index) {\n const items = this._getItems()\n if (index > items.length - 1 || index < 0) {\n return\n }\n\n if (this._isSliding) {\n EventHandler.one(this._element, EVENT_SLID, () => this.to(index))\n return\n }\n\n const activeIndex = this._getItemIndex(this._getActive())\n if (activeIndex === index) {\n return\n }\n\n const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV\n\n this._slide(order, items[index])\n }\n\n dispose() {\n if (this._swipeHelper) {\n this._swipeHelper.dispose()\n }\n\n super.dispose()\n }\n\n // Private\n _configAfterMerge(config) {\n config.defaultInterval = config.interval\n return config\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event))\n }\n\n if (this._config.pause === 'hover') {\n EventHandler.on(this._element, EVENT_MOUSEENTER, () => this.pause())\n EventHandler.on(this._element, EVENT_MOUSELEAVE, () => this._maybeEnableCycle())\n }\n\n if (this._config.touch && Swipe.isSupported()) {\n this._addTouchEventListeners()\n }\n }\n\n _addTouchEventListeners() {\n for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) {\n EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault())\n }\n\n const endCallBack = () => {\n if (this._config.pause !== 'hover') {\n return\n }\n\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause()\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout)\n }\n\n this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n }\n\n const swipeConfig = {\n leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)),\n rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)),\n endCallback: endCallBack\n }\n\n this._swipeHelper = new Swipe(this._element, swipeConfig)\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return\n }\n\n const direction = KEY_TO_DIRECTION[event.key]\n if (direction) {\n event.preventDefault()\n this._slide(this._directionToOrder(direction))\n }\n }\n\n _getItemIndex(element) {\n return this._getItems().indexOf(element)\n }\n\n _setActiveIndicatorElement(index) {\n if (!this._indicatorsElement) {\n return\n }\n\n const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement)\n\n activeIndicator.classList.remove(CLASS_NAME_ACTIVE)\n activeIndicator.removeAttribute('aria-current')\n\n const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to=\"${index}\"]`, this._indicatorsElement)\n\n if (newActiveIndicator) {\n newActiveIndicator.classList.add(CLASS_NAME_ACTIVE)\n newActiveIndicator.setAttribute('aria-current', 'true')\n }\n }\n\n _updateInterval() {\n const element = this._activeElement || this._getActive()\n\n if (!element) {\n return\n }\n\n const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10)\n\n this._config.interval = elementInterval || this._config.defaultInterval\n }\n\n _slide(order, element = null) {\n if (this._isSliding) {\n return\n }\n\n const activeElement = this._getActive()\n const isNext = order === ORDER_NEXT\n const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap)\n\n if (nextElement === activeElement) {\n return\n }\n\n const nextElementIndex = this._getItemIndex(nextElement)\n\n const triggerEvent = eventName => {\n return EventHandler.trigger(this._element, eventName, {\n relatedTarget: nextElement,\n direction: this._orderToDirection(order),\n from: this._getItemIndex(activeElement),\n to: nextElementIndex\n })\n }\n\n const slideEvent = triggerEvent(EVENT_SLIDE)\n\n if (slideEvent.defaultPrevented) {\n return\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n // TODO: change tests that use empty divs to avoid this check\n return\n }\n\n const isCycling = Boolean(this._interval)\n this.pause()\n\n this._isSliding = true\n\n this._setActiveIndicatorElement(nextElementIndex)\n this._activeElement = nextElement\n\n const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END\n const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV\n\n nextElement.classList.add(orderClassName)\n\n reflow(nextElement)\n\n activeElement.classList.add(directionalClassName)\n nextElement.classList.add(directionalClassName)\n\n const completeCallBack = () => {\n nextElement.classList.remove(directionalClassName, orderClassName)\n nextElement.classList.add(CLASS_NAME_ACTIVE)\n\n activeElement.classList.remove(CLASS_NAME_ACTIVE, orderClassName, directionalClassName)\n\n this._isSliding = false\n\n triggerEvent(EVENT_SLID)\n }\n\n this._queueCallback(completeCallBack, activeElement, this._isAnimated())\n\n if (isCycling) {\n this.cycle()\n }\n }\n\n _isAnimated() {\n return this._element.classList.contains(CLASS_NAME_SLIDE)\n }\n\n _getActive() {\n return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element)\n }\n\n _getItems() {\n return SelectorEngine.find(SELECTOR_ITEM, this._element)\n }\n\n _clearInterval() {\n if (this._interval) {\n clearInterval(this._interval)\n this._interval = null\n }\n }\n\n _directionToOrder(direction) {\n if (isRTL()) {\n return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT\n }\n\n return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV\n }\n\n _orderToDirection(order) {\n if (isRTL()) {\n return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT\n }\n\n return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Carousel.getOrCreateInstance(this, config)\n\n if (typeof config === 'number') {\n data.to(config)\n return\n }\n\n if (typeof config === 'string') {\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, function (event) {\n const target = SelectorEngine.getElementFromSelector(this)\n\n if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {\n return\n }\n\n event.preventDefault()\n\n const carousel = Carousel.getOrCreateInstance(target)\n const slideIndex = this.getAttribute('data-bs-slide-to')\n\n if (slideIndex) {\n carousel.to(slideIndex)\n carousel._maybeEnableCycle()\n return\n }\n\n if (Manipulator.getDataAttribute(this, 'slide') === 'next') {\n carousel.next()\n carousel._maybeEnableCycle()\n return\n }\n\n carousel.prev()\n carousel._maybeEnableCycle()\n})\n\nEventHandler.on(window, EVENT_LOAD_DATA_API, () => {\n const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE)\n\n for (const carousel of carousels) {\n Carousel.getOrCreateInstance(carousel)\n }\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Carousel)\n\nexport default Carousel\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport {\n defineJQueryPlugin,\n getElement,\n reflow\n} from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'collapse'\nconst DATA_KEY = 'bs.collapse'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_COLLAPSE = 'collapse'\nconst CLASS_NAME_COLLAPSING = 'collapsing'\nconst CLASS_NAME_COLLAPSED = 'collapsed'\nconst CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`\nconst CLASS_NAME_HORIZONTAL = 'collapse-horizontal'\n\nconst WIDTH = 'width'\nconst HEIGHT = 'height'\n\nconst SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"collapse\"]'\n\nconst Default = {\n parent: null,\n toggle: true\n}\n\nconst DefaultType = {\n parent: '(null|element)',\n toggle: 'boolean'\n}\n\n/**\n * Class definition\n */\n\nclass Collapse extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n this._isTransitioning = false\n this._triggerArray = []\n\n const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE)\n\n for (const elem of toggleList) {\n const selector = SelectorEngine.getSelectorFromElement(elem)\n const filterElement = SelectorEngine.find(selector)\n .filter(foundElement => foundElement === this._element)\n\n if (selector !== null && filterElement.length) {\n this._triggerArray.push(elem)\n }\n }\n\n this._initializeChildren()\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._triggerArray, this._isShown())\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle() {\n if (this._isShown()) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning || this._isShown()) {\n return\n }\n\n let activeChildren = []\n\n // find active children\n if (this._config.parent) {\n activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES)\n .filter(element => element !== this._element)\n .map(element => Collapse.getOrCreateInstance(element, { toggle: false }))\n }\n\n if (activeChildren.length && activeChildren[0]._isTransitioning) {\n return\n }\n\n const startEvent = EventHandler.trigger(this._element, EVENT_SHOW)\n if (startEvent.defaultPrevented) {\n return\n }\n\n for (const activeInstance of activeChildren) {\n activeInstance.hide()\n }\n\n const dimension = this._getDimension()\n\n this._element.classList.remove(CLASS_NAME_COLLAPSE)\n this._element.classList.add(CLASS_NAME_COLLAPSING)\n\n this._element.style[dimension] = 0\n\n this._addAriaAndCollapsedClass(this._triggerArray, true)\n this._isTransitioning = true\n\n const complete = () => {\n this._isTransitioning = false\n\n this._element.classList.remove(CLASS_NAME_COLLAPSING)\n this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW)\n\n this._element.style[dimension] = ''\n\n EventHandler.trigger(this._element, EVENT_SHOWN)\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n\n this._queueCallback(complete, this._element, true)\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning || !this._isShown()) {\n return\n }\n\n const startEvent = EventHandler.trigger(this._element, EVENT_HIDE)\n if (startEvent.defaultPrevented) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n reflow(this._element)\n\n this._element.classList.add(CLASS_NAME_COLLAPSING)\n this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW)\n\n for (const trigger of this._triggerArray) {\n const element = SelectorEngine.getElementFromSelector(trigger)\n\n if (element && !this._isShown(element)) {\n this._addAriaAndCollapsedClass([trigger], false)\n }\n }\n\n this._isTransitioning = true\n\n const complete = () => {\n this._isTransitioning = false\n this._element.classList.remove(CLASS_NAME_COLLAPSING)\n this._element.classList.add(CLASS_NAME_COLLAPSE)\n EventHandler.trigger(this._element, EVENT_HIDDEN)\n }\n\n this._element.style[dimension] = ''\n\n this._queueCallback(complete, this._element, true)\n }\n\n _isShown(element = this._element) {\n return element.classList.contains(CLASS_NAME_SHOW)\n }\n\n // Private\n _configAfterMerge(config) {\n config.toggle = Boolean(config.toggle) // Coerce string values\n config.parent = getElement(config.parent)\n return config\n }\n\n _getDimension() {\n return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT\n }\n\n _initializeChildren() {\n if (!this._config.parent) {\n return\n }\n\n const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE)\n\n for (const element of children) {\n const selected = SelectorEngine.getElementFromSelector(element)\n\n if (selected) {\n this._addAriaAndCollapsedClass([element], this._isShown(selected))\n }\n }\n }\n\n _getFirstLevelChildren(selector) {\n const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent)\n // remove children if greater depth\n return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element))\n }\n\n _addAriaAndCollapsedClass(triggerArray, isOpen) {\n if (!triggerArray.length) {\n return\n }\n\n for (const element of triggerArray) {\n element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen)\n element.setAttribute('aria-expanded', isOpen)\n }\n }\n\n // Static\n static jQueryInterface(config) {\n const _config = {}\n if (typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n return this.each(function () {\n const data = Collapse.getOrCreateInstance(this, _config)\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n // preventDefault only for elements (which change the URL) not inside the collapsible element\n if (event.target.tagName === 'A' || (event.delegateTarget && event.delegateTarget.tagName === 'A')) {\n event.preventDefault()\n }\n\n for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) {\n Collapse.getOrCreateInstance(element, { toggle: false }).toggle()\n }\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Collapse)\n\nexport default Collapse\n","export var top = 'top';\nexport var bottom = 'bottom';\nexport var right = 'right';\nexport var left = 'left';\nexport var auto = 'auto';\nexport var basePlacements = [top, bottom, right, left];\nexport var start = 'start';\nexport var end = 'end';\nexport var clippingParents = 'clippingParents';\nexport var viewport = 'viewport';\nexport var popper = 'popper';\nexport var reference = 'reference';\nexport var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) {\n return acc.concat([placement + \"-\" + start, placement + \"-\" + end]);\n}, []);\nexport var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) {\n return acc.concat([placement, placement + \"-\" + start, placement + \"-\" + end]);\n}, []); // modifiers that need to read the DOM\n\nexport var beforeRead = 'beforeRead';\nexport var read = 'read';\nexport var afterRead = 'afterRead'; // pure-logic modifiers\n\nexport var beforeMain = 'beforeMain';\nexport var main = 'main';\nexport var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)\n\nexport var beforeWrite = 'beforeWrite';\nexport var write = 'write';\nexport var afterWrite = 'afterWrite';\nexport var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];","export default function getNodeName(element) {\n return element ? (element.nodeName || '').toLowerCase() : null;\n}","export default function getWindow(node) {\n if (node == null) {\n return window;\n }\n\n if (node.toString() !== '[object Window]') {\n var ownerDocument = node.ownerDocument;\n return ownerDocument ? ownerDocument.defaultView || window : window;\n }\n\n return node;\n}","import getWindow from \"./getWindow.js\";\n\nfunction isElement(node) {\n var OwnElement = getWindow(node).Element;\n return node instanceof OwnElement || node instanceof Element;\n}\n\nfunction isHTMLElement(node) {\n var OwnElement = getWindow(node).HTMLElement;\n return node instanceof OwnElement || node instanceof HTMLElement;\n}\n\nfunction isShadowRoot(node) {\n // IE 11 has no ShadowRoot\n if (typeof ShadowRoot === 'undefined') {\n return false;\n }\n\n var OwnElement = getWindow(node).ShadowRoot;\n return node instanceof OwnElement || node instanceof ShadowRoot;\n}\n\nexport { isElement, isHTMLElement, isShadowRoot };","import getNodeName from \"../dom-utils/getNodeName.js\";\nimport { isHTMLElement } from \"../dom-utils/instanceOf.js\"; // This modifier takes the styles prepared by the `computeStyles` modifier\n// and applies them to the HTMLElements such as popper and arrow\n\nfunction applyStyles(_ref) {\n var state = _ref.state;\n Object.keys(state.elements).forEach(function (name) {\n var style = state.styles[name] || {};\n var attributes = state.attributes[name] || {};\n var element = state.elements[name]; // arrow is optional + virtual elements\n\n if (!isHTMLElement(element) || !getNodeName(element)) {\n return;\n } // Flow doesn't support to extend this property, but it's the most\n // effective way to apply styles to an HTMLElement\n // $FlowFixMe[cannot-write]\n\n\n Object.assign(element.style, style);\n Object.keys(attributes).forEach(function (name) {\n var value = attributes[name];\n\n if (value === false) {\n element.removeAttribute(name);\n } else {\n element.setAttribute(name, value === true ? '' : value);\n }\n });\n });\n}\n\nfunction effect(_ref2) {\n var state = _ref2.state;\n var initialStyles = {\n popper: {\n position: state.options.strategy,\n left: '0',\n top: '0',\n margin: '0'\n },\n arrow: {\n position: 'absolute'\n },\n reference: {}\n };\n Object.assign(state.elements.popper.style, initialStyles.popper);\n state.styles = initialStyles;\n\n if (state.elements.arrow) {\n Object.assign(state.elements.arrow.style, initialStyles.arrow);\n }\n\n return function () {\n Object.keys(state.elements).forEach(function (name) {\n var element = state.elements[name];\n var attributes = state.attributes[name] || {};\n var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them\n\n var style = styleProperties.reduce(function (style, property) {\n style[property] = '';\n return style;\n }, {}); // arrow is optional + virtual elements\n\n if (!isHTMLElement(element) || !getNodeName(element)) {\n return;\n }\n\n Object.assign(element.style, style);\n Object.keys(attributes).forEach(function (attribute) {\n element.removeAttribute(attribute);\n });\n });\n };\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'applyStyles',\n enabled: true,\n phase: 'write',\n fn: applyStyles,\n effect: effect,\n requires: ['computeStyles']\n};","import { auto } from \"../enums.js\";\nexport default function getBasePlacement(placement) {\n return placement.split('-')[0];\n}","export var max = Math.max;\nexport var min = Math.min;\nexport var round = Math.round;","export default function getUAString() {\n var uaData = navigator.userAgentData;\n\n if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) {\n return uaData.brands.map(function (item) {\n return item.brand + \"/\" + item.version;\n }).join(' ');\n }\n\n return navigator.userAgent;\n}","import getUAString from \"../utils/userAgent.js\";\nexport default function isLayoutViewport() {\n return !/^((?!chrome|android).)*safari/i.test(getUAString());\n}","import { isElement, isHTMLElement } from \"./instanceOf.js\";\nimport { round } from \"../utils/math.js\";\nimport getWindow from \"./getWindow.js\";\nimport isLayoutViewport from \"./isLayoutViewport.js\";\nexport default function getBoundingClientRect(element, includeScale, isFixedStrategy) {\n if (includeScale === void 0) {\n includeScale = false;\n }\n\n if (isFixedStrategy === void 0) {\n isFixedStrategy = false;\n }\n\n var clientRect = element.getBoundingClientRect();\n var scaleX = 1;\n var scaleY = 1;\n\n if (includeScale && isHTMLElement(element)) {\n scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;\n scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;\n }\n\n var _ref = isElement(element) ? getWindow(element) : window,\n visualViewport = _ref.visualViewport;\n\n var addVisualOffsets = !isLayoutViewport() && isFixedStrategy;\n var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX;\n var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY;\n var width = clientRect.width / scaleX;\n var height = clientRect.height / scaleY;\n return {\n width: width,\n height: height,\n top: y,\n right: x + width,\n bottom: y + height,\n left: x,\n x: x,\n y: y\n };\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\"; // Returns the layout rect of an element relative to its offsetParent. Layout\n// means it doesn't take into account transforms.\n\nexport default function getLayoutRect(element) {\n var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed.\n // Fixes https://github.com/popperjs/popper-core/issues/1223\n\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n if (Math.abs(clientRect.width - width) <= 1) {\n width = clientRect.width;\n }\n\n if (Math.abs(clientRect.height - height) <= 1) {\n height = clientRect.height;\n }\n\n return {\n x: element.offsetLeft,\n y: element.offsetTop,\n width: width,\n height: height\n };\n}","import { isShadowRoot } from \"./instanceOf.js\";\nexport default function contains(parent, child) {\n var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method\n\n if (parent.contains(child)) {\n return true;\n } // then fallback to custom implementation with Shadow DOM support\n else if (rootNode && isShadowRoot(rootNode)) {\n var next = child;\n\n do {\n if (next && parent.isSameNode(next)) {\n return true;\n } // $FlowFixMe[prop-missing]: need a better way to handle this...\n\n\n next = next.parentNode || next.host;\n } while (next);\n } // Give up, the result is false\n\n\n return false;\n}","import getWindow from \"./getWindow.js\";\nexport default function getComputedStyle(element) {\n return getWindow(element).getComputedStyle(element);\n}","import getNodeName from \"./getNodeName.js\";\nexport default function isTableElement(element) {\n return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;\n}","import { isElement } from \"./instanceOf.js\";\nexport default function getDocumentElement(element) {\n // $FlowFixMe[incompatible-return]: assume body is always available\n return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing]\n element.document) || window.document).documentElement;\n}","import getNodeName from \"./getNodeName.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport { isShadowRoot } from \"./instanceOf.js\";\nexport default function getParentNode(element) {\n if (getNodeName(element) === 'html') {\n return element;\n }\n\n return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle\n // $FlowFixMe[incompatible-return]\n // $FlowFixMe[prop-missing]\n element.assignedSlot || // step into the shadow DOM of the parent of a slotted node\n element.parentNode || ( // DOM Element detected\n isShadowRoot(element) ? element.host : null) || // ShadowRoot detected\n // $FlowFixMe[incompatible-call]: HTMLElement is a Node\n getDocumentElement(element) // fallback\n\n );\n}","import getWindow from \"./getWindow.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport { isHTMLElement, isShadowRoot } from \"./instanceOf.js\";\nimport isTableElement from \"./isTableElement.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport getUAString from \"../utils/userAgent.js\";\n\nfunction getTrueOffsetParent(element) {\n if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837\n getComputedStyle(element).position === 'fixed') {\n return null;\n }\n\n return element.offsetParent;\n} // `.offsetParent` reports `null` for fixed elements, while absolute elements\n// return the containing block\n\n\nfunction getContainingBlock(element) {\n var isFirefox = /firefox/i.test(getUAString());\n var isIE = /Trident/i.test(getUAString());\n\n if (isIE && isHTMLElement(element)) {\n // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport\n var elementCss = getComputedStyle(element);\n\n if (elementCss.position === 'fixed') {\n return null;\n }\n }\n\n var currentNode = getParentNode(element);\n\n if (isShadowRoot(currentNode)) {\n currentNode = currentNode.host;\n }\n\n while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {\n var css = getComputedStyle(currentNode); // This is non-exhaustive but covers the most common CSS properties that\n // create a containing block.\n // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\n\n if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') {\n return currentNode;\n } else {\n currentNode = currentNode.parentNode;\n }\n }\n\n return null;\n} // Gets the closest ancestor positioned element. Handles some edge cases,\n// such as table ancestors and cross browser bugs.\n\n\nexport default function getOffsetParent(element) {\n var window = getWindow(element);\n var offsetParent = getTrueOffsetParent(element);\n\n while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === 'static') {\n offsetParent = getTrueOffsetParent(offsetParent);\n }\n\n if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static')) {\n return window;\n }\n\n return offsetParent || getContainingBlock(element) || window;\n}","export default function getMainAxisFromPlacement(placement) {\n return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y';\n}","import { max as mathMax, min as mathMin } from \"./math.js\";\nexport function within(min, value, max) {\n return mathMax(min, mathMin(value, max));\n}\nexport function withinMaxClamp(min, value, max) {\n var v = within(min, value, max);\n return v > max ? max : v;\n}","import getFreshSideObject from \"./getFreshSideObject.js\";\nexport default function mergePaddingObject(paddingObject) {\n return Object.assign({}, getFreshSideObject(), paddingObject);\n}","export default function getFreshSideObject() {\n return {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0\n };\n}","export default function expandToHashMap(value, keys) {\n return keys.reduce(function (hashMap, key) {\n hashMap[key] = value;\n return hashMap;\n }, {});\n}","import getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getLayoutRect from \"../dom-utils/getLayoutRect.js\";\nimport contains from \"../dom-utils/contains.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport getMainAxisFromPlacement from \"../utils/getMainAxisFromPlacement.js\";\nimport { within } from \"../utils/within.js\";\nimport mergePaddingObject from \"../utils/mergePaddingObject.js\";\nimport expandToHashMap from \"../utils/expandToHashMap.js\";\nimport { left, right, basePlacements, top, bottom } from \"../enums.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar toPaddingObject = function toPaddingObject(padding, state) {\n padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, {\n placement: state.placement\n })) : padding;\n return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n};\n\nfunction arrow(_ref) {\n var _state$modifiersData$;\n\n var state = _ref.state,\n name = _ref.name,\n options = _ref.options;\n var arrowElement = state.elements.arrow;\n var popperOffsets = state.modifiersData.popperOffsets;\n var basePlacement = getBasePlacement(state.placement);\n var axis = getMainAxisFromPlacement(basePlacement);\n var isVertical = [left, right].indexOf(basePlacement) >= 0;\n var len = isVertical ? 'height' : 'width';\n\n if (!arrowElement || !popperOffsets) {\n return;\n }\n\n var paddingObject = toPaddingObject(options.padding, state);\n var arrowRect = getLayoutRect(arrowElement);\n var minProp = axis === 'y' ? top : left;\n var maxProp = axis === 'y' ? bottom : right;\n var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len];\n var startDiff = popperOffsets[axis] - state.rects.reference[axis];\n var arrowOffsetParent = getOffsetParent(arrowElement);\n var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;\n var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is\n // outside of the popper bounds\n\n var min = paddingObject[minProp];\n var max = clientSize - arrowRect[len] - paddingObject[maxProp];\n var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;\n var offset = within(min, center, max); // Prevents breaking syntax highlighting...\n\n var axisProp = axis;\n state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$);\n}\n\nfunction effect(_ref2) {\n var state = _ref2.state,\n options = _ref2.options;\n var _options$element = options.element,\n arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element;\n\n if (arrowElement == null) {\n return;\n } // CSS selector\n\n\n if (typeof arrowElement === 'string') {\n arrowElement = state.elements.popper.querySelector(arrowElement);\n\n if (!arrowElement) {\n return;\n }\n }\n\n if (!contains(state.elements.popper, arrowElement)) {\n return;\n }\n\n state.elements.arrow = arrowElement;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'arrow',\n enabled: true,\n phase: 'main',\n fn: arrow,\n effect: effect,\n requires: ['popperOffsets'],\n requiresIfExists: ['preventOverflow']\n};","export default function getVariation(placement) {\n return placement.split('-')[1];\n}","import { top, left, right, bottom, end } from \"../enums.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport getWindow from \"../dom-utils/getWindow.js\";\nimport getDocumentElement from \"../dom-utils/getDocumentElement.js\";\nimport getComputedStyle from \"../dom-utils/getComputedStyle.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getVariation from \"../utils/getVariation.js\";\nimport { round } from \"../utils/math.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar unsetSides = {\n top: 'auto',\n right: 'auto',\n bottom: 'auto',\n left: 'auto'\n}; // Round the offsets to the nearest suitable subpixel based on the DPR.\n// Zooming can change the DPR, but it seems to report a value that will\n// cleanly divide the values into the appropriate subpixels.\n\nfunction roundOffsetsByDPR(_ref, win) {\n var x = _ref.x,\n y = _ref.y;\n var dpr = win.devicePixelRatio || 1;\n return {\n x: round(x * dpr) / dpr || 0,\n y: round(y * dpr) / dpr || 0\n };\n}\n\nexport function mapToStyles(_ref2) {\n var _Object$assign2;\n\n var popper = _ref2.popper,\n popperRect = _ref2.popperRect,\n placement = _ref2.placement,\n variation = _ref2.variation,\n offsets = _ref2.offsets,\n position = _ref2.position,\n gpuAcceleration = _ref2.gpuAcceleration,\n adaptive = _ref2.adaptive,\n roundOffsets = _ref2.roundOffsets,\n isFixed = _ref2.isFixed;\n var _offsets$x = offsets.x,\n x = _offsets$x === void 0 ? 0 : _offsets$x,\n _offsets$y = offsets.y,\n y = _offsets$y === void 0 ? 0 : _offsets$y;\n\n var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({\n x: x,\n y: y\n }) : {\n x: x,\n y: y\n };\n\n x = _ref3.x;\n y = _ref3.y;\n var hasX = offsets.hasOwnProperty('x');\n var hasY = offsets.hasOwnProperty('y');\n var sideX = left;\n var sideY = top;\n var win = window;\n\n if (adaptive) {\n var offsetParent = getOffsetParent(popper);\n var heightProp = 'clientHeight';\n var widthProp = 'clientWidth';\n\n if (offsetParent === getWindow(popper)) {\n offsetParent = getDocumentElement(popper);\n\n if (getComputedStyle(offsetParent).position !== 'static' && position === 'absolute') {\n heightProp = 'scrollHeight';\n widthProp = 'scrollWidth';\n }\n } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it\n\n\n offsetParent = offsetParent;\n\n if (placement === top || (placement === left || placement === right) && variation === end) {\n sideY = bottom;\n var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]\n offsetParent[heightProp];\n y -= offsetY - popperRect.height;\n y *= gpuAcceleration ? 1 : -1;\n }\n\n if (placement === left || (placement === top || placement === bottom) && variation === end) {\n sideX = right;\n var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]\n offsetParent[widthProp];\n x -= offsetX - popperRect.width;\n x *= gpuAcceleration ? 1 : -1;\n }\n }\n\n var commonStyles = Object.assign({\n position: position\n }, adaptive && unsetSides);\n\n var _ref4 = roundOffsets === true ? roundOffsetsByDPR({\n x: x,\n y: y\n }, getWindow(popper)) : {\n x: x,\n y: y\n };\n\n x = _ref4.x;\n y = _ref4.y;\n\n if (gpuAcceleration) {\n var _Object$assign;\n\n return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? \"translate(\" + x + \"px, \" + y + \"px)\" : \"translate3d(\" + x + \"px, \" + y + \"px, 0)\", _Object$assign));\n }\n\n return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + \"px\" : '', _Object$assign2[sideX] = hasX ? x + \"px\" : '', _Object$assign2.transform = '', _Object$assign2));\n}\n\nfunction computeStyles(_ref5) {\n var state = _ref5.state,\n options = _ref5.options;\n var _options$gpuAccelerat = options.gpuAcceleration,\n gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,\n _options$adaptive = options.adaptive,\n adaptive = _options$adaptive === void 0 ? true : _options$adaptive,\n _options$roundOffsets = options.roundOffsets,\n roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;\n var commonStyles = {\n placement: getBasePlacement(state.placement),\n variation: getVariation(state.placement),\n popper: state.elements.popper,\n popperRect: state.rects.popper,\n gpuAcceleration: gpuAcceleration,\n isFixed: state.options.strategy === 'fixed'\n };\n\n if (state.modifiersData.popperOffsets != null) {\n state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {\n offsets: state.modifiersData.popperOffsets,\n position: state.options.strategy,\n adaptive: adaptive,\n roundOffsets: roundOffsets\n })));\n }\n\n if (state.modifiersData.arrow != null) {\n state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {\n offsets: state.modifiersData.arrow,\n position: 'absolute',\n adaptive: false,\n roundOffsets: roundOffsets\n })));\n }\n\n state.attributes.popper = Object.assign({}, state.attributes.popper, {\n 'data-popper-placement': state.placement\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'computeStyles',\n enabled: true,\n phase: 'beforeWrite',\n fn: computeStyles,\n data: {}\n};","import getWindow from \"../dom-utils/getWindow.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar passive = {\n passive: true\n};\n\nfunction effect(_ref) {\n var state = _ref.state,\n instance = _ref.instance,\n options = _ref.options;\n var _options$scroll = options.scroll,\n scroll = _options$scroll === void 0 ? true : _options$scroll,\n _options$resize = options.resize,\n resize = _options$resize === void 0 ? true : _options$resize;\n var window = getWindow(state.elements.popper);\n var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);\n\n if (scroll) {\n scrollParents.forEach(function (scrollParent) {\n scrollParent.addEventListener('scroll', instance.update, passive);\n });\n }\n\n if (resize) {\n window.addEventListener('resize', instance.update, passive);\n }\n\n return function () {\n if (scroll) {\n scrollParents.forEach(function (scrollParent) {\n scrollParent.removeEventListener('scroll', instance.update, passive);\n });\n }\n\n if (resize) {\n window.removeEventListener('resize', instance.update, passive);\n }\n };\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'eventListeners',\n enabled: true,\n phase: 'write',\n fn: function fn() {},\n effect: effect,\n data: {}\n};","var hash = {\n left: 'right',\n right: 'left',\n bottom: 'top',\n top: 'bottom'\n};\nexport default function getOppositePlacement(placement) {\n return placement.replace(/left|right|bottom|top/g, function (matched) {\n return hash[matched];\n });\n}","var hash = {\n start: 'end',\n end: 'start'\n};\nexport default function getOppositeVariationPlacement(placement) {\n return placement.replace(/start|end/g, function (matched) {\n return hash[matched];\n });\n}","import getWindow from \"./getWindow.js\";\nexport default function getWindowScroll(node) {\n var win = getWindow(node);\n var scrollLeft = win.pageXOffset;\n var scrollTop = win.pageYOffset;\n return {\n scrollLeft: scrollLeft,\n scrollTop: scrollTop\n };\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getWindowScroll from \"./getWindowScroll.js\";\nexport default function getWindowScrollBarX(element) {\n // If has a CSS width greater than the viewport, then this will be\n // incorrect for RTL.\n // Popper 1 is broken in this case and never had a bug report so let's assume\n // it's not an issue. I don't think anyone ever specifies width on \n // anyway.\n // Browsers where the left scrollbar doesn't cause an issue report `0` for\n // this (e.g. Edge 2019, IE11, Safari)\n return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;\n}","import getComputedStyle from \"./getComputedStyle.js\";\nexport default function isScrollParent(element) {\n // Firefox wants us to check `-x` and `-y` variations as well\n var _getComputedStyle = getComputedStyle(element),\n overflow = _getComputedStyle.overflow,\n overflowX = _getComputedStyle.overflowX,\n overflowY = _getComputedStyle.overflowY;\n\n return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);\n}","import getParentNode from \"./getParentNode.js\";\nimport isScrollParent from \"./isScrollParent.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nexport default function getScrollParent(node) {\n if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {\n // $FlowFixMe[incompatible-return]: assume body is always available\n return node.ownerDocument.body;\n }\n\n if (isHTMLElement(node) && isScrollParent(node)) {\n return node;\n }\n\n return getScrollParent(getParentNode(node));\n}","import getScrollParent from \"./getScrollParent.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport getWindow from \"./getWindow.js\";\nimport isScrollParent from \"./isScrollParent.js\";\n/*\ngiven a DOM element, return the list of all scroll parents, up the list of ancesors\nuntil we get to the top window object. This list is what we attach scroll listeners\nto, because if any of these parent elements scroll, we'll need to re-calculate the\nreference element's position.\n*/\n\nexport default function listScrollParents(element, list) {\n var _element$ownerDocumen;\n\n if (list === void 0) {\n list = [];\n }\n\n var scrollParent = getScrollParent(element);\n var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);\n var win = getWindow(scrollParent);\n var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;\n var updatedList = list.concat(target);\n return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here\n updatedList.concat(listScrollParents(getParentNode(target)));\n}","export default function rectToClientRect(rect) {\n return Object.assign({}, rect, {\n left: rect.x,\n top: rect.y,\n right: rect.x + rect.width,\n bottom: rect.y + rect.height\n });\n}","import { viewport } from \"../enums.js\";\nimport getViewportRect from \"./getViewportRect.js\";\nimport getDocumentRect from \"./getDocumentRect.js\";\nimport listScrollParents from \"./listScrollParents.js\";\nimport getOffsetParent from \"./getOffsetParent.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport { isElement, isHTMLElement } from \"./instanceOf.js\";\nimport getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport contains from \"./contains.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport rectToClientRect from \"../utils/rectToClientRect.js\";\nimport { max, min } from \"../utils/math.js\";\n\nfunction getInnerBoundingClientRect(element, strategy) {\n var rect = getBoundingClientRect(element, false, strategy === 'fixed');\n rect.top = rect.top + element.clientTop;\n rect.left = rect.left + element.clientLeft;\n rect.bottom = rect.top + element.clientHeight;\n rect.right = rect.left + element.clientWidth;\n rect.width = element.clientWidth;\n rect.height = element.clientHeight;\n rect.x = rect.left;\n rect.y = rect.top;\n return rect;\n}\n\nfunction getClientRectFromMixedType(element, clippingParent, strategy) {\n return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element)));\n} // A \"clipping parent\" is an overflowable container with the characteristic of\n// clipping (or hiding) overflowing elements with a position different from\n// `initial`\n\n\nfunction getClippingParents(element) {\n var clippingParents = listScrollParents(getParentNode(element));\n var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle(element).position) >= 0;\n var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;\n\n if (!isElement(clipperElement)) {\n return [];\n } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414\n\n\n return clippingParents.filter(function (clippingParent) {\n return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body';\n });\n} // Gets the maximum area that the element is visible in due to any number of\n// clipping parents\n\n\nexport default function getClippingRect(element, boundary, rootBoundary, strategy) {\n var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary);\n var clippingParents = [].concat(mainClippingParents, [rootBoundary]);\n var firstClippingParent = clippingParents[0];\n var clippingRect = clippingParents.reduce(function (accRect, clippingParent) {\n var rect = getClientRectFromMixedType(element, clippingParent, strategy);\n accRect.top = max(rect.top, accRect.top);\n accRect.right = min(rect.right, accRect.right);\n accRect.bottom = min(rect.bottom, accRect.bottom);\n accRect.left = max(rect.left, accRect.left);\n return accRect;\n }, getClientRectFromMixedType(element, firstClippingParent, strategy));\n clippingRect.width = clippingRect.right - clippingRect.left;\n clippingRect.height = clippingRect.bottom - clippingRect.top;\n clippingRect.x = clippingRect.left;\n clippingRect.y = clippingRect.top;\n return clippingRect;\n}","import getWindow from \"./getWindow.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport isLayoutViewport from \"./isLayoutViewport.js\";\nexport default function getViewportRect(element, strategy) {\n var win = getWindow(element);\n var html = getDocumentElement(element);\n var visualViewport = win.visualViewport;\n var width = html.clientWidth;\n var height = html.clientHeight;\n var x = 0;\n var y = 0;\n\n if (visualViewport) {\n width = visualViewport.width;\n height = visualViewport.height;\n var layoutViewport = isLayoutViewport();\n\n if (layoutViewport || !layoutViewport && strategy === 'fixed') {\n x = visualViewport.offsetLeft;\n y = visualViewport.offsetTop;\n }\n }\n\n return {\n width: width,\n height: height,\n x: x + getWindowScrollBarX(element),\n y: y\n };\n}","import getDocumentElement from \"./getDocumentElement.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport getWindowScroll from \"./getWindowScroll.js\";\nimport { max } from \"../utils/math.js\"; // Gets the entire size of the scrollable document area, even extending outside\n// of the `` and `` rect bounds if horizontally scrollable\n\nexport default function getDocumentRect(element) {\n var _element$ownerDocumen;\n\n var html = getDocumentElement(element);\n var winScroll = getWindowScroll(element);\n var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;\n var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);\n var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);\n var x = -winScroll.scrollLeft + getWindowScrollBarX(element);\n var y = -winScroll.scrollTop;\n\n if (getComputedStyle(body || html).direction === 'rtl') {\n x += max(html.clientWidth, body ? body.clientWidth : 0) - width;\n }\n\n return {\n width: width,\n height: height,\n x: x,\n y: y\n };\n}","import getBasePlacement from \"./getBasePlacement.js\";\nimport getVariation from \"./getVariation.js\";\nimport getMainAxisFromPlacement from \"./getMainAxisFromPlacement.js\";\nimport { top, right, bottom, left, start, end } from \"../enums.js\";\nexport default function computeOffsets(_ref) {\n var reference = _ref.reference,\n element = _ref.element,\n placement = _ref.placement;\n var basePlacement = placement ? getBasePlacement(placement) : null;\n var variation = placement ? getVariation(placement) : null;\n var commonX = reference.x + reference.width / 2 - element.width / 2;\n var commonY = reference.y + reference.height / 2 - element.height / 2;\n var offsets;\n\n switch (basePlacement) {\n case top:\n offsets = {\n x: commonX,\n y: reference.y - element.height\n };\n break;\n\n case bottom:\n offsets = {\n x: commonX,\n y: reference.y + reference.height\n };\n break;\n\n case right:\n offsets = {\n x: reference.x + reference.width,\n y: commonY\n };\n break;\n\n case left:\n offsets = {\n x: reference.x - element.width,\n y: commonY\n };\n break;\n\n default:\n offsets = {\n x: reference.x,\n y: reference.y\n };\n }\n\n var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;\n\n if (mainAxis != null) {\n var len = mainAxis === 'y' ? 'height' : 'width';\n\n switch (variation) {\n case start:\n offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2);\n break;\n\n case end:\n offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2);\n break;\n\n default:\n }\n }\n\n return offsets;\n}","import getClippingRect from \"../dom-utils/getClippingRect.js\";\nimport getDocumentElement from \"../dom-utils/getDocumentElement.js\";\nimport getBoundingClientRect from \"../dom-utils/getBoundingClientRect.js\";\nimport computeOffsets from \"./computeOffsets.js\";\nimport rectToClientRect from \"./rectToClientRect.js\";\nimport { clippingParents, reference, popper, bottom, top, right, basePlacements, viewport } from \"../enums.js\";\nimport { isElement } from \"../dom-utils/instanceOf.js\";\nimport mergePaddingObject from \"./mergePaddingObject.js\";\nimport expandToHashMap from \"./expandToHashMap.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport default function detectOverflow(state, options) {\n if (options === void 0) {\n options = {};\n }\n\n var _options = options,\n _options$placement = _options.placement,\n placement = _options$placement === void 0 ? state.placement : _options$placement,\n _options$strategy = _options.strategy,\n strategy = _options$strategy === void 0 ? state.strategy : _options$strategy,\n _options$boundary = _options.boundary,\n boundary = _options$boundary === void 0 ? clippingParents : _options$boundary,\n _options$rootBoundary = _options.rootBoundary,\n rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary,\n _options$elementConte = _options.elementContext,\n elementContext = _options$elementConte === void 0 ? popper : _options$elementConte,\n _options$altBoundary = _options.altBoundary,\n altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary,\n _options$padding = _options.padding,\n padding = _options$padding === void 0 ? 0 : _options$padding;\n var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n var altContext = elementContext === popper ? reference : popper;\n var popperRect = state.rects.popper;\n var element = state.elements[altBoundary ? altContext : elementContext];\n var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy);\n var referenceClientRect = getBoundingClientRect(state.elements.reference);\n var popperOffsets = computeOffsets({\n reference: referenceClientRect,\n element: popperRect,\n strategy: 'absolute',\n placement: placement\n });\n var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets));\n var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect\n // 0 or negative = within the clipping rect\n\n var overflowOffsets = {\n top: clippingClientRect.top - elementClientRect.top + paddingObject.top,\n bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,\n left: clippingClientRect.left - elementClientRect.left + paddingObject.left,\n right: elementClientRect.right - clippingClientRect.right + paddingObject.right\n };\n var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element\n\n if (elementContext === popper && offsetData) {\n var offset = offsetData[placement];\n Object.keys(overflowOffsets).forEach(function (key) {\n var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;\n var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x';\n overflowOffsets[key] += offset[axis] * multiply;\n });\n }\n\n return overflowOffsets;\n}","import getVariation from \"./getVariation.js\";\nimport { variationPlacements, basePlacements, placements as allPlacements } from \"../enums.js\";\nimport detectOverflow from \"./detectOverflow.js\";\nimport getBasePlacement from \"./getBasePlacement.js\";\nexport default function computeAutoPlacement(state, options) {\n if (options === void 0) {\n options = {};\n }\n\n var _options = options,\n placement = _options.placement,\n boundary = _options.boundary,\n rootBoundary = _options.rootBoundary,\n padding = _options.padding,\n flipVariations = _options.flipVariations,\n _options$allowedAutoP = _options.allowedAutoPlacements,\n allowedAutoPlacements = _options$allowedAutoP === void 0 ? allPlacements : _options$allowedAutoP;\n var variation = getVariation(placement);\n var placements = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) {\n return getVariation(placement) === variation;\n }) : basePlacements;\n var allowedPlacements = placements.filter(function (placement) {\n return allowedAutoPlacements.indexOf(placement) >= 0;\n });\n\n if (allowedPlacements.length === 0) {\n allowedPlacements = placements;\n } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...\n\n\n var overflows = allowedPlacements.reduce(function (acc, placement) {\n acc[placement] = detectOverflow(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding\n })[getBasePlacement(placement)];\n return acc;\n }, {});\n return Object.keys(overflows).sort(function (a, b) {\n return overflows[a] - overflows[b];\n });\n}","import getOppositePlacement from \"../utils/getOppositePlacement.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getOppositeVariationPlacement from \"../utils/getOppositeVariationPlacement.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\nimport computeAutoPlacement from \"../utils/computeAutoPlacement.js\";\nimport { bottom, top, start, right, left, auto } from \"../enums.js\";\nimport getVariation from \"../utils/getVariation.js\"; // eslint-disable-next-line import/no-unused-modules\n\nfunction getExpandedFallbackPlacements(placement) {\n if (getBasePlacement(placement) === auto) {\n return [];\n }\n\n var oppositePlacement = getOppositePlacement(placement);\n return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];\n}\n\nfunction flip(_ref) {\n var state = _ref.state,\n options = _ref.options,\n name = _ref.name;\n\n if (state.modifiersData[name]._skip) {\n return;\n }\n\n var _options$mainAxis = options.mainAxis,\n checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n _options$altAxis = options.altAxis,\n checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis,\n specifiedFallbackPlacements = options.fallbackPlacements,\n padding = options.padding,\n boundary = options.boundary,\n rootBoundary = options.rootBoundary,\n altBoundary = options.altBoundary,\n _options$flipVariatio = options.flipVariations,\n flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio,\n allowedAutoPlacements = options.allowedAutoPlacements;\n var preferredPlacement = state.options.placement;\n var basePlacement = getBasePlacement(preferredPlacement);\n var isBasePlacement = basePlacement === preferredPlacement;\n var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));\n var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {\n return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding,\n flipVariations: flipVariations,\n allowedAutoPlacements: allowedAutoPlacements\n }) : placement);\n }, []);\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var checksMap = new Map();\n var makeFallbackChecks = true;\n var firstFittingPlacement = placements[0];\n\n for (var i = 0; i < placements.length; i++) {\n var placement = placements[i];\n\n var _basePlacement = getBasePlacement(placement);\n\n var isStartVariation = getVariation(placement) === start;\n var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;\n var len = isVertical ? 'width' : 'height';\n var overflow = detectOverflow(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n altBoundary: altBoundary,\n padding: padding\n });\n var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;\n\n if (referenceRect[len] > popperRect[len]) {\n mainVariationSide = getOppositePlacement(mainVariationSide);\n }\n\n var altVariationSide = getOppositePlacement(mainVariationSide);\n var checks = [];\n\n if (checkMainAxis) {\n checks.push(overflow[_basePlacement] <= 0);\n }\n\n if (checkAltAxis) {\n checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);\n }\n\n if (checks.every(function (check) {\n return check;\n })) {\n firstFittingPlacement = placement;\n makeFallbackChecks = false;\n break;\n }\n\n checksMap.set(placement, checks);\n }\n\n if (makeFallbackChecks) {\n // `2` may be desired in some cases – research later\n var numberOfChecks = flipVariations ? 3 : 1;\n\n var _loop = function _loop(_i) {\n var fittingPlacement = placements.find(function (placement) {\n var checks = checksMap.get(placement);\n\n if (checks) {\n return checks.slice(0, _i).every(function (check) {\n return check;\n });\n }\n });\n\n if (fittingPlacement) {\n firstFittingPlacement = fittingPlacement;\n return \"break\";\n }\n };\n\n for (var _i = numberOfChecks; _i > 0; _i--) {\n var _ret = _loop(_i);\n\n if (_ret === \"break\") break;\n }\n }\n\n if (state.placement !== firstFittingPlacement) {\n state.modifiersData[name]._skip = true;\n state.placement = firstFittingPlacement;\n state.reset = true;\n }\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'flip',\n enabled: true,\n phase: 'main',\n fn: flip,\n requiresIfExists: ['offset'],\n data: {\n _skip: false\n }\n};","import { top, bottom, left, right } from \"../enums.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\n\nfunction getSideOffsets(overflow, rect, preventedOffsets) {\n if (preventedOffsets === void 0) {\n preventedOffsets = {\n x: 0,\n y: 0\n };\n }\n\n return {\n top: overflow.top - rect.height - preventedOffsets.y,\n right: overflow.right - rect.width + preventedOffsets.x,\n bottom: overflow.bottom - rect.height + preventedOffsets.y,\n left: overflow.left - rect.width - preventedOffsets.x\n };\n}\n\nfunction isAnySideFullyClipped(overflow) {\n return [top, right, bottom, left].some(function (side) {\n return overflow[side] >= 0;\n });\n}\n\nfunction hide(_ref) {\n var state = _ref.state,\n name = _ref.name;\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var preventedOffsets = state.modifiersData.preventOverflow;\n var referenceOverflow = detectOverflow(state, {\n elementContext: 'reference'\n });\n var popperAltOverflow = detectOverflow(state, {\n altBoundary: true\n });\n var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);\n var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);\n var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);\n var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);\n state.modifiersData[name] = {\n referenceClippingOffsets: referenceClippingOffsets,\n popperEscapeOffsets: popperEscapeOffsets,\n isReferenceHidden: isReferenceHidden,\n hasPopperEscaped: hasPopperEscaped\n };\n state.attributes.popper = Object.assign({}, state.attributes.popper, {\n 'data-popper-reference-hidden': isReferenceHidden,\n 'data-popper-escaped': hasPopperEscaped\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'hide',\n enabled: true,\n phase: 'main',\n requiresIfExists: ['preventOverflow'],\n fn: hide\n};","import getBasePlacement from \"../utils/getBasePlacement.js\";\nimport { top, left, right, placements } from \"../enums.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport function distanceAndSkiddingToXY(placement, rects, offset) {\n var basePlacement = getBasePlacement(placement);\n var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;\n\n var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, {\n placement: placement\n })) : offset,\n skidding = _ref[0],\n distance = _ref[1];\n\n skidding = skidding || 0;\n distance = (distance || 0) * invertDistance;\n return [left, right].indexOf(basePlacement) >= 0 ? {\n x: distance,\n y: skidding\n } : {\n x: skidding,\n y: distance\n };\n}\n\nfunction offset(_ref2) {\n var state = _ref2.state,\n options = _ref2.options,\n name = _ref2.name;\n var _options$offset = options.offset,\n offset = _options$offset === void 0 ? [0, 0] : _options$offset;\n var data = placements.reduce(function (acc, placement) {\n acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);\n return acc;\n }, {});\n var _data$state$placement = data[state.placement],\n x = _data$state$placement.x,\n y = _data$state$placement.y;\n\n if (state.modifiersData.popperOffsets != null) {\n state.modifiersData.popperOffsets.x += x;\n state.modifiersData.popperOffsets.y += y;\n }\n\n state.modifiersData[name] = data;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'offset',\n enabled: true,\n phase: 'main',\n requires: ['popperOffsets'],\n fn: offset\n};","import computeOffsets from \"../utils/computeOffsets.js\";\n\nfunction popperOffsets(_ref) {\n var state = _ref.state,\n name = _ref.name;\n // Offsets are the actual position the popper needs to have to be\n // properly positioned near its reference element\n // This is the most basic placement, and will be adjusted by\n // the modifiers in the next step\n state.modifiersData[name] = computeOffsets({\n reference: state.rects.reference,\n element: state.rects.popper,\n strategy: 'absolute',\n placement: state.placement\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'popperOffsets',\n enabled: true,\n phase: 'read',\n fn: popperOffsets,\n data: {}\n};","import { top, left, right, bottom, start } from \"../enums.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getMainAxisFromPlacement from \"../utils/getMainAxisFromPlacement.js\";\nimport getAltAxis from \"../utils/getAltAxis.js\";\nimport { within, withinMaxClamp } from \"../utils/within.js\";\nimport getLayoutRect from \"../dom-utils/getLayoutRect.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\nimport getVariation from \"../utils/getVariation.js\";\nimport getFreshSideObject from \"../utils/getFreshSideObject.js\";\nimport { min as mathMin, max as mathMax } from \"../utils/math.js\";\n\nfunction preventOverflow(_ref) {\n var state = _ref.state,\n options = _ref.options,\n name = _ref.name;\n var _options$mainAxis = options.mainAxis,\n checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n _options$altAxis = options.altAxis,\n checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis,\n boundary = options.boundary,\n rootBoundary = options.rootBoundary,\n altBoundary = options.altBoundary,\n padding = options.padding,\n _options$tether = options.tether,\n tether = _options$tether === void 0 ? true : _options$tether,\n _options$tetherOffset = options.tetherOffset,\n tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;\n var overflow = detectOverflow(state, {\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding,\n altBoundary: altBoundary\n });\n var basePlacement = getBasePlacement(state.placement);\n var variation = getVariation(state.placement);\n var isBasePlacement = !variation;\n var mainAxis = getMainAxisFromPlacement(basePlacement);\n var altAxis = getAltAxis(mainAxis);\n var popperOffsets = state.modifiersData.popperOffsets;\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, {\n placement: state.placement\n })) : tetherOffset;\n var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? {\n mainAxis: tetherOffsetValue,\n altAxis: tetherOffsetValue\n } : Object.assign({\n mainAxis: 0,\n altAxis: 0\n }, tetherOffsetValue);\n var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null;\n var data = {\n x: 0,\n y: 0\n };\n\n if (!popperOffsets) {\n return;\n }\n\n if (checkMainAxis) {\n var _offsetModifierState$;\n\n var mainSide = mainAxis === 'y' ? top : left;\n var altSide = mainAxis === 'y' ? bottom : right;\n var len = mainAxis === 'y' ? 'height' : 'width';\n var offset = popperOffsets[mainAxis];\n var min = offset + overflow[mainSide];\n var max = offset - overflow[altSide];\n var additive = tether ? -popperRect[len] / 2 : 0;\n var minLen = variation === start ? referenceRect[len] : popperRect[len];\n var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go\n // outside the reference bounds\n\n var arrowElement = state.elements.arrow;\n var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {\n width: 0,\n height: 0\n };\n var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject();\n var arrowPaddingMin = arrowPaddingObject[mainSide];\n var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want\n // to include its full size in the calculation. If the reference is small\n // and near the edge of a boundary, the popper can overflow even if the\n // reference is not overflowing as well (e.g. virtual elements with no\n // width or height)\n\n var arrowLen = within(0, referenceRect[len], arrowRect[len]);\n var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis;\n var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis;\n var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);\n var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;\n var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0;\n var tetherMin = offset + minOffset - offsetModifierValue - clientOffset;\n var tetherMax = offset + maxOffset - offsetModifierValue;\n var preventedOffset = within(tether ? mathMin(min, tetherMin) : min, offset, tether ? mathMax(max, tetherMax) : max);\n popperOffsets[mainAxis] = preventedOffset;\n data[mainAxis] = preventedOffset - offset;\n }\n\n if (checkAltAxis) {\n var _offsetModifierState$2;\n\n var _mainSide = mainAxis === 'x' ? top : left;\n\n var _altSide = mainAxis === 'x' ? bottom : right;\n\n var _offset = popperOffsets[altAxis];\n\n var _len = altAxis === 'y' ? 'height' : 'width';\n\n var _min = _offset + overflow[_mainSide];\n\n var _max = _offset - overflow[_altSide];\n\n var isOriginSide = [top, left].indexOf(basePlacement) !== -1;\n\n var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0;\n\n var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis;\n\n var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max;\n\n var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max);\n\n popperOffsets[altAxis] = _preventedOffset;\n data[altAxis] = _preventedOffset - _offset;\n }\n\n state.modifiersData[name] = data;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'preventOverflow',\n enabled: true,\n phase: 'main',\n fn: preventOverflow,\n requiresIfExists: ['offset']\n};","export default function getAltAxis(axis) {\n return axis === 'x' ? 'y' : 'x';\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getNodeScroll from \"./getNodeScroll.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport isScrollParent from \"./isScrollParent.js\";\nimport { round } from \"../utils/math.js\";\n\nfunction isElementScaled(element) {\n var rect = element.getBoundingClientRect();\n var scaleX = round(rect.width) / element.offsetWidth || 1;\n var scaleY = round(rect.height) / element.offsetHeight || 1;\n return scaleX !== 1 || scaleY !== 1;\n} // Returns the composite rect of an element relative to its offsetParent.\n// Composite means it takes into account transforms as well as layout.\n\n\nexport default function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {\n if (isFixed === void 0) {\n isFixed = false;\n }\n\n var isOffsetParentAnElement = isHTMLElement(offsetParent);\n var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);\n var documentElement = getDocumentElement(offsetParent);\n var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed);\n var scroll = {\n scrollLeft: 0,\n scrollTop: 0\n };\n var offsets = {\n x: 0,\n y: 0\n };\n\n if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {\n if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078\n isScrollParent(documentElement)) {\n scroll = getNodeScroll(offsetParent);\n }\n\n if (isHTMLElement(offsetParent)) {\n offsets = getBoundingClientRect(offsetParent, true);\n offsets.x += offsetParent.clientLeft;\n offsets.y += offsetParent.clientTop;\n } else if (documentElement) {\n offsets.x = getWindowScrollBarX(documentElement);\n }\n }\n\n return {\n x: rect.left + scroll.scrollLeft - offsets.x,\n y: rect.top + scroll.scrollTop - offsets.y,\n width: rect.width,\n height: rect.height\n };\n}","import getWindowScroll from \"./getWindowScroll.js\";\nimport getWindow from \"./getWindow.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nimport getHTMLElementScroll from \"./getHTMLElementScroll.js\";\nexport default function getNodeScroll(node) {\n if (node === getWindow(node) || !isHTMLElement(node)) {\n return getWindowScroll(node);\n } else {\n return getHTMLElementScroll(node);\n }\n}","export default function getHTMLElementScroll(element) {\n return {\n scrollLeft: element.scrollLeft,\n scrollTop: element.scrollTop\n };\n}","import { modifierPhases } from \"../enums.js\"; // source: https://stackoverflow.com/questions/49875255\n\nfunction order(modifiers) {\n var map = new Map();\n var visited = new Set();\n var result = [];\n modifiers.forEach(function (modifier) {\n map.set(modifier.name, modifier);\n }); // On visiting object, check for its dependencies and visit them recursively\n\n function sort(modifier) {\n visited.add(modifier.name);\n var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);\n requires.forEach(function (dep) {\n if (!visited.has(dep)) {\n var depModifier = map.get(dep);\n\n if (depModifier) {\n sort(depModifier);\n }\n }\n });\n result.push(modifier);\n }\n\n modifiers.forEach(function (modifier) {\n if (!visited.has(modifier.name)) {\n // check for visited object\n sort(modifier);\n }\n });\n return result;\n}\n\nexport default function orderModifiers(modifiers) {\n // order based on dependencies\n var orderedModifiers = order(modifiers); // order based on phase\n\n return modifierPhases.reduce(function (acc, phase) {\n return acc.concat(orderedModifiers.filter(function (modifier) {\n return modifier.phase === phase;\n }));\n }, []);\n}","import getCompositeRect from \"./dom-utils/getCompositeRect.js\";\nimport getLayoutRect from \"./dom-utils/getLayoutRect.js\";\nimport listScrollParents from \"./dom-utils/listScrollParents.js\";\nimport getOffsetParent from \"./dom-utils/getOffsetParent.js\";\nimport orderModifiers from \"./utils/orderModifiers.js\";\nimport debounce from \"./utils/debounce.js\";\nimport mergeByName from \"./utils/mergeByName.js\";\nimport detectOverflow from \"./utils/detectOverflow.js\";\nimport { isElement } from \"./dom-utils/instanceOf.js\";\nvar DEFAULT_OPTIONS = {\n placement: 'bottom',\n modifiers: [],\n strategy: 'absolute'\n};\n\nfunction areValidElements() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n return !args.some(function (element) {\n return !(element && typeof element.getBoundingClientRect === 'function');\n });\n}\n\nexport function popperGenerator(generatorOptions) {\n if (generatorOptions === void 0) {\n generatorOptions = {};\n }\n\n var _generatorOptions = generatorOptions,\n _generatorOptions$def = _generatorOptions.defaultModifiers,\n defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def,\n _generatorOptions$def2 = _generatorOptions.defaultOptions,\n defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;\n return function createPopper(reference, popper, options) {\n if (options === void 0) {\n options = defaultOptions;\n }\n\n var state = {\n placement: 'bottom',\n orderedModifiers: [],\n options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),\n modifiersData: {},\n elements: {\n reference: reference,\n popper: popper\n },\n attributes: {},\n styles: {}\n };\n var effectCleanupFns = [];\n var isDestroyed = false;\n var instance = {\n state: state,\n setOptions: function setOptions(setOptionsAction) {\n var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction;\n cleanupModifierEffects();\n state.options = Object.assign({}, defaultOptions, state.options, options);\n state.scrollParents = {\n reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [],\n popper: listScrollParents(popper)\n }; // Orders the modifiers based on their dependencies and `phase`\n // properties\n\n var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers\n\n state.orderedModifiers = orderedModifiers.filter(function (m) {\n return m.enabled;\n });\n runModifierEffects();\n return instance.update();\n },\n // Sync update – it will always be executed, even if not necessary. This\n // is useful for low frequency updates where sync behavior simplifies the\n // logic.\n // For high frequency updates (e.g. `resize` and `scroll` events), always\n // prefer the async Popper#update method\n forceUpdate: function forceUpdate() {\n if (isDestroyed) {\n return;\n }\n\n var _state$elements = state.elements,\n reference = _state$elements.reference,\n popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements\n // anymore\n\n if (!areValidElements(reference, popper)) {\n return;\n } // Store the reference and popper rects to be read by modifiers\n\n\n state.rects = {\n reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'),\n popper: getLayoutRect(popper)\n }; // Modifiers have the ability to reset the current update cycle. The\n // most common use case for this is the `flip` modifier changing the\n // placement, which then needs to re-run all the modifiers, because the\n // logic was previously ran for the previous placement and is therefore\n // stale/incorrect\n\n state.reset = false;\n state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier\n // is filled with the initial data specified by the modifier. This means\n // it doesn't persist and is fresh on each update.\n // To ensure persistent data, use `${name}#persistent`\n\n state.orderedModifiers.forEach(function (modifier) {\n return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);\n });\n\n for (var index = 0; index < state.orderedModifiers.length; index++) {\n if (state.reset === true) {\n state.reset = false;\n index = -1;\n continue;\n }\n\n var _state$orderedModifie = state.orderedModifiers[index],\n fn = _state$orderedModifie.fn,\n _state$orderedModifie2 = _state$orderedModifie.options,\n _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2,\n name = _state$orderedModifie.name;\n\n if (typeof fn === 'function') {\n state = fn({\n state: state,\n options: _options,\n name: name,\n instance: instance\n }) || state;\n }\n }\n },\n // Async and optimistically optimized update – it will not be executed if\n // not necessary (debounced to run at most once-per-tick)\n update: debounce(function () {\n return new Promise(function (resolve) {\n instance.forceUpdate();\n resolve(state);\n });\n }),\n destroy: function destroy() {\n cleanupModifierEffects();\n isDestroyed = true;\n }\n };\n\n if (!areValidElements(reference, popper)) {\n return instance;\n }\n\n instance.setOptions(options).then(function (state) {\n if (!isDestroyed && options.onFirstUpdate) {\n options.onFirstUpdate(state);\n }\n }); // Modifiers have the ability to execute arbitrary code before the first\n // update cycle runs. They will be executed in the same order as the update\n // cycle. This is useful when a modifier adds some persistent data that\n // other modifiers need to use, but the modifier is run after the dependent\n // one.\n\n function runModifierEffects() {\n state.orderedModifiers.forEach(function (_ref) {\n var name = _ref.name,\n _ref$options = _ref.options,\n options = _ref$options === void 0 ? {} : _ref$options,\n effect = _ref.effect;\n\n if (typeof effect === 'function') {\n var cleanupFn = effect({\n state: state,\n name: name,\n instance: instance,\n options: options\n });\n\n var noopFn = function noopFn() {};\n\n effectCleanupFns.push(cleanupFn || noopFn);\n }\n });\n }\n\n function cleanupModifierEffects() {\n effectCleanupFns.forEach(function (fn) {\n return fn();\n });\n effectCleanupFns = [];\n }\n\n return instance;\n };\n}\nexport var createPopper = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules\n\nexport { detectOverflow };","export default function debounce(fn) {\n var pending;\n return function () {\n if (!pending) {\n pending = new Promise(function (resolve) {\n Promise.resolve().then(function () {\n pending = undefined;\n resolve(fn());\n });\n });\n }\n\n return pending;\n };\n}","export default function mergeByName(modifiers) {\n var merged = modifiers.reduce(function (merged, current) {\n var existing = merged[current.name];\n merged[current.name] = existing ? Object.assign({}, existing, current, {\n options: Object.assign({}, existing.options, current.options),\n data: Object.assign({}, existing.data, current.data)\n }) : current;\n return merged;\n }, {}); // IE11 does not support Object.values\n\n return Object.keys(merged).map(function (key) {\n return merged[key];\n });\n}","import { popperGenerator, detectOverflow } from \"./createPopper.js\";\nimport eventListeners from \"./modifiers/eventListeners.js\";\nimport popperOffsets from \"./modifiers/popperOffsets.js\";\nimport computeStyles from \"./modifiers/computeStyles.js\";\nimport applyStyles from \"./modifiers/applyStyles.js\";\nvar defaultModifiers = [eventListeners, popperOffsets, computeStyles, applyStyles];\nvar createPopper = /*#__PURE__*/popperGenerator({\n defaultModifiers: defaultModifiers\n}); // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper, popperGenerator, defaultModifiers, detectOverflow };","import { popperGenerator, detectOverflow } from \"./createPopper.js\";\nimport eventListeners from \"./modifiers/eventListeners.js\";\nimport popperOffsets from \"./modifiers/popperOffsets.js\";\nimport computeStyles from \"./modifiers/computeStyles.js\";\nimport applyStyles from \"./modifiers/applyStyles.js\";\nimport offset from \"./modifiers/offset.js\";\nimport flip from \"./modifiers/flip.js\";\nimport preventOverflow from \"./modifiers/preventOverflow.js\";\nimport arrow from \"./modifiers/arrow.js\";\nimport hide from \"./modifiers/hide.js\";\nvar defaultModifiers = [eventListeners, popperOffsets, computeStyles, applyStyles, offset, flip, preventOverflow, arrow, hide];\nvar createPopper = /*#__PURE__*/popperGenerator({\n defaultModifiers: defaultModifiers\n}); // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper, popperGenerator, defaultModifiers, detectOverflow }; // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper as createPopperLite } from \"./popper-lite.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport * from \"./modifiers/index.js\";","/**\n * --------------------------------------------------------------------------\n * Bootstrap dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport * as Popper from '@popperjs/core'\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport Manipulator from './dom/manipulator.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport {\n defineJQueryPlugin,\n execute,\n getElement,\n getNextActiveElement,\n isDisabled,\n isElement,\n isRTL,\n isVisible,\n noop\n} from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'dropdown'\nconst DATA_KEY = 'bs.dropdown'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst ESCAPE_KEY = 'Escape'\nconst TAB_KEY = 'Tab'\nconst ARROW_UP_KEY = 'ArrowUp'\nconst ARROW_DOWN_KEY = 'ArrowDown'\nconst RIGHT_MOUSE_BUTTON = 2 // MouseEvent.button value for the secondary button, usually the right button\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_DROPUP = 'dropup'\nconst CLASS_NAME_DROPEND = 'dropend'\nconst CLASS_NAME_DROPSTART = 'dropstart'\nconst CLASS_NAME_DROPUP_CENTER = 'dropup-center'\nconst CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center'\n\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"dropdown\"]:not(.disabled):not(:disabled)'\nconst SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE}.${CLASS_NAME_SHOW}`\nconst SELECTOR_MENU = '.dropdown-menu'\nconst SELECTOR_NAVBAR = '.navbar'\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav'\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'\n\nconst PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start'\nconst PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end'\nconst PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start'\nconst PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end'\nconst PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start'\nconst PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start'\nconst PLACEMENT_TOPCENTER = 'top'\nconst PLACEMENT_BOTTOMCENTER = 'bottom'\n\nconst Default = {\n autoClose: true,\n boundary: 'clippingParents',\n display: 'dynamic',\n offset: [0, 2],\n popperConfig: null,\n reference: 'toggle'\n}\n\nconst DefaultType = {\n autoClose: '(boolean|string)',\n boundary: '(string|element)',\n display: 'string',\n offset: '(array|string|function)',\n popperConfig: '(null|object|function)',\n reference: '(string|element|object)'\n}\n\n/**\n * Class definition\n */\n\nclass Dropdown extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n this._popper = null\n this._parent = this._element.parentNode // dropdown wrapper\n // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/\n this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] ||\n SelectorEngine.prev(this._element, SELECTOR_MENU)[0] ||\n SelectorEngine.findOne(SELECTOR_MENU, this._parent)\n this._inNavbar = this._detectNavbar()\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle() {\n return this._isShown() ? this.hide() : this.show()\n }\n\n show() {\n if (isDisabled(this._element) || this._isShown()) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, relatedTarget)\n\n if (showEvent.defaultPrevented) {\n return\n }\n\n this._createPopper()\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.on(element, 'mouseover', noop)\n }\n }\n\n this._element.focus()\n this._element.setAttribute('aria-expanded', true)\n\n this._menu.classList.add(CLASS_NAME_SHOW)\n this._element.classList.add(CLASS_NAME_SHOW)\n EventHandler.trigger(this._element, EVENT_SHOWN, relatedTarget)\n }\n\n hide() {\n if (isDisabled(this._element) || !this._isShown()) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n\n this._completeHide(relatedTarget)\n }\n\n dispose() {\n if (this._popper) {\n this._popper.destroy()\n }\n\n super.dispose()\n }\n\n update() {\n this._inNavbar = this._detectNavbar()\n if (this._popper) {\n this._popper.update()\n }\n }\n\n // Private\n _completeHide(relatedTarget) {\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE, relatedTarget)\n if (hideEvent.defaultPrevented) {\n return\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.off(element, 'mouseover', noop)\n }\n }\n\n if (this._popper) {\n this._popper.destroy()\n }\n\n this._menu.classList.remove(CLASS_NAME_SHOW)\n this._element.classList.remove(CLASS_NAME_SHOW)\n this._element.setAttribute('aria-expanded', 'false')\n Manipulator.removeDataAttribute(this._menu, 'popper')\n EventHandler.trigger(this._element, EVENT_HIDDEN, relatedTarget)\n }\n\n _getConfig(config) {\n config = super._getConfig(config)\n\n if (typeof config.reference === 'object' && !isElement(config.reference) &&\n typeof config.reference.getBoundingClientRect !== 'function'\n ) {\n // Popper virtual elements require a getBoundingClientRect method\n throw new TypeError(`${NAME.toUpperCase()}: Option \"reference\" provided type \"object\" without a required \"getBoundingClientRect\" method.`)\n }\n\n return config\n }\n\n _createPopper() {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org)')\n }\n\n let referenceElement = this._element\n\n if (this._config.reference === 'parent') {\n referenceElement = this._parent\n } else if (isElement(this._config.reference)) {\n referenceElement = getElement(this._config.reference)\n } else if (typeof this._config.reference === 'object') {\n referenceElement = this._config.reference\n }\n\n const popperConfig = this._getPopperConfig()\n this._popper = Popper.createPopper(referenceElement, this._menu, popperConfig)\n }\n\n _isShown() {\n return this._menu.classList.contains(CLASS_NAME_SHOW)\n }\n\n _getPlacement() {\n const parentDropdown = this._parent\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {\n return PLACEMENT_RIGHT\n }\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {\n return PLACEMENT_LEFT\n }\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) {\n return PLACEMENT_TOPCENTER\n }\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) {\n return PLACEMENT_BOTTOMCENTER\n }\n\n // We need to trim the value because custom properties can also include spaces\n const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end'\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {\n return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP\n }\n\n return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM\n }\n\n _detectNavbar() {\n return this._element.closest(SELECTOR_NAVBAR) !== null\n }\n\n _getOffset() {\n const { offset } = this._config\n\n if (typeof offset === 'string') {\n return offset.split(',').map(value => Number.parseInt(value, 10))\n }\n\n if (typeof offset === 'function') {\n return popperData => offset(popperData, this._element)\n }\n\n return offset\n }\n\n _getPopperConfig() {\n const defaultBsPopperConfig = {\n placement: this._getPlacement(),\n modifiers: [{\n name: 'preventOverflow',\n options: {\n boundary: this._config.boundary\n }\n },\n {\n name: 'offset',\n options: {\n offset: this._getOffset()\n }\n }]\n }\n\n // Disable Popper if we have a static display or Dropdown is in Navbar\n if (this._inNavbar || this._config.display === 'static') {\n Manipulator.setDataAttribute(this._menu, 'popper', 'static') // TODO: v6 remove\n defaultBsPopperConfig.modifiers = [{\n name: 'applyStyles',\n enabled: false\n }]\n }\n\n return {\n ...defaultBsPopperConfig,\n ...execute(this._config.popperConfig, [defaultBsPopperConfig])\n }\n }\n\n _selectMenuItem({ key, target }) {\n const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => isVisible(element))\n\n if (!items.length) {\n return\n }\n\n // if target isn't included in items (e.g. when expanding the dropdown)\n // allow cycling to get the last item in case key equals ARROW_UP_KEY\n getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus()\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Dropdown.getOrCreateInstance(this, config)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n })\n }\n\n static clearMenus(event) {\n if (event.button === RIGHT_MOUSE_BUTTON || (event.type === 'keyup' && event.key !== TAB_KEY)) {\n return\n }\n\n const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN)\n\n for (const toggle of openToggles) {\n const context = Dropdown.getInstance(toggle)\n if (!context || context._config.autoClose === false) {\n continue\n }\n\n const composedPath = event.composedPath()\n const isMenuTarget = composedPath.includes(context._menu)\n if (\n composedPath.includes(context._element) ||\n (context._config.autoClose === 'inside' && !isMenuTarget) ||\n (context._config.autoClose === 'outside' && isMenuTarget)\n ) {\n continue\n }\n\n // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu\n if (context._menu.contains(event.target) && ((event.type === 'keyup' && event.key === TAB_KEY) || /input|select|option|textarea|form/i.test(event.target.tagName))) {\n continue\n }\n\n const relatedTarget = { relatedTarget: context._element }\n\n if (event.type === 'click') {\n relatedTarget.clickEvent = event\n }\n\n context._completeHide(relatedTarget)\n }\n }\n\n static dataApiKeydownHandler(event) {\n // If not an UP | DOWN | ESCAPE key => not a dropdown command\n // If input/textarea && if key is other than ESCAPE => not a dropdown command\n\n const isInput = /input|textarea/i.test(event.target.tagName)\n const isEscapeEvent = event.key === ESCAPE_KEY\n const isUpOrDownEvent = [ARROW_UP_KEY, ARROW_DOWN_KEY].includes(event.key)\n\n if (!isUpOrDownEvent && !isEscapeEvent) {\n return\n }\n\n if (isInput && !isEscapeEvent) {\n return\n }\n\n event.preventDefault()\n\n // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/\n const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE) ?\n this :\n (SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0] ||\n SelectorEngine.next(this, SELECTOR_DATA_TOGGLE)[0] ||\n SelectorEngine.findOne(SELECTOR_DATA_TOGGLE, event.delegateTarget.parentNode))\n\n const instance = Dropdown.getOrCreateInstance(getToggleButton)\n\n if (isUpOrDownEvent) {\n event.stopPropagation()\n instance.show()\n instance._selectMenuItem(event)\n return\n }\n\n if (instance._isShown()) { // else is escape and we check if it is shown\n event.stopPropagation()\n instance.hide()\n getToggleButton.focus()\n }\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown.dataApiKeydownHandler)\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler)\nEventHandler.on(document, EVENT_CLICK_DATA_API, Dropdown.clearMenus)\nEventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus)\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n Dropdown.getOrCreateInstance(this).toggle()\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Dropdown)\n\nexport default Dropdown\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap util/backdrop.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler.js'\nimport Config from './config.js'\nimport { execute, executeAfterTransition, getElement, reflow } from './index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'backdrop'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst EVENT_MOUSEDOWN = `mousedown.bs.${NAME}`\n\nconst Default = {\n className: 'modal-backdrop',\n clickCallback: null,\n isAnimated: false,\n isVisible: true, // if false, we use the backdrop helper without adding any element to the dom\n rootElement: 'body' // give the choice to place backdrop under different elements\n}\n\nconst DefaultType = {\n className: 'string',\n clickCallback: '(function|null)',\n isAnimated: 'boolean',\n isVisible: 'boolean',\n rootElement: '(element|string)'\n}\n\n/**\n * Class definition\n */\n\nclass Backdrop extends Config {\n constructor(config) {\n super()\n this._config = this._getConfig(config)\n this._isAppended = false\n this._element = null\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n show(callback) {\n if (!this._config.isVisible) {\n execute(callback)\n return\n }\n\n this._append()\n\n const element = this._getElement()\n if (this._config.isAnimated) {\n reflow(element)\n }\n\n element.classList.add(CLASS_NAME_SHOW)\n\n this._emulateAnimation(() => {\n execute(callback)\n })\n }\n\n hide(callback) {\n if (!this._config.isVisible) {\n execute(callback)\n return\n }\n\n this._getElement().classList.remove(CLASS_NAME_SHOW)\n\n this._emulateAnimation(() => {\n this.dispose()\n execute(callback)\n })\n }\n\n dispose() {\n if (!this._isAppended) {\n return\n }\n\n EventHandler.off(this._element, EVENT_MOUSEDOWN)\n\n this._element.remove()\n this._isAppended = false\n }\n\n // Private\n _getElement() {\n if (!this._element) {\n const backdrop = document.createElement('div')\n backdrop.className = this._config.className\n if (this._config.isAnimated) {\n backdrop.classList.add(CLASS_NAME_FADE)\n }\n\n this._element = backdrop\n }\n\n return this._element\n }\n\n _configAfterMerge(config) {\n // use getElement() with the default \"body\" to get a fresh Element on each instantiation\n config.rootElement = getElement(config.rootElement)\n return config\n }\n\n _append() {\n if (this._isAppended) {\n return\n }\n\n const element = this._getElement()\n this._config.rootElement.append(element)\n\n EventHandler.on(element, EVENT_MOUSEDOWN, () => {\n execute(this._config.clickCallback)\n })\n\n this._isAppended = true\n }\n\n _emulateAnimation(callback) {\n executeAfterTransition(callback, this._getElement(), this._config.isAnimated)\n }\n}\n\nexport default Backdrop\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap util/focustrap.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler.js'\nimport SelectorEngine from '../dom/selector-engine.js'\nimport Config from './config.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'focustrap'\nconst DATA_KEY = 'bs.focustrap'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY}`\n\nconst TAB_KEY = 'Tab'\nconst TAB_NAV_FORWARD = 'forward'\nconst TAB_NAV_BACKWARD = 'backward'\n\nconst Default = {\n autofocus: true,\n trapElement: null // The element to trap focus inside of\n}\n\nconst DefaultType = {\n autofocus: 'boolean',\n trapElement: 'element'\n}\n\n/**\n * Class definition\n */\n\nclass FocusTrap extends Config {\n constructor(config) {\n super()\n this._config = this._getConfig(config)\n this._isActive = false\n this._lastTabNavDirection = null\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n activate() {\n if (this._isActive) {\n return\n }\n\n if (this._config.autofocus) {\n this._config.trapElement.focus()\n }\n\n EventHandler.off(document, EVENT_KEY) // guard against infinite focus loop\n EventHandler.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event))\n EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event))\n\n this._isActive = true\n }\n\n deactivate() {\n if (!this._isActive) {\n return\n }\n\n this._isActive = false\n EventHandler.off(document, EVENT_KEY)\n }\n\n // Private\n _handleFocusin(event) {\n const { trapElement } = this._config\n\n if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {\n return\n }\n\n const elements = SelectorEngine.focusableChildren(trapElement)\n\n if (elements.length === 0) {\n trapElement.focus()\n } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {\n elements[elements.length - 1].focus()\n } else {\n elements[0].focus()\n }\n }\n\n _handleKeydown(event) {\n if (event.key !== TAB_KEY) {\n return\n }\n\n this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD\n }\n}\n\nexport default FocusTrap\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap util/scrollBar.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Manipulator from '../dom/manipulator.js'\nimport SelectorEngine from '../dom/selector-engine.js'\nimport { isElement } from './index.js'\n\n/**\n * Constants\n */\n\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'\nconst SELECTOR_STICKY_CONTENT = '.sticky-top'\nconst PROPERTY_PADDING = 'padding-right'\nconst PROPERTY_MARGIN = 'margin-right'\n\n/**\n * Class definition\n */\n\nclass ScrollBarHelper {\n constructor() {\n this._element = document.body\n }\n\n // Public\n getWidth() {\n // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes\n const documentWidth = document.documentElement.clientWidth\n return Math.abs(window.innerWidth - documentWidth)\n }\n\n hide() {\n const width = this.getWidth()\n this._disableOverFlow()\n // give padding to element to balance the hidden scrollbar width\n this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width)\n // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth\n this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width)\n this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width)\n }\n\n reset() {\n this._resetElementAttributes(this._element, 'overflow')\n this._resetElementAttributes(this._element, PROPERTY_PADDING)\n this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING)\n this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN)\n }\n\n isOverflowing() {\n return this.getWidth() > 0\n }\n\n // Private\n _disableOverFlow() {\n this._saveInitialAttribute(this._element, 'overflow')\n this._element.style.overflow = 'hidden'\n }\n\n _setElementAttributes(selector, styleProperty, callback) {\n const scrollbarWidth = this.getWidth()\n const manipulationCallBack = element => {\n if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {\n return\n }\n\n this._saveInitialAttribute(element, styleProperty)\n const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty)\n element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`)\n }\n\n this._applyManipulationCallback(selector, manipulationCallBack)\n }\n\n _saveInitialAttribute(element, styleProperty) {\n const actualValue = element.style.getPropertyValue(styleProperty)\n if (actualValue) {\n Manipulator.setDataAttribute(element, styleProperty, actualValue)\n }\n }\n\n _resetElementAttributes(selector, styleProperty) {\n const manipulationCallBack = element => {\n const value = Manipulator.getDataAttribute(element, styleProperty)\n // We only want to remove the property if the value is `null`; the value can also be zero\n if (value === null) {\n element.style.removeProperty(styleProperty)\n return\n }\n\n Manipulator.removeDataAttribute(element, styleProperty)\n element.style.setProperty(styleProperty, value)\n }\n\n this._applyManipulationCallback(selector, manipulationCallBack)\n }\n\n _applyManipulationCallback(selector, callBack) {\n if (isElement(selector)) {\n callBack(selector)\n return\n }\n\n for (const sel of SelectorEngine.find(selector, this._element)) {\n callBack(sel)\n }\n }\n}\n\nexport default ScrollBarHelper\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport Backdrop from './util/backdrop.js'\nimport { enableDismissTrigger } from './util/component-functions.js'\nimport FocusTrap from './util/focustrap.js'\nimport { defineJQueryPlugin, isRTL, isVisible, reflow } from './util/index.js'\nimport ScrollBarHelper from './util/scrollbar.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'modal'\nconst DATA_KEY = 'bs.modal'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst ESCAPE_KEY = 'Escape'\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_OPEN = 'modal-open'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_STATIC = 'modal-static'\n\nconst OPEN_SELECTOR = '.modal.show'\nconst SELECTOR_DIALOG = '.modal-dialog'\nconst SELECTOR_MODAL_BODY = '.modal-body'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"modal\"]'\n\nconst Default = {\n backdrop: true,\n focus: true,\n keyboard: true\n}\n\nconst DefaultType = {\n backdrop: '(boolean|string)',\n focus: 'boolean',\n keyboard: 'boolean'\n}\n\n/**\n * Class definition\n */\n\nclass Modal extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element)\n this._backdrop = this._initializeBackDrop()\n this._focustrap = this._initializeFocusTrap()\n this._isShown = false\n this._isTransitioning = false\n this._scrollBar = new ScrollBarHelper()\n\n this._addEventListeners()\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return\n }\n\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {\n relatedTarget\n })\n\n if (showEvent.defaultPrevented) {\n return\n }\n\n this._isShown = true\n this._isTransitioning = true\n\n this._scrollBar.hide()\n\n document.body.classList.add(CLASS_NAME_OPEN)\n\n this._adjustDialog()\n\n this._backdrop.show(() => this._showElement(relatedTarget))\n }\n\n hide() {\n if (!this._isShown || this._isTransitioning) {\n return\n }\n\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)\n\n if (hideEvent.defaultPrevented) {\n return\n }\n\n this._isShown = false\n this._isTransitioning = true\n this._focustrap.deactivate()\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n\n this._queueCallback(() => this._hideModal(), this._element, this._isAnimated())\n }\n\n dispose() {\n EventHandler.off(window, EVENT_KEY)\n EventHandler.off(this._dialog, EVENT_KEY)\n\n this._backdrop.dispose()\n this._focustrap.deactivate()\n\n super.dispose()\n }\n\n handleUpdate() {\n this._adjustDialog()\n }\n\n // Private\n _initializeBackDrop() {\n return new Backdrop({\n isVisible: Boolean(this._config.backdrop), // 'static' option will be translated to true, and booleans will keep their value,\n isAnimated: this._isAnimated()\n })\n }\n\n _initializeFocusTrap() {\n return new FocusTrap({\n trapElement: this._element\n })\n }\n\n _showElement(relatedTarget) {\n // try to append dynamic modal\n if (!document.body.contains(this._element)) {\n document.body.append(this._element)\n }\n\n this._element.style.display = 'block'\n this._element.removeAttribute('aria-hidden')\n this._element.setAttribute('aria-modal', true)\n this._element.setAttribute('role', 'dialog')\n this._element.scrollTop = 0\n\n const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog)\n if (modalBody) {\n modalBody.scrollTop = 0\n }\n\n reflow(this._element)\n\n this._element.classList.add(CLASS_NAME_SHOW)\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._focustrap.activate()\n }\n\n this._isTransitioning = false\n EventHandler.trigger(this._element, EVENT_SHOWN, {\n relatedTarget\n })\n }\n\n this._queueCallback(transitionComplete, this._dialog, this._isAnimated())\n }\n\n _addEventListeners() {\n EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {\n if (event.key !== ESCAPE_KEY) {\n return\n }\n\n if (this._config.keyboard) {\n this.hide()\n return\n }\n\n this._triggerBackdropTransition()\n })\n\n EventHandler.on(window, EVENT_RESIZE, () => {\n if (this._isShown && !this._isTransitioning) {\n this._adjustDialog()\n }\n })\n\n EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => {\n // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks\n EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => {\n if (this._element !== event.target || this._element !== event2.target) {\n return\n }\n\n if (this._config.backdrop === 'static') {\n this._triggerBackdropTransition()\n return\n }\n\n if (this._config.backdrop) {\n this.hide()\n }\n })\n })\n }\n\n _hideModal() {\n this._element.style.display = 'none'\n this._element.setAttribute('aria-hidden', true)\n this._element.removeAttribute('aria-modal')\n this._element.removeAttribute('role')\n this._isTransitioning = false\n\n this._backdrop.hide(() => {\n document.body.classList.remove(CLASS_NAME_OPEN)\n this._resetAdjustments()\n this._scrollBar.reset()\n EventHandler.trigger(this._element, EVENT_HIDDEN)\n })\n }\n\n _isAnimated() {\n return this._element.classList.contains(CLASS_NAME_FADE)\n }\n\n _triggerBackdropTransition() {\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)\n if (hideEvent.defaultPrevented) {\n return\n }\n\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n const initialOverflowY = this._element.style.overflowY\n // return if the following background transition hasn't yet completed\n if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) {\n return\n }\n\n if (!isModalOverflowing) {\n this._element.style.overflowY = 'hidden'\n }\n\n this._element.classList.add(CLASS_NAME_STATIC)\n this._queueCallback(() => {\n this._element.classList.remove(CLASS_NAME_STATIC)\n this._queueCallback(() => {\n this._element.style.overflowY = initialOverflowY\n }, this._dialog)\n }, this._dialog)\n\n this._element.focus()\n }\n\n /**\n * The following methods are used to handle overflowing modals\n */\n\n _adjustDialog() {\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n const scrollbarWidth = this._scrollBar.getWidth()\n const isBodyOverflowing = scrollbarWidth > 0\n\n if (isBodyOverflowing && !isModalOverflowing) {\n const property = isRTL() ? 'paddingLeft' : 'paddingRight'\n this._element.style[property] = `${scrollbarWidth}px`\n }\n\n if (!isBodyOverflowing && isModalOverflowing) {\n const property = isRTL() ? 'paddingRight' : 'paddingLeft'\n this._element.style[property] = `${scrollbarWidth}px`\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = ''\n this._element.style.paddingRight = ''\n }\n\n // Static\n static jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n const data = Modal.getOrCreateInstance(this, config)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](relatedTarget)\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n const target = SelectorEngine.getElementFromSelector(this)\n\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault()\n }\n\n EventHandler.one(target, EVENT_SHOW, showEvent => {\n if (showEvent.defaultPrevented) {\n // only register focus restorer if modal will actually get shown\n return\n }\n\n EventHandler.one(target, EVENT_HIDDEN, () => {\n if (isVisible(this)) {\n this.focus()\n }\n })\n })\n\n // avoid conflict when clicking modal toggler while another one is open\n const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR)\n if (alreadyOpen) {\n Modal.getInstance(alreadyOpen).hide()\n }\n\n const data = Modal.getOrCreateInstance(target)\n\n data.toggle(this)\n})\n\nenableDismissTrigger(Modal)\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Modal)\n\nexport default Modal\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap offcanvas.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport Backdrop from './util/backdrop.js'\nimport { enableDismissTrigger } from './util/component-functions.js'\nimport FocusTrap from './util/focustrap.js'\nimport {\n defineJQueryPlugin,\n isDisabled,\n isVisible\n} from './util/index.js'\nimport ScrollBarHelper from './util/scrollbar.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'offcanvas'\nconst DATA_KEY = 'bs.offcanvas'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\nconst ESCAPE_KEY = 'Escape'\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_SHOWING = 'showing'\nconst CLASS_NAME_HIDING = 'hiding'\nconst CLASS_NAME_BACKDROP = 'offcanvas-backdrop'\nconst OPEN_SELECTOR = '.offcanvas.show'\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\n\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"offcanvas\"]'\n\nconst Default = {\n backdrop: true,\n keyboard: true,\n scroll: false\n}\n\nconst DefaultType = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n scroll: 'boolean'\n}\n\n/**\n * Class definition\n */\n\nclass Offcanvas extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n this._isShown = false\n this._backdrop = this._initializeBackDrop()\n this._focustrap = this._initializeFocusTrap()\n this._addEventListeners()\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isShown) {\n return\n }\n\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, { relatedTarget })\n\n if (showEvent.defaultPrevented) {\n return\n }\n\n this._isShown = true\n this._backdrop.show()\n\n if (!this._config.scroll) {\n new ScrollBarHelper().hide()\n }\n\n this._element.setAttribute('aria-modal', true)\n this._element.setAttribute('role', 'dialog')\n this._element.classList.add(CLASS_NAME_SHOWING)\n\n const completeCallBack = () => {\n if (!this._config.scroll || this._config.backdrop) {\n this._focustrap.activate()\n }\n\n this._element.classList.add(CLASS_NAME_SHOW)\n this._element.classList.remove(CLASS_NAME_SHOWING)\n EventHandler.trigger(this._element, EVENT_SHOWN, { relatedTarget })\n }\n\n this._queueCallback(completeCallBack, this._element, true)\n }\n\n hide() {\n if (!this._isShown) {\n return\n }\n\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)\n\n if (hideEvent.defaultPrevented) {\n return\n }\n\n this._focustrap.deactivate()\n this._element.blur()\n this._isShown = false\n this._element.classList.add(CLASS_NAME_HIDING)\n this._backdrop.hide()\n\n const completeCallback = () => {\n this._element.classList.remove(CLASS_NAME_SHOW, CLASS_NAME_HIDING)\n this._element.removeAttribute('aria-modal')\n this._element.removeAttribute('role')\n\n if (!this._config.scroll) {\n new ScrollBarHelper().reset()\n }\n\n EventHandler.trigger(this._element, EVENT_HIDDEN)\n }\n\n this._queueCallback(completeCallback, this._element, true)\n }\n\n dispose() {\n this._backdrop.dispose()\n this._focustrap.deactivate()\n super.dispose()\n }\n\n // Private\n _initializeBackDrop() {\n const clickCallback = () => {\n if (this._config.backdrop === 'static') {\n EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)\n return\n }\n\n this.hide()\n }\n\n // 'static' option will be translated to true, and booleans will keep their value\n const isVisible = Boolean(this._config.backdrop)\n\n return new Backdrop({\n className: CLASS_NAME_BACKDROP,\n isVisible,\n isAnimated: true,\n rootElement: this._element.parentNode,\n clickCallback: isVisible ? clickCallback : null\n })\n }\n\n _initializeFocusTrap() {\n return new FocusTrap({\n trapElement: this._element\n })\n }\n\n _addEventListeners() {\n EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {\n if (event.key !== ESCAPE_KEY) {\n return\n }\n\n if (this._config.keyboard) {\n this.hide()\n return\n }\n\n EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)\n })\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Offcanvas.getOrCreateInstance(this, config)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n const target = SelectorEngine.getElementFromSelector(this)\n\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault()\n }\n\n if (isDisabled(this)) {\n return\n }\n\n EventHandler.one(target, EVENT_HIDDEN, () => {\n // focus on trigger when it is closed\n if (isVisible(this)) {\n this.focus()\n }\n })\n\n // avoid conflict when clicking a toggler of an offcanvas, while another is open\n const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR)\n if (alreadyOpen && alreadyOpen !== target) {\n Offcanvas.getInstance(alreadyOpen).hide()\n }\n\n const data = Offcanvas.getOrCreateInstance(target)\n data.toggle(this)\n})\n\nEventHandler.on(window, EVENT_LOAD_DATA_API, () => {\n for (const selector of SelectorEngine.find(OPEN_SELECTOR)) {\n Offcanvas.getOrCreateInstance(selector).show()\n }\n})\n\nEventHandler.on(window, EVENT_RESIZE, () => {\n for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) {\n if (getComputedStyle(element).position !== 'fixed') {\n Offcanvas.getOrCreateInstance(element).hide()\n }\n }\n})\n\nenableDismissTrigger(Offcanvas)\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Offcanvas)\n\nexport default Offcanvas\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap util/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n// js-docs-start allow-list\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i\n\nexport const DefaultAllowlist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n}\n// js-docs-end allow-list\n\nconst uriAttributes = new Set([\n 'background',\n 'cite',\n 'href',\n 'itemtype',\n 'longdesc',\n 'poster',\n 'src',\n 'xlink:href'\n])\n\n/**\n * A pattern that recognizes URLs that are safe wrt. XSS in URL navigation\n * contexts.\n *\n * Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38\n */\n// eslint-disable-next-line unicorn/better-regex\nconst SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i\n\nconst allowedAttribute = (attribute, allowedAttributeList) => {\n const attributeName = attribute.nodeName.toLowerCase()\n\n if (allowedAttributeList.includes(attributeName)) {\n if (uriAttributes.has(attributeName)) {\n return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue))\n }\n\n return true\n }\n\n // Check if a regular expression validates the attribute.\n return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp)\n .some(regex => regex.test(attributeName))\n}\n\nexport function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {\n if (!unsafeHtml.length) {\n return unsafeHtml\n }\n\n if (sanitizeFunction && typeof sanitizeFunction === 'function') {\n return sanitizeFunction(unsafeHtml)\n }\n\n const domParser = new window.DOMParser()\n const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html')\n const elements = [].concat(...createdDocument.body.querySelectorAll('*'))\n\n for (const element of elements) {\n const elementName = element.nodeName.toLowerCase()\n\n if (!Object.keys(allowList).includes(elementName)) {\n element.remove()\n continue\n }\n\n const attributeList = [].concat(...element.attributes)\n const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || [])\n\n for (const attribute of attributeList) {\n if (!allowedAttribute(attribute, allowedAttributes)) {\n element.removeAttribute(attribute.nodeName)\n }\n }\n }\n\n return createdDocument.body.innerHTML\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap util/template-factory.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport SelectorEngine from '../dom/selector-engine.js'\nimport Config from './config.js'\nimport { DefaultAllowlist, sanitizeHtml } from './sanitizer.js'\nimport { execute, getElement, isElement } from './index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'TemplateFactory'\n\nconst Default = {\n allowList: DefaultAllowlist,\n content: {}, // { selector : text , selector2 : text2 , }\n extraClass: '',\n html: false,\n sanitize: true,\n sanitizeFn: null,\n template: '
'\n}\n\nconst DefaultType = {\n allowList: 'object',\n content: 'object',\n extraClass: '(string|function)',\n html: 'boolean',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n template: 'string'\n}\n\nconst DefaultContentType = {\n entry: '(string|element|function|null)',\n selector: '(string|element)'\n}\n\n/**\n * Class definition\n */\n\nclass TemplateFactory extends Config {\n constructor(config) {\n super()\n this._config = this._getConfig(config)\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n getContent() {\n return Object.values(this._config.content)\n .map(config => this._resolvePossibleFunction(config))\n .filter(Boolean)\n }\n\n hasContent() {\n return this.getContent().length > 0\n }\n\n changeContent(content) {\n this._checkContent(content)\n this._config.content = { ...this._config.content, ...content }\n return this\n }\n\n toHtml() {\n const templateWrapper = document.createElement('div')\n templateWrapper.innerHTML = this._maybeSanitize(this._config.template)\n\n for (const [selector, text] of Object.entries(this._config.content)) {\n this._setContent(templateWrapper, text, selector)\n }\n\n const template = templateWrapper.children[0]\n const extraClass = this._resolvePossibleFunction(this._config.extraClass)\n\n if (extraClass) {\n template.classList.add(...extraClass.split(' '))\n }\n\n return template\n }\n\n // Private\n _typeCheckConfig(config) {\n super._typeCheckConfig(config)\n this._checkContent(config.content)\n }\n\n _checkContent(arg) {\n for (const [selector, content] of Object.entries(arg)) {\n super._typeCheckConfig({ selector, entry: content }, DefaultContentType)\n }\n }\n\n _setContent(template, content, selector) {\n const templateElement = SelectorEngine.findOne(selector, template)\n\n if (!templateElement) {\n return\n }\n\n content = this._resolvePossibleFunction(content)\n\n if (!content) {\n templateElement.remove()\n return\n }\n\n if (isElement(content)) {\n this._putElementInTemplate(getElement(content), templateElement)\n return\n }\n\n if (this._config.html) {\n templateElement.innerHTML = this._maybeSanitize(content)\n return\n }\n\n templateElement.textContent = content\n }\n\n _maybeSanitize(arg) {\n return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg\n }\n\n _resolvePossibleFunction(arg) {\n return execute(arg, [this])\n }\n\n _putElementInTemplate(element, templateElement) {\n if (this._config.html) {\n templateElement.innerHTML = ''\n templateElement.append(element)\n return\n }\n\n templateElement.textContent = element.textContent\n }\n}\n\nexport default TemplateFactory\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport * as Popper from '@popperjs/core'\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport Manipulator from './dom/manipulator.js'\nimport { defineJQueryPlugin, execute, findShadowRoot, getElement, getUID, isRTL, noop } from './util/index.js'\nimport { DefaultAllowlist } from './util/sanitizer.js'\nimport TemplateFactory from './util/template-factory.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'tooltip'\nconst DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn'])\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_MODAL = 'modal'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner'\nconst SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`\n\nconst EVENT_MODAL_HIDE = 'hide.bs.modal'\n\nconst TRIGGER_HOVER = 'hover'\nconst TRIGGER_FOCUS = 'focus'\nconst TRIGGER_CLICK = 'click'\nconst TRIGGER_MANUAL = 'manual'\n\nconst EVENT_HIDE = 'hide'\nconst EVENT_HIDDEN = 'hidden'\nconst EVENT_SHOW = 'show'\nconst EVENT_SHOWN = 'shown'\nconst EVENT_INSERTED = 'inserted'\nconst EVENT_CLICK = 'click'\nconst EVENT_FOCUSIN = 'focusin'\nconst EVENT_FOCUSOUT = 'focusout'\nconst EVENT_MOUSEENTER = 'mouseenter'\nconst EVENT_MOUSELEAVE = 'mouseleave'\n\nconst AttachmentMap = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: isRTL() ? 'left' : 'right',\n BOTTOM: 'bottom',\n LEFT: isRTL() ? 'right' : 'left'\n}\n\nconst Default = {\n allowList: DefaultAllowlist,\n animation: true,\n boundary: 'clippingParents',\n container: false,\n customClass: '',\n delay: 0,\n fallbackPlacements: ['top', 'right', 'bottom', 'left'],\n html: false,\n offset: [0, 6],\n placement: 'top',\n popperConfig: null,\n sanitize: true,\n sanitizeFn: null,\n selector: false,\n template: '
' +\n '
' +\n '
' +\n '
',\n title: '',\n trigger: 'hover focus'\n}\n\nconst DefaultType = {\n allowList: 'object',\n animation: 'boolean',\n boundary: '(string|element)',\n container: '(string|element|boolean)',\n customClass: '(string|function)',\n delay: '(number|object)',\n fallbackPlacements: 'array',\n html: 'boolean',\n offset: '(array|string|function)',\n placement: '(string|function)',\n popperConfig: '(null|object|function)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n selector: '(string|boolean)',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string'\n}\n\n/**\n * Class definition\n */\n\nclass Tooltip extends BaseComponent {\n constructor(element, config) {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org)')\n }\n\n super(element, config)\n\n // Private\n this._isEnabled = true\n this._timeout = 0\n this._isHovered = null\n this._activeTrigger = {}\n this._popper = null\n this._templateFactory = null\n this._newContent = null\n\n // Protected\n this.tip = null\n\n this._setListeners()\n\n if (!this._config.selector) {\n this._fixTitle()\n }\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n enable() {\n this._isEnabled = true\n }\n\n disable() {\n this._isEnabled = false\n }\n\n toggleEnabled() {\n this._isEnabled = !this._isEnabled\n }\n\n toggle() {\n if (!this._isEnabled) {\n return\n }\n\n this._activeTrigger.click = !this._activeTrigger.click\n if (this._isShown()) {\n this._leave()\n return\n }\n\n this._enter()\n }\n\n dispose() {\n clearTimeout(this._timeout)\n\n EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler)\n\n if (this._element.getAttribute('data-bs-original-title')) {\n this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title'))\n }\n\n this._disposePopper()\n super.dispose()\n }\n\n show() {\n if (this._element.style.display === 'none') {\n throw new Error('Please use show on visible elements')\n }\n\n if (!(this._isWithContent() && this._isEnabled)) {\n return\n }\n\n const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW))\n const shadowRoot = findShadowRoot(this._element)\n const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element)\n\n if (showEvent.defaultPrevented || !isInTheDom) {\n return\n }\n\n // TODO: v6 remove this or make it optional\n this._disposePopper()\n\n const tip = this._getTipElement()\n\n this._element.setAttribute('aria-describedby', tip.getAttribute('id'))\n\n const { container } = this._config\n\n if (!this._element.ownerDocument.documentElement.contains(this.tip)) {\n container.append(tip)\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED))\n }\n\n this._popper = this._createPopper(tip)\n\n tip.classList.add(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.on(element, 'mouseover', noop)\n }\n }\n\n const complete = () => {\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN))\n\n if (this._isHovered === false) {\n this._leave()\n }\n\n this._isHovered = false\n }\n\n this._queueCallback(complete, this.tip, this._isAnimated())\n }\n\n hide() {\n if (!this._isShown()) {\n return\n }\n\n const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE))\n if (hideEvent.defaultPrevented) {\n return\n }\n\n const tip = this._getTipElement()\n tip.classList.remove(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.off(element, 'mouseover', noop)\n }\n }\n\n this._activeTrigger[TRIGGER_CLICK] = false\n this._activeTrigger[TRIGGER_FOCUS] = false\n this._activeTrigger[TRIGGER_HOVER] = false\n this._isHovered = null // it is a trick to support manual triggering\n\n const complete = () => {\n if (this._isWithActiveTrigger()) {\n return\n }\n\n if (!this._isHovered) {\n this._disposePopper()\n }\n\n this._element.removeAttribute('aria-describedby')\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN))\n }\n\n this._queueCallback(complete, this.tip, this._isAnimated())\n }\n\n update() {\n if (this._popper) {\n this._popper.update()\n }\n }\n\n // Protected\n _isWithContent() {\n return Boolean(this._getTitle())\n }\n\n _getTipElement() {\n if (!this.tip) {\n this.tip = this._createTipElement(this._newContent || this._getContentForTemplate())\n }\n\n return this.tip\n }\n\n _createTipElement(content) {\n const tip = this._getTemplateFactory(content).toHtml()\n\n // TODO: remove this check in v6\n if (!tip) {\n return null\n }\n\n tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW)\n // TODO: v6 the following can be achieved with CSS only\n tip.classList.add(`bs-${this.constructor.NAME}-auto`)\n\n const tipId = getUID(this.constructor.NAME).toString()\n\n tip.setAttribute('id', tipId)\n\n if (this._isAnimated()) {\n tip.classList.add(CLASS_NAME_FADE)\n }\n\n return tip\n }\n\n setContent(content) {\n this._newContent = content\n if (this._isShown()) {\n this._disposePopper()\n this.show()\n }\n }\n\n _getTemplateFactory(content) {\n if (this._templateFactory) {\n this._templateFactory.changeContent(content)\n } else {\n this._templateFactory = new TemplateFactory({\n ...this._config,\n // the `content` var has to be after `this._config`\n // to override config.content in case of popover\n content,\n extraClass: this._resolvePossibleFunction(this._config.customClass)\n })\n }\n\n return this._templateFactory\n }\n\n _getContentForTemplate() {\n return {\n [SELECTOR_TOOLTIP_INNER]: this._getTitle()\n }\n }\n\n _getTitle() {\n return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title')\n }\n\n // Private\n _initializeOnDelegatedTarget(event) {\n return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig())\n }\n\n _isAnimated() {\n return this._config.animation || (this.tip && this.tip.classList.contains(CLASS_NAME_FADE))\n }\n\n _isShown() {\n return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW)\n }\n\n _createPopper(tip) {\n const placement = execute(this._config.placement, [this, tip, this._element])\n const attachment = AttachmentMap[placement.toUpperCase()]\n return Popper.createPopper(this._element, tip, this._getPopperConfig(attachment))\n }\n\n _getOffset() {\n const { offset } = this._config\n\n if (typeof offset === 'string') {\n return offset.split(',').map(value => Number.parseInt(value, 10))\n }\n\n if (typeof offset === 'function') {\n return popperData => offset(popperData, this._element)\n }\n\n return offset\n }\n\n _resolvePossibleFunction(arg) {\n return execute(arg, [this._element])\n }\n\n _getPopperConfig(attachment) {\n const defaultBsPopperConfig = {\n placement: attachment,\n modifiers: [\n {\n name: 'flip',\n options: {\n fallbackPlacements: this._config.fallbackPlacements\n }\n },\n {\n name: 'offset',\n options: {\n offset: this._getOffset()\n }\n },\n {\n name: 'preventOverflow',\n options: {\n boundary: this._config.boundary\n }\n },\n {\n name: 'arrow',\n options: {\n element: `.${this.constructor.NAME}-arrow`\n }\n },\n {\n name: 'preSetPlacement',\n enabled: true,\n phase: 'beforeMain',\n fn: data => {\n // Pre-set Popper's placement attribute in order to read the arrow sizes properly.\n // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement\n this._getTipElement().setAttribute('data-popper-placement', data.state.placement)\n }\n }\n ]\n }\n\n return {\n ...defaultBsPopperConfig,\n ...execute(this._config.popperConfig, [defaultBsPopperConfig])\n }\n }\n\n _setListeners() {\n const triggers = this._config.trigger.split(' ')\n\n for (const trigger of triggers) {\n if (trigger === 'click') {\n EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK), this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event)\n context.toggle()\n })\n } else if (trigger !== TRIGGER_MANUAL) {\n const eventIn = trigger === TRIGGER_HOVER ?\n this.constructor.eventName(EVENT_MOUSEENTER) :\n this.constructor.eventName(EVENT_FOCUSIN)\n const eventOut = trigger === TRIGGER_HOVER ?\n this.constructor.eventName(EVENT_MOUSELEAVE) :\n this.constructor.eventName(EVENT_FOCUSOUT)\n\n EventHandler.on(this._element, eventIn, this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event)\n context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true\n context._enter()\n })\n EventHandler.on(this._element, eventOut, this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event)\n context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] =\n context._element.contains(event.relatedTarget)\n\n context._leave()\n })\n }\n }\n\n this._hideModalHandler = () => {\n if (this._element) {\n this.hide()\n }\n }\n\n EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler)\n }\n\n _fixTitle() {\n const title = this._element.getAttribute('title')\n\n if (!title) {\n return\n }\n\n if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) {\n this._element.setAttribute('aria-label', title)\n }\n\n this._element.setAttribute('data-bs-original-title', title) // DO NOT USE IT. Is only for backwards compatibility\n this._element.removeAttribute('title')\n }\n\n _enter() {\n if (this._isShown() || this._isHovered) {\n this._isHovered = true\n return\n }\n\n this._isHovered = true\n\n this._setTimeout(() => {\n if (this._isHovered) {\n this.show()\n }\n }, this._config.delay.show)\n }\n\n _leave() {\n if (this._isWithActiveTrigger()) {\n return\n }\n\n this._isHovered = false\n\n this._setTimeout(() => {\n if (!this._isHovered) {\n this.hide()\n }\n }, this._config.delay.hide)\n }\n\n _setTimeout(handler, timeout) {\n clearTimeout(this._timeout)\n this._timeout = setTimeout(handler, timeout)\n }\n\n _isWithActiveTrigger() {\n return Object.values(this._activeTrigger).includes(true)\n }\n\n _getConfig(config) {\n const dataAttributes = Manipulator.getDataAttributes(this._element)\n\n for (const dataAttribute of Object.keys(dataAttributes)) {\n if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) {\n delete dataAttributes[dataAttribute]\n }\n }\n\n config = {\n ...dataAttributes,\n ...(typeof config === 'object' && config ? config : {})\n }\n config = this._mergeConfigObj(config)\n config = this._configAfterMerge(config)\n this._typeCheckConfig(config)\n return config\n }\n\n _configAfterMerge(config) {\n config.container = config.container === false ? document.body : getElement(config.container)\n\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n }\n }\n\n if (typeof config.title === 'number') {\n config.title = config.title.toString()\n }\n\n if (typeof config.content === 'number') {\n config.content = config.content.toString()\n }\n\n return config\n }\n\n _getDelegateConfig() {\n const config = {}\n\n for (const [key, value] of Object.entries(this._config)) {\n if (this.constructor.Default[key] !== value) {\n config[key] = value\n }\n }\n\n config.selector = false\n config.trigger = 'manual'\n\n // In the future can be replaced with:\n // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])\n // `Object.fromEntries(keysWithDifferentValues)`\n return config\n }\n\n _disposePopper() {\n if (this._popper) {\n this._popper.destroy()\n this._popper = null\n }\n\n if (this.tip) {\n this.tip.remove()\n this.tip = null\n }\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Tooltip.getOrCreateInstance(this, config)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n })\n }\n}\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Tooltip)\n\nexport default Tooltip\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Tooltip from './tooltip.js'\nimport { defineJQueryPlugin } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'popover'\n\nconst SELECTOR_TITLE = '.popover-header'\nconst SELECTOR_CONTENT = '.popover-body'\n\nconst Default = {\n ...Tooltip.Default,\n content: '',\n offset: [0, 8],\n placement: 'right',\n template: '
' +\n '
' +\n '

' +\n '
' +\n '
',\n trigger: 'click'\n}\n\nconst DefaultType = {\n ...Tooltip.DefaultType,\n content: '(null|string|element|function)'\n}\n\n/**\n * Class definition\n */\n\nclass Popover extends Tooltip {\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Overrides\n _isWithContent() {\n return this._getTitle() || this._getContent()\n }\n\n // Private\n _getContentForTemplate() {\n return {\n [SELECTOR_TITLE]: this._getTitle(),\n [SELECTOR_CONTENT]: this._getContent()\n }\n }\n\n _getContent() {\n return this._resolvePossibleFunction(this._config.content)\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Popover.getOrCreateInstance(this, config)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n })\n }\n}\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Popover)\n\nexport default Popover\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport { defineJQueryPlugin, getElement, isDisabled, isVisible } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'scrollspy'\nconst DATA_KEY = 'bs.scrollspy'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst EVENT_ACTIVATE = `activate${EVENT_KEY}`\nconst EVENT_CLICK = `click${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'\nconst CLASS_NAME_ACTIVE = 'active'\n\nconst SELECTOR_DATA_SPY = '[data-bs-spy=\"scroll\"]'\nconst SELECTOR_TARGET_LINKS = '[href]'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_NAV_LINKS = '.nav-link'\nconst SELECTOR_NAV_ITEMS = '.nav-item'\nconst SELECTOR_LIST_ITEMS = '.list-group-item'\nconst SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\n\nconst Default = {\n offset: null, // TODO: v6 @deprecated, keep it for backwards compatibility reasons\n rootMargin: '0px 0px -25%',\n smoothScroll: false,\n target: null,\n threshold: [0.1, 0.5, 1]\n}\n\nconst DefaultType = {\n offset: '(number|null)', // TODO v6 @deprecated, keep it for backwards compatibility reasons\n rootMargin: 'string',\n smoothScroll: 'boolean',\n target: 'element',\n threshold: 'array'\n}\n\n/**\n * Class definition\n */\n\nclass ScrollSpy extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n // this._element is the observablesContainer and config.target the menu links wrapper\n this._targetLinks = new Map()\n this._observableSections = new Map()\n this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element\n this._activeTarget = null\n this._observer = null\n this._previousScrollData = {\n visibleEntryTop: 0,\n parentScrollTop: 0\n }\n this.refresh() // initialize\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n refresh() {\n this._initializeTargetsAndObservables()\n this._maybeEnableSmoothScroll()\n\n if (this._observer) {\n this._observer.disconnect()\n } else {\n this._observer = this._getNewObserver()\n }\n\n for (const section of this._observableSections.values()) {\n this._observer.observe(section)\n }\n }\n\n dispose() {\n this._observer.disconnect()\n super.dispose()\n }\n\n // Private\n _configAfterMerge(config) {\n // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case\n config.target = getElement(config.target) || document.body\n\n // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only\n config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin\n\n if (typeof config.threshold === 'string') {\n config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value))\n }\n\n return config\n }\n\n _maybeEnableSmoothScroll() {\n if (!this._config.smoothScroll) {\n return\n }\n\n // unregister any previous listeners\n EventHandler.off(this._config.target, EVENT_CLICK)\n\n EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => {\n const observableSection = this._observableSections.get(event.target.hash)\n if (observableSection) {\n event.preventDefault()\n const root = this._rootElement || window\n const height = observableSection.offsetTop - this._element.offsetTop\n if (root.scrollTo) {\n root.scrollTo({ top: height, behavior: 'smooth' })\n return\n }\n\n // Chrome 60 doesn't support `scrollTo`\n root.scrollTop = height\n }\n })\n }\n\n _getNewObserver() {\n const options = {\n root: this._rootElement,\n threshold: this._config.threshold,\n rootMargin: this._config.rootMargin\n }\n\n return new IntersectionObserver(entries => this._observerCallback(entries), options)\n }\n\n // The logic of selection\n _observerCallback(entries) {\n const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`)\n const activate = entry => {\n this._previousScrollData.visibleEntryTop = entry.target.offsetTop\n this._process(targetElement(entry))\n }\n\n const parentScrollTop = (this._rootElement || document.documentElement).scrollTop\n const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop\n this._previousScrollData.parentScrollTop = parentScrollTop\n\n for (const entry of entries) {\n if (!entry.isIntersecting) {\n this._activeTarget = null\n this._clearActiveClass(targetElement(entry))\n\n continue\n }\n\n const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop\n // if we are scrolling down, pick the bigger offsetTop\n if (userScrollsDown && entryIsLowerThanPrevious) {\n activate(entry)\n // if parent isn't scrolled, let's keep the first visible item, breaking the iteration\n if (!parentScrollTop) {\n return\n }\n\n continue\n }\n\n // if we are scrolling up, pick the smallest offsetTop\n if (!userScrollsDown && !entryIsLowerThanPrevious) {\n activate(entry)\n }\n }\n }\n\n _initializeTargetsAndObservables() {\n this._targetLinks = new Map()\n this._observableSections = new Map()\n\n const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target)\n\n for (const anchor of targetLinks) {\n // ensure that the anchor has an id and is not disabled\n if (!anchor.hash || isDisabled(anchor)) {\n continue\n }\n\n const observableSection = SelectorEngine.findOne(decodeURI(anchor.hash), this._element)\n\n // ensure that the observableSection exists & is visible\n if (isVisible(observableSection)) {\n this._targetLinks.set(decodeURI(anchor.hash), anchor)\n this._observableSections.set(anchor.hash, observableSection)\n }\n }\n }\n\n _process(target) {\n if (this._activeTarget === target) {\n return\n }\n\n this._clearActiveClass(this._config.target)\n this._activeTarget = target\n target.classList.add(CLASS_NAME_ACTIVE)\n this._activateParents(target)\n\n EventHandler.trigger(this._element, EVENT_ACTIVATE, { relatedTarget: target })\n }\n\n _activateParents(target) {\n // Activate dropdown parents\n if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {\n SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE, target.closest(SELECTOR_DROPDOWN))\n .classList.add(CLASS_NAME_ACTIVE)\n return\n }\n\n for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) {\n // Set triggered links parents as active\n // With both
    and
')},createChildNavList:function(e){var t=this.createNavList();return e.append(t),t},generateNavEl:function(e,t){var n=a('
');n.attr("href","#"+e),n.text(t);var r=a("
  • ");return r.append(n),r},generateNavItem:function(e){var t=this.generateAnchor(e),n=a(e),r=n.data("toc-text")||n.text();return this.generateNavEl(t,r)},getTopLevel:function(e){for(var t=1;t<=6;t++){if(1 + + + + + + + + + + + + diff --git a/docs/deps/font-awesome-6.5.2/css/all.css b/docs/deps/font-awesome-6.5.2/css/all.css new file mode 100644 index 00000000..151dd57c --- /dev/null +++ b/docs/deps/font-awesome-6.5.2/css/all.css @@ -0,0 +1,8028 @@ +/*! + * Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + * Copyright 2024 Fonticons, Inc. + */ +.fa { + font-family: var(--fa-style-family, "Font Awesome 6 Free"); + font-weight: var(--fa-style, 900); } + +.fa, +.fa-classic, +.fa-sharp, +.fas, +.fa-solid, +.far, +.fa-regular, +.fab, +.fa-brands { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: var(--fa-display, inline-block); + font-style: normal; + font-variant: normal; + line-height: 1; + text-rendering: auto; } + +.fas, +.fa-classic, +.fa-solid, +.far, +.fa-regular { + font-family: 'Font Awesome 6 Free'; } + +.fab, +.fa-brands { + font-family: 'Font Awesome 6 Brands'; } + +.fa-1x { + font-size: 1em; } + +.fa-2x { + font-size: 2em; } + +.fa-3x { + font-size: 3em; } + +.fa-4x { + font-size: 4em; } + +.fa-5x { + font-size: 5em; } + +.fa-6x { + font-size: 6em; } + +.fa-7x { + font-size: 7em; } + +.fa-8x { + font-size: 8em; } + +.fa-9x { + font-size: 9em; } + +.fa-10x { + font-size: 10em; } + +.fa-2xs { + font-size: 0.625em; + line-height: 0.1em; + vertical-align: 0.225em; } + +.fa-xs { + font-size: 0.75em; + line-height: 0.08333em; + vertical-align: 0.125em; } + +.fa-sm { + font-size: 0.875em; + line-height: 0.07143em; + vertical-align: 0.05357em; } + +.fa-lg { + font-size: 1.25em; + line-height: 0.05em; + vertical-align: -0.075em; } + +.fa-xl { + font-size: 1.5em; + line-height: 0.04167em; + vertical-align: -0.125em; } + +.fa-2xl { + font-size: 2em; + line-height: 0.03125em; + vertical-align: -0.1875em; } + +.fa-fw { + text-align: center; + width: 1.25em; } + +.fa-ul { + list-style-type: none; + margin-left: var(--fa-li-margin, 2.5em); + padding-left: 0; } + .fa-ul > li { + position: relative; } + +.fa-li { + left: calc(var(--fa-li-width, 2em) * -1); + position: absolute; + text-align: center; + width: var(--fa-li-width, 2em); + line-height: inherit; } + +.fa-border { + border-color: var(--fa-border-color, #eee); + border-radius: var(--fa-border-radius, 0.1em); + border-style: var(--fa-border-style, solid); + border-width: var(--fa-border-width, 0.08em); + padding: var(--fa-border-padding, 0.2em 0.25em 0.15em); } + +.fa-pull-left { + float: left; + margin-right: var(--fa-pull-margin, 0.3em); } + +.fa-pull-right { + float: right; + margin-left: var(--fa-pull-margin, 0.3em); } + +.fa-beat { + -webkit-animation-name: fa-beat; + animation-name: fa-beat; + -webkit-animation-delay: var(--fa-animation-delay, 0s); + animation-delay: var(--fa-animation-delay, 0s); + -webkit-animation-direction: var(--fa-animation-direction, normal); + animation-direction: var(--fa-animation-direction, normal); + -webkit-animation-duration: var(--fa-animation-duration, 1s); + animation-duration: var(--fa-animation-duration, 1s); + -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite); + animation-iteration-count: var(--fa-animation-iteration-count, infinite); + -webkit-animation-timing-function: var(--fa-animation-timing, ease-in-out); + animation-timing-function: var(--fa-animation-timing, ease-in-out); } + +.fa-bounce { + -webkit-animation-name: fa-bounce; + animation-name: fa-bounce; + -webkit-animation-delay: var(--fa-animation-delay, 0s); + animation-delay: var(--fa-animation-delay, 0s); + -webkit-animation-direction: var(--fa-animation-direction, normal); + animation-direction: var(--fa-animation-direction, normal); + -webkit-animation-duration: var(--fa-animation-duration, 1s); + animation-duration: var(--fa-animation-duration, 1s); + -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite); + animation-iteration-count: var(--fa-animation-iteration-count, infinite); + -webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1)); + animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1)); } + +.fa-fade { + -webkit-animation-name: fa-fade; + animation-name: fa-fade; + -webkit-animation-delay: var(--fa-animation-delay, 0s); + animation-delay: var(--fa-animation-delay, 0s); + -webkit-animation-direction: var(--fa-animation-direction, normal); + animation-direction: var(--fa-animation-direction, normal); + -webkit-animation-duration: var(--fa-animation-duration, 1s); + animation-duration: var(--fa-animation-duration, 1s); + -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite); + animation-iteration-count: var(--fa-animation-iteration-count, infinite); + -webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1)); + animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1)); } + +.fa-beat-fade { + -webkit-animation-name: fa-beat-fade; + animation-name: fa-beat-fade; + -webkit-animation-delay: var(--fa-animation-delay, 0s); + animation-delay: var(--fa-animation-delay, 0s); + -webkit-animation-direction: var(--fa-animation-direction, normal); + animation-direction: var(--fa-animation-direction, normal); + -webkit-animation-duration: var(--fa-animation-duration, 1s); + animation-duration: var(--fa-animation-duration, 1s); + -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite); + animation-iteration-count: var(--fa-animation-iteration-count, infinite); + -webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1)); + animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1)); } + +.fa-flip { + -webkit-animation-name: fa-flip; + animation-name: fa-flip; + -webkit-animation-delay: var(--fa-animation-delay, 0s); + animation-delay: var(--fa-animation-delay, 0s); + -webkit-animation-direction: var(--fa-animation-direction, normal); + animation-direction: var(--fa-animation-direction, normal); + -webkit-animation-duration: var(--fa-animation-duration, 1s); + animation-duration: var(--fa-animation-duration, 1s); + -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite); + animation-iteration-count: var(--fa-animation-iteration-count, infinite); + -webkit-animation-timing-function: var(--fa-animation-timing, ease-in-out); + animation-timing-function: var(--fa-animation-timing, ease-in-out); } + +.fa-shake { + -webkit-animation-name: fa-shake; + animation-name: fa-shake; + -webkit-animation-delay: var(--fa-animation-delay, 0s); + animation-delay: var(--fa-animation-delay, 0s); + -webkit-animation-direction: var(--fa-animation-direction, normal); + animation-direction: var(--fa-animation-direction, normal); + -webkit-animation-duration: var(--fa-animation-duration, 1s); + animation-duration: var(--fa-animation-duration, 1s); + -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite); + animation-iteration-count: var(--fa-animation-iteration-count, infinite); + -webkit-animation-timing-function: var(--fa-animation-timing, linear); + animation-timing-function: var(--fa-animation-timing, linear); } + +.fa-spin { + -webkit-animation-name: fa-spin; + animation-name: fa-spin; + -webkit-animation-delay: var(--fa-animation-delay, 0s); + animation-delay: var(--fa-animation-delay, 0s); + -webkit-animation-direction: var(--fa-animation-direction, normal); + animation-direction: var(--fa-animation-direction, normal); + -webkit-animation-duration: var(--fa-animation-duration, 2s); + animation-duration: var(--fa-animation-duration, 2s); + -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite); + animation-iteration-count: var(--fa-animation-iteration-count, infinite); + -webkit-animation-timing-function: var(--fa-animation-timing, linear); + animation-timing-function: var(--fa-animation-timing, linear); } + +.fa-spin-reverse { + --fa-animation-direction: reverse; } + +.fa-pulse, +.fa-spin-pulse { + -webkit-animation-name: fa-spin; + animation-name: fa-spin; + -webkit-animation-direction: var(--fa-animation-direction, normal); + animation-direction: var(--fa-animation-direction, normal); + -webkit-animation-duration: var(--fa-animation-duration, 1s); + animation-duration: var(--fa-animation-duration, 1s); + -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite); + animation-iteration-count: var(--fa-animation-iteration-count, infinite); + -webkit-animation-timing-function: var(--fa-animation-timing, steps(8)); + animation-timing-function: var(--fa-animation-timing, steps(8)); } + +@media (prefers-reduced-motion: reduce) { + .fa-beat, + .fa-bounce, + .fa-fade, + .fa-beat-fade, + .fa-flip, + .fa-pulse, + .fa-shake, + .fa-spin, + .fa-spin-pulse { + -webkit-animation-delay: -1ms; + animation-delay: -1ms; + -webkit-animation-duration: 1ms; + animation-duration: 1ms; + -webkit-animation-iteration-count: 1; + animation-iteration-count: 1; + -webkit-transition-delay: 0s; + transition-delay: 0s; + -webkit-transition-duration: 0s; + transition-duration: 0s; } } + +@-webkit-keyframes fa-beat { + 0%, 90% { + -webkit-transform: scale(1); + transform: scale(1); } + 45% { + -webkit-transform: scale(var(--fa-beat-scale, 1.25)); + transform: scale(var(--fa-beat-scale, 1.25)); } } + +@keyframes fa-beat { + 0%, 90% { + -webkit-transform: scale(1); + transform: scale(1); } + 45% { + -webkit-transform: scale(var(--fa-beat-scale, 1.25)); + transform: scale(var(--fa-beat-scale, 1.25)); } } + +@-webkit-keyframes fa-bounce { + 0% { + -webkit-transform: scale(1, 1) translateY(0); + transform: scale(1, 1) translateY(0); } + 10% { + -webkit-transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0); + transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0); } + 30% { + -webkit-transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em)); + transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em)); } + 50% { + -webkit-transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0); + transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0); } + 57% { + -webkit-transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em)); + transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em)); } + 64% { + -webkit-transform: scale(1, 1) translateY(0); + transform: scale(1, 1) translateY(0); } + 100% { + -webkit-transform: scale(1, 1) translateY(0); + transform: scale(1, 1) translateY(0); } } + +@keyframes fa-bounce { + 0% { + -webkit-transform: scale(1, 1) translateY(0); + transform: scale(1, 1) translateY(0); } + 10% { + -webkit-transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0); + transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0); } + 30% { + -webkit-transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em)); + transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em)); } + 50% { + -webkit-transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0); + transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0); } + 57% { + -webkit-transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em)); + transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em)); } + 64% { + -webkit-transform: scale(1, 1) translateY(0); + transform: scale(1, 1) translateY(0); } + 100% { + -webkit-transform: scale(1, 1) translateY(0); + transform: scale(1, 1) translateY(0); } } + +@-webkit-keyframes fa-fade { + 50% { + opacity: var(--fa-fade-opacity, 0.4); } } + +@keyframes fa-fade { + 50% { + opacity: var(--fa-fade-opacity, 0.4); } } + +@-webkit-keyframes fa-beat-fade { + 0%, 100% { + opacity: var(--fa-beat-fade-opacity, 0.4); + -webkit-transform: scale(1); + transform: scale(1); } + 50% { + opacity: 1; + -webkit-transform: scale(var(--fa-beat-fade-scale, 1.125)); + transform: scale(var(--fa-beat-fade-scale, 1.125)); } } + +@keyframes fa-beat-fade { + 0%, 100% { + opacity: var(--fa-beat-fade-opacity, 0.4); + -webkit-transform: scale(1); + transform: scale(1); } + 50% { + opacity: 1; + -webkit-transform: scale(var(--fa-beat-fade-scale, 1.125)); + transform: scale(var(--fa-beat-fade-scale, 1.125)); } } + +@-webkit-keyframes fa-flip { + 50% { + -webkit-transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg)); + transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg)); } } + +@keyframes fa-flip { + 50% { + -webkit-transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg)); + transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg)); } } + +@-webkit-keyframes fa-shake { + 0% { + -webkit-transform: rotate(-15deg); + transform: rotate(-15deg); } + 4% { + -webkit-transform: rotate(15deg); + transform: rotate(15deg); } + 8%, 24% { + -webkit-transform: rotate(-18deg); + transform: rotate(-18deg); } + 12%, 28% { + -webkit-transform: rotate(18deg); + transform: rotate(18deg); } + 16% { + -webkit-transform: rotate(-22deg); + transform: rotate(-22deg); } + 20% { + -webkit-transform: rotate(22deg); + transform: rotate(22deg); } + 32% { + -webkit-transform: rotate(-12deg); + transform: rotate(-12deg); } + 36% { + -webkit-transform: rotate(12deg); + transform: rotate(12deg); } + 40%, 100% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } } + +@keyframes fa-shake { + 0% { + -webkit-transform: rotate(-15deg); + transform: rotate(-15deg); } + 4% { + -webkit-transform: rotate(15deg); + transform: rotate(15deg); } + 8%, 24% { + -webkit-transform: rotate(-18deg); + transform: rotate(-18deg); } + 12%, 28% { + -webkit-transform: rotate(18deg); + transform: rotate(18deg); } + 16% { + -webkit-transform: rotate(-22deg); + transform: rotate(-22deg); } + 20% { + -webkit-transform: rotate(22deg); + transform: rotate(22deg); } + 32% { + -webkit-transform: rotate(-12deg); + transform: rotate(-12deg); } + 36% { + -webkit-transform: rotate(12deg); + transform: rotate(12deg); } + 40%, 100% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } } + +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +.fa-rotate-90 { + -webkit-transform: rotate(90deg); + transform: rotate(90deg); } + +.fa-rotate-180 { + -webkit-transform: rotate(180deg); + transform: rotate(180deg); } + +.fa-rotate-270 { + -webkit-transform: rotate(270deg); + transform: rotate(270deg); } + +.fa-flip-horizontal { + -webkit-transform: scale(-1, 1); + transform: scale(-1, 1); } + +.fa-flip-vertical { + -webkit-transform: scale(1, -1); + transform: scale(1, -1); } + +.fa-flip-both, +.fa-flip-horizontal.fa-flip-vertical { + -webkit-transform: scale(-1, -1); + transform: scale(-1, -1); } + +.fa-rotate-by { + -webkit-transform: rotate(var(--fa-rotate-angle, 0)); + transform: rotate(var(--fa-rotate-angle, 0)); } + +.fa-stack { + display: inline-block; + height: 2em; + line-height: 2em; + position: relative; + vertical-align: middle; + width: 2.5em; } + +.fa-stack-1x, +.fa-stack-2x { + left: 0; + position: absolute; + text-align: center; + width: 100%; + z-index: var(--fa-stack-z-index, auto); } + +.fa-stack-1x { + line-height: inherit; } + +.fa-stack-2x { + font-size: 2em; } + +.fa-inverse { + color: var(--fa-inverse, #fff); } + +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen +readers do not read off random characters that represent icons */ + +.fa-0::before { + content: "\30"; } + +.fa-1::before { + content: "\31"; } + +.fa-2::before { + content: "\32"; } + +.fa-3::before { + content: "\33"; } + +.fa-4::before { + content: "\34"; } + +.fa-5::before { + content: "\35"; } + +.fa-6::before { + content: "\36"; } + +.fa-7::before { + content: "\37"; } + +.fa-8::before { + content: "\38"; } + +.fa-9::before { + content: "\39"; } + +.fa-fill-drip::before { + content: "\f576"; } + +.fa-arrows-to-circle::before { + content: "\e4bd"; } + +.fa-circle-chevron-right::before { + content: "\f138"; } + +.fa-chevron-circle-right::before { + content: "\f138"; } + +.fa-at::before { + content: "\40"; } + +.fa-trash-can::before { + content: "\f2ed"; } + +.fa-trash-alt::before { + content: "\f2ed"; } + +.fa-text-height::before { + content: "\f034"; } + +.fa-user-xmark::before { + content: "\f235"; } + +.fa-user-times::before { + content: "\f235"; } + +.fa-stethoscope::before { + content: "\f0f1"; } + +.fa-message::before { + content: "\f27a"; } + +.fa-comment-alt::before { + content: "\f27a"; } + +.fa-info::before { + content: "\f129"; } + +.fa-down-left-and-up-right-to-center::before { + content: "\f422"; } + +.fa-compress-alt::before { + content: "\f422"; } + +.fa-explosion::before { + content: "\e4e9"; } + +.fa-file-lines::before { + content: "\f15c"; } + +.fa-file-alt::before { + content: "\f15c"; } + +.fa-file-text::before { + content: "\f15c"; } + +.fa-wave-square::before { + content: "\f83e"; } + +.fa-ring::before { + content: "\f70b"; } + +.fa-building-un::before { + content: "\e4d9"; } + +.fa-dice-three::before { + content: "\f527"; } + +.fa-calendar-days::before { + content: "\f073"; } + +.fa-calendar-alt::before { + content: "\f073"; } + +.fa-anchor-circle-check::before { + content: "\e4aa"; } + +.fa-building-circle-arrow-right::before { + content: "\e4d1"; } + +.fa-volleyball::before { + content: "\f45f"; } + +.fa-volleyball-ball::before { + content: "\f45f"; } + +.fa-arrows-up-to-line::before { + content: "\e4c2"; } + +.fa-sort-down::before { + content: "\f0dd"; } + +.fa-sort-desc::before { + content: "\f0dd"; } + +.fa-circle-minus::before { + content: "\f056"; } + +.fa-minus-circle::before { + content: "\f056"; } + +.fa-door-open::before { + content: "\f52b"; } + +.fa-right-from-bracket::before { + content: "\f2f5"; } + +.fa-sign-out-alt::before { + content: "\f2f5"; } + +.fa-atom::before { + content: "\f5d2"; } + +.fa-soap::before { + content: "\e06e"; } + +.fa-icons::before { + content: "\f86d"; } + +.fa-heart-music-camera-bolt::before { + content: "\f86d"; } + +.fa-microphone-lines-slash::before { + content: "\f539"; } + +.fa-microphone-alt-slash::before { + content: "\f539"; } + +.fa-bridge-circle-check::before { + content: "\e4c9"; } + +.fa-pump-medical::before { + content: "\e06a"; } + +.fa-fingerprint::before { + content: "\f577"; } + +.fa-hand-point-right::before { + content: "\f0a4"; } + +.fa-magnifying-glass-location::before { + content: "\f689"; } + +.fa-search-location::before { + content: "\f689"; } + +.fa-forward-step::before { + content: "\f051"; } + +.fa-step-forward::before { + content: "\f051"; } + +.fa-face-smile-beam::before { + content: "\f5b8"; } + +.fa-smile-beam::before { + content: "\f5b8"; } + +.fa-flag-checkered::before { + content: "\f11e"; } + +.fa-football::before { + content: "\f44e"; } + +.fa-football-ball::before { + content: "\f44e"; } + +.fa-school-circle-exclamation::before { + content: "\e56c"; } + +.fa-crop::before { + content: "\f125"; } + +.fa-angles-down::before { + content: "\f103"; } + +.fa-angle-double-down::before { + content: "\f103"; } + +.fa-users-rectangle::before { + content: "\e594"; } + +.fa-people-roof::before { + content: "\e537"; } + +.fa-people-line::before { + content: "\e534"; } + +.fa-beer-mug-empty::before { + content: "\f0fc"; } + +.fa-beer::before { + content: "\f0fc"; } + +.fa-diagram-predecessor::before { + content: "\e477"; } + +.fa-arrow-up-long::before { + content: "\f176"; } + +.fa-long-arrow-up::before { + content: "\f176"; } + +.fa-fire-flame-simple::before { + content: "\f46a"; } + +.fa-burn::before { + content: "\f46a"; } + +.fa-person::before { + content: "\f183"; } + +.fa-male::before { + content: "\f183"; } + +.fa-laptop::before { + content: "\f109"; } + +.fa-file-csv::before { + content: "\f6dd"; } + +.fa-menorah::before { + content: "\f676"; } + +.fa-truck-plane::before { + content: "\e58f"; } + +.fa-record-vinyl::before { + content: "\f8d9"; } + +.fa-face-grin-stars::before { + content: "\f587"; } + +.fa-grin-stars::before { + content: "\f587"; } + +.fa-bong::before { + content: "\f55c"; } + +.fa-spaghetti-monster-flying::before { + content: "\f67b"; } + +.fa-pastafarianism::before { + content: "\f67b"; } + +.fa-arrow-down-up-across-line::before { + content: "\e4af"; } + +.fa-spoon::before { + content: "\f2e5"; } + +.fa-utensil-spoon::before { + content: "\f2e5"; } + +.fa-jar-wheat::before { + content: "\e517"; } + +.fa-envelopes-bulk::before { + content: "\f674"; } + +.fa-mail-bulk::before { + content: "\f674"; } + +.fa-file-circle-exclamation::before { + content: "\e4eb"; } + +.fa-circle-h::before { + content: "\f47e"; } + +.fa-hospital-symbol::before { + content: "\f47e"; } + +.fa-pager::before { + content: "\f815"; } + +.fa-address-book::before { + content: "\f2b9"; } + +.fa-contact-book::before { + content: "\f2b9"; } + +.fa-strikethrough::before { + content: "\f0cc"; } + +.fa-k::before { + content: "\4b"; } + +.fa-landmark-flag::before { + content: "\e51c"; } + +.fa-pencil::before { + content: "\f303"; } + +.fa-pencil-alt::before { + content: "\f303"; } + +.fa-backward::before { + content: "\f04a"; } + +.fa-caret-right::before { + content: "\f0da"; } + +.fa-comments::before { + content: "\f086"; } + +.fa-paste::before { + content: "\f0ea"; } + +.fa-file-clipboard::before { + content: "\f0ea"; } + +.fa-code-pull-request::before { + content: "\e13c"; } + +.fa-clipboard-list::before { + content: "\f46d"; } + +.fa-truck-ramp-box::before { + content: "\f4de"; } + +.fa-truck-loading::before { + content: "\f4de"; } + +.fa-user-check::before { + content: "\f4fc"; } + +.fa-vial-virus::before { + content: "\e597"; } + +.fa-sheet-plastic::before { + content: "\e571"; } + +.fa-blog::before { + content: "\f781"; } + +.fa-user-ninja::before { + content: "\f504"; } + +.fa-person-arrow-up-from-line::before { + content: "\e539"; } + +.fa-scroll-torah::before { + content: "\f6a0"; } + +.fa-torah::before { + content: "\f6a0"; } + +.fa-broom-ball::before { + content: "\f458"; } + +.fa-quidditch::before { + content: "\f458"; } + +.fa-quidditch-broom-ball::before { + content: "\f458"; } + +.fa-toggle-off::before { + content: "\f204"; } + +.fa-box-archive::before { + content: "\f187"; } + +.fa-archive::before { + content: "\f187"; } + +.fa-person-drowning::before { + content: "\e545"; } + +.fa-arrow-down-9-1::before { + content: "\f886"; } + +.fa-sort-numeric-desc::before { + content: "\f886"; } + +.fa-sort-numeric-down-alt::before { + content: "\f886"; } + +.fa-face-grin-tongue-squint::before { + content: "\f58a"; } + +.fa-grin-tongue-squint::before { + content: "\f58a"; } + +.fa-spray-can::before { + content: "\f5bd"; } + +.fa-truck-monster::before { + content: "\f63b"; } + +.fa-w::before { + content: "\57"; } + +.fa-earth-africa::before { + content: "\f57c"; } + +.fa-globe-africa::before { + content: "\f57c"; } + +.fa-rainbow::before { + content: "\f75b"; } + +.fa-circle-notch::before { + content: "\f1ce"; } + +.fa-tablet-screen-button::before { + content: "\f3fa"; } + +.fa-tablet-alt::before { + content: "\f3fa"; } + +.fa-paw::before { + content: "\f1b0"; } + +.fa-cloud::before { + content: "\f0c2"; } + +.fa-trowel-bricks::before { + content: "\e58a"; } + +.fa-face-flushed::before { + content: "\f579"; } + +.fa-flushed::before { + content: "\f579"; } + +.fa-hospital-user::before { + content: "\f80d"; } + +.fa-tent-arrow-left-right::before { + content: "\e57f"; } + +.fa-gavel::before { + content: "\f0e3"; } + +.fa-legal::before { + content: "\f0e3"; } + +.fa-binoculars::before { + content: "\f1e5"; } + +.fa-microphone-slash::before { + content: "\f131"; } + +.fa-box-tissue::before { + content: "\e05b"; } + +.fa-motorcycle::before { + content: "\f21c"; } + +.fa-bell-concierge::before { + content: "\f562"; } + +.fa-concierge-bell::before { + content: "\f562"; } + +.fa-pen-ruler::before { + content: "\f5ae"; } + +.fa-pencil-ruler::before { + content: "\f5ae"; } + +.fa-people-arrows::before { + content: "\e068"; } + +.fa-people-arrows-left-right::before { + content: "\e068"; } + +.fa-mars-and-venus-burst::before { + content: "\e523"; } + +.fa-square-caret-right::before { + content: "\f152"; } + +.fa-caret-square-right::before { + content: "\f152"; } + +.fa-scissors::before { + content: "\f0c4"; } + +.fa-cut::before { + content: "\f0c4"; } + +.fa-sun-plant-wilt::before { + content: "\e57a"; } + +.fa-toilets-portable::before { + content: "\e584"; } + +.fa-hockey-puck::before { + content: "\f453"; } + +.fa-table::before { + content: "\f0ce"; } + +.fa-magnifying-glass-arrow-right::before { + content: "\e521"; } + +.fa-tachograph-digital::before { + content: "\f566"; } + +.fa-digital-tachograph::before { + content: "\f566"; } + +.fa-users-slash::before { + content: "\e073"; } + +.fa-clover::before { + content: "\e139"; } + +.fa-reply::before { + content: "\f3e5"; } + +.fa-mail-reply::before { + content: "\f3e5"; } + +.fa-star-and-crescent::before { + content: "\f699"; } + +.fa-house-fire::before { + content: "\e50c"; } + +.fa-square-minus::before { + content: "\f146"; } + +.fa-minus-square::before { + content: "\f146"; } + +.fa-helicopter::before { + content: "\f533"; } + +.fa-compass::before { + content: "\f14e"; } + +.fa-square-caret-down::before { + content: "\f150"; } + +.fa-caret-square-down::before { + content: "\f150"; } + +.fa-file-circle-question::before { + content: "\e4ef"; } + +.fa-laptop-code::before { + content: "\f5fc"; } + +.fa-swatchbook::before { + content: "\f5c3"; } + +.fa-prescription-bottle::before { + content: "\f485"; } + +.fa-bars::before { + content: "\f0c9"; } + +.fa-navicon::before { + content: "\f0c9"; } + +.fa-people-group::before { + content: "\e533"; } + +.fa-hourglass-end::before { + content: "\f253"; } + +.fa-hourglass-3::before { + content: "\f253"; } + +.fa-heart-crack::before { + content: "\f7a9"; } + +.fa-heart-broken::before { + content: "\f7a9"; } + +.fa-square-up-right::before { + content: "\f360"; } + +.fa-external-link-square-alt::before { + content: "\f360"; } + +.fa-face-kiss-beam::before { + content: "\f597"; } + +.fa-kiss-beam::before { + content: "\f597"; } + +.fa-film::before { + content: "\f008"; } + +.fa-ruler-horizontal::before { + content: "\f547"; } + +.fa-people-robbery::before { + content: "\e536"; } + +.fa-lightbulb::before { + content: "\f0eb"; } + +.fa-caret-left::before { + content: "\f0d9"; } + +.fa-circle-exclamation::before { + content: "\f06a"; } + +.fa-exclamation-circle::before { + content: "\f06a"; } + +.fa-school-circle-xmark::before { + content: "\e56d"; } + +.fa-arrow-right-from-bracket::before { + content: "\f08b"; } + +.fa-sign-out::before { + content: "\f08b"; } + +.fa-circle-chevron-down::before { + content: "\f13a"; } + +.fa-chevron-circle-down::before { + content: "\f13a"; } + +.fa-unlock-keyhole::before { + content: "\f13e"; } + +.fa-unlock-alt::before { + content: "\f13e"; } + +.fa-cloud-showers-heavy::before { + content: "\f740"; } + +.fa-headphones-simple::before { + content: "\f58f"; } + +.fa-headphones-alt::before { + content: "\f58f"; } + +.fa-sitemap::before { + content: "\f0e8"; } + +.fa-circle-dollar-to-slot::before { + content: "\f4b9"; } + +.fa-donate::before { + content: "\f4b9"; } + +.fa-memory::before { + content: "\f538"; } + +.fa-road-spikes::before { + content: "\e568"; } + +.fa-fire-burner::before { + content: "\e4f1"; } + +.fa-flag::before { + content: "\f024"; } + +.fa-hanukiah::before { + content: "\f6e6"; } + +.fa-feather::before { + content: "\f52d"; } + +.fa-volume-low::before { + content: "\f027"; } + +.fa-volume-down::before { + content: "\f027"; } + +.fa-comment-slash::before { + content: "\f4b3"; } + +.fa-cloud-sun-rain::before { + content: "\f743"; } + +.fa-compress::before { + content: "\f066"; } + +.fa-wheat-awn::before { + content: "\e2cd"; } + +.fa-wheat-alt::before { + content: "\e2cd"; } + +.fa-ankh::before { + content: "\f644"; } + +.fa-hands-holding-child::before { + content: "\e4fa"; } + +.fa-asterisk::before { + content: "\2a"; } + +.fa-square-check::before { + content: "\f14a"; } + +.fa-check-square::before { + content: "\f14a"; } + +.fa-peseta-sign::before { + content: "\e221"; } + +.fa-heading::before { + content: "\f1dc"; } + +.fa-header::before { + content: "\f1dc"; } + +.fa-ghost::before { + content: "\f6e2"; } + +.fa-list::before { + content: "\f03a"; } + +.fa-list-squares::before { + content: "\f03a"; } + +.fa-square-phone-flip::before { + content: "\f87b"; } + +.fa-phone-square-alt::before { + content: "\f87b"; } + +.fa-cart-plus::before { + content: "\f217"; } + +.fa-gamepad::before { + content: "\f11b"; } + +.fa-circle-dot::before { + content: "\f192"; } + +.fa-dot-circle::before { + content: "\f192"; } + +.fa-face-dizzy::before { + content: "\f567"; } + +.fa-dizzy::before { + content: "\f567"; } + +.fa-egg::before { + content: "\f7fb"; } + +.fa-house-medical-circle-xmark::before { + content: "\e513"; } + +.fa-campground::before { + content: "\f6bb"; } + +.fa-folder-plus::before { + content: "\f65e"; } + +.fa-futbol::before { + content: "\f1e3"; } + +.fa-futbol-ball::before { + content: "\f1e3"; } + +.fa-soccer-ball::before { + content: "\f1e3"; } + +.fa-paintbrush::before { + content: "\f1fc"; } + +.fa-paint-brush::before { + content: "\f1fc"; } + +.fa-lock::before { + content: "\f023"; } + +.fa-gas-pump::before { + content: "\f52f"; } + +.fa-hot-tub-person::before { + content: "\f593"; } + +.fa-hot-tub::before { + content: "\f593"; } + +.fa-map-location::before { + content: "\f59f"; } + +.fa-map-marked::before { + content: "\f59f"; } + +.fa-house-flood-water::before { + content: "\e50e"; } + +.fa-tree::before { + content: "\f1bb"; } + +.fa-bridge-lock::before { + content: "\e4cc"; } + +.fa-sack-dollar::before { + content: "\f81d"; } + +.fa-pen-to-square::before { + content: "\f044"; } + +.fa-edit::before { + content: "\f044"; } + +.fa-car-side::before { + content: "\f5e4"; } + +.fa-share-nodes::before { + content: "\f1e0"; } + +.fa-share-alt::before { + content: "\f1e0"; } + +.fa-heart-circle-minus::before { + content: "\e4ff"; } + +.fa-hourglass-half::before { + content: "\f252"; } + +.fa-hourglass-2::before { + content: "\f252"; } + +.fa-microscope::before { + content: "\f610"; } + +.fa-sink::before { + content: "\e06d"; } + +.fa-bag-shopping::before { + content: "\f290"; } + +.fa-shopping-bag::before { + content: "\f290"; } + +.fa-arrow-down-z-a::before { + content: "\f881"; } + +.fa-sort-alpha-desc::before { + content: "\f881"; } + +.fa-sort-alpha-down-alt::before { + content: "\f881"; } + +.fa-mitten::before { + content: "\f7b5"; } + +.fa-person-rays::before { + content: "\e54d"; } + +.fa-users::before { + content: "\f0c0"; } + +.fa-eye-slash::before { + content: "\f070"; } + +.fa-flask-vial::before { + content: "\e4f3"; } + +.fa-hand::before { + content: "\f256"; } + +.fa-hand-paper::before { + content: "\f256"; } + +.fa-om::before { + content: "\f679"; } + +.fa-worm::before { + content: "\e599"; } + +.fa-house-circle-xmark::before { + content: "\e50b"; } + +.fa-plug::before { + content: "\f1e6"; } + +.fa-chevron-up::before { + content: "\f077"; } + +.fa-hand-spock::before { + content: "\f259"; } + +.fa-stopwatch::before { + content: "\f2f2"; } + +.fa-face-kiss::before { + content: "\f596"; } + +.fa-kiss::before { + content: "\f596"; } + +.fa-bridge-circle-xmark::before { + content: "\e4cb"; } + +.fa-face-grin-tongue::before { + content: "\f589"; } + +.fa-grin-tongue::before { + content: "\f589"; } + +.fa-chess-bishop::before { + content: "\f43a"; } + +.fa-face-grin-wink::before { + content: "\f58c"; } + +.fa-grin-wink::before { + content: "\f58c"; } + +.fa-ear-deaf::before { + content: "\f2a4"; } + +.fa-deaf::before { + content: "\f2a4"; } + +.fa-deafness::before { + content: "\f2a4"; } + +.fa-hard-of-hearing::before { + content: "\f2a4"; } + +.fa-road-circle-check::before { + content: "\e564"; } + +.fa-dice-five::before { + content: "\f523"; } + +.fa-square-rss::before { + content: "\f143"; } + +.fa-rss-square::before { + content: "\f143"; } + +.fa-land-mine-on::before { + content: "\e51b"; } + +.fa-i-cursor::before { + content: "\f246"; } + +.fa-stamp::before { + content: "\f5bf"; } + +.fa-stairs::before { + content: "\e289"; } + +.fa-i::before { + content: "\49"; } + +.fa-hryvnia-sign::before { + content: "\f6f2"; } + +.fa-hryvnia::before { + content: "\f6f2"; } + +.fa-pills::before { + content: "\f484"; } + +.fa-face-grin-wide::before { + content: "\f581"; } + +.fa-grin-alt::before { + content: "\f581"; } + +.fa-tooth::before { + content: "\f5c9"; } + +.fa-v::before { + content: "\56"; } + +.fa-bangladeshi-taka-sign::before { + content: "\e2e6"; } + +.fa-bicycle::before { + content: "\f206"; } + +.fa-staff-snake::before { + content: "\e579"; } + +.fa-rod-asclepius::before { + content: "\e579"; } + +.fa-rod-snake::before { + content: "\e579"; } + +.fa-staff-aesculapius::before { + content: "\e579"; } + +.fa-head-side-cough-slash::before { + content: "\e062"; } + +.fa-truck-medical::before { + content: "\f0f9"; } + +.fa-ambulance::before { + content: "\f0f9"; } + +.fa-wheat-awn-circle-exclamation::before { + content: "\e598"; } + +.fa-snowman::before { + content: "\f7d0"; } + +.fa-mortar-pestle::before { + content: "\f5a7"; } + +.fa-road-barrier::before { + content: "\e562"; } + +.fa-school::before { + content: "\f549"; } + +.fa-igloo::before { + content: "\f7ae"; } + +.fa-joint::before { + content: "\f595"; } + +.fa-angle-right::before { + content: "\f105"; } + +.fa-horse::before { + content: "\f6f0"; } + +.fa-q::before { + content: "\51"; } + +.fa-g::before { + content: "\47"; } + +.fa-notes-medical::before { + content: "\f481"; } + +.fa-temperature-half::before { + content: "\f2c9"; } + +.fa-temperature-2::before { + content: "\f2c9"; } + +.fa-thermometer-2::before { + content: "\f2c9"; } + +.fa-thermometer-half::before { + content: "\f2c9"; } + +.fa-dong-sign::before { + content: "\e169"; } + +.fa-capsules::before { + content: "\f46b"; } + +.fa-poo-storm::before { + content: "\f75a"; } + +.fa-poo-bolt::before { + content: "\f75a"; } + +.fa-face-frown-open::before { + content: "\f57a"; } + +.fa-frown-open::before { + content: "\f57a"; } + +.fa-hand-point-up::before { + content: "\f0a6"; } + +.fa-money-bill::before { + content: "\f0d6"; } + +.fa-bookmark::before { + content: "\f02e"; } + +.fa-align-justify::before { + content: "\f039"; } + +.fa-umbrella-beach::before { + content: "\f5ca"; } + +.fa-helmet-un::before { + content: "\e503"; } + +.fa-bullseye::before { + content: "\f140"; } + +.fa-bacon::before { + content: "\f7e5"; } + +.fa-hand-point-down::before { + content: "\f0a7"; } + +.fa-arrow-up-from-bracket::before { + content: "\e09a"; } + +.fa-folder::before { + content: "\f07b"; } + +.fa-folder-blank::before { + content: "\f07b"; } + +.fa-file-waveform::before { + content: "\f478"; } + +.fa-file-medical-alt::before { + content: "\f478"; } + +.fa-radiation::before { + content: "\f7b9"; } + +.fa-chart-simple::before { + content: "\e473"; } + +.fa-mars-stroke::before { + content: "\f229"; } + +.fa-vial::before { + content: "\f492"; } + +.fa-gauge::before { + content: "\f624"; } + +.fa-dashboard::before { + content: "\f624"; } + +.fa-gauge-med::before { + content: "\f624"; } + +.fa-tachometer-alt-average::before { + content: "\f624"; } + +.fa-wand-magic-sparkles::before { + content: "\e2ca"; } + +.fa-magic-wand-sparkles::before { + content: "\e2ca"; } + +.fa-e::before { + content: "\45"; } + +.fa-pen-clip::before { + content: "\f305"; } + +.fa-pen-alt::before { + content: "\f305"; } + +.fa-bridge-circle-exclamation::before { + content: "\e4ca"; } + +.fa-user::before { + content: "\f007"; } + +.fa-school-circle-check::before { + content: "\e56b"; } + +.fa-dumpster::before { + content: "\f793"; } + +.fa-van-shuttle::before { + content: "\f5b6"; } + +.fa-shuttle-van::before { + content: "\f5b6"; } + +.fa-building-user::before { + content: "\e4da"; } + +.fa-square-caret-left::before { + content: "\f191"; } + +.fa-caret-square-left::before { + content: "\f191"; } + +.fa-highlighter::before { + content: "\f591"; } + +.fa-key::before { + content: "\f084"; } + +.fa-bullhorn::before { + content: "\f0a1"; } + +.fa-globe::before { + content: "\f0ac"; } + +.fa-synagogue::before { + content: "\f69b"; } + +.fa-person-half-dress::before { + content: "\e548"; } + +.fa-road-bridge::before { + content: "\e563"; } + +.fa-location-arrow::before { + content: "\f124"; } + +.fa-c::before { + content: "\43"; } + +.fa-tablet-button::before { + content: "\f10a"; } + +.fa-building-lock::before { + content: "\e4d6"; } + +.fa-pizza-slice::before { + content: "\f818"; } + +.fa-money-bill-wave::before { + content: "\f53a"; } + +.fa-chart-area::before { + content: "\f1fe"; } + +.fa-area-chart::before { + content: "\f1fe"; } + +.fa-house-flag::before { + content: "\e50d"; } + +.fa-person-circle-minus::before { + content: "\e540"; } + +.fa-ban::before { + content: "\f05e"; } + +.fa-cancel::before { + content: "\f05e"; } + +.fa-camera-rotate::before { + content: "\e0d8"; } + +.fa-spray-can-sparkles::before { + content: "\f5d0"; } + +.fa-air-freshener::before { + content: "\f5d0"; } + +.fa-star::before { + content: "\f005"; } + +.fa-repeat::before { + content: "\f363"; } + +.fa-cross::before { + content: "\f654"; } + +.fa-box::before { + content: "\f466"; } + +.fa-venus-mars::before { + content: "\f228"; } + +.fa-arrow-pointer::before { + content: "\f245"; } + +.fa-mouse-pointer::before { + content: "\f245"; } + +.fa-maximize::before { + content: "\f31e"; } + +.fa-expand-arrows-alt::before { + content: "\f31e"; } + +.fa-charging-station::before { + content: "\f5e7"; } + +.fa-shapes::before { + content: "\f61f"; } + +.fa-triangle-circle-square::before { + content: "\f61f"; } + +.fa-shuffle::before { + content: "\f074"; } + +.fa-random::before { + content: "\f074"; } + +.fa-person-running::before { + content: "\f70c"; } + +.fa-running::before { + content: "\f70c"; } + +.fa-mobile-retro::before { + content: "\e527"; } + +.fa-grip-lines-vertical::before { + content: "\f7a5"; } + +.fa-spider::before { + content: "\f717"; } + +.fa-hands-bound::before { + content: "\e4f9"; } + +.fa-file-invoice-dollar::before { + content: "\f571"; } + +.fa-plane-circle-exclamation::before { + content: "\e556"; } + +.fa-x-ray::before { + content: "\f497"; } + +.fa-spell-check::before { + content: "\f891"; } + +.fa-slash::before { + content: "\f715"; } + +.fa-computer-mouse::before { + content: "\f8cc"; } + +.fa-mouse::before { + content: "\f8cc"; } + +.fa-arrow-right-to-bracket::before { + content: "\f090"; } + +.fa-sign-in::before { + content: "\f090"; } + +.fa-shop-slash::before { + content: "\e070"; } + +.fa-store-alt-slash::before { + content: "\e070"; } + +.fa-server::before { + content: "\f233"; } + +.fa-virus-covid-slash::before { + content: "\e4a9"; } + +.fa-shop-lock::before { + content: "\e4a5"; } + +.fa-hourglass-start::before { + content: "\f251"; } + +.fa-hourglass-1::before { + content: "\f251"; } + +.fa-blender-phone::before { + content: "\f6b6"; } + +.fa-building-wheat::before { + content: "\e4db"; } + +.fa-person-breastfeeding::before { + content: "\e53a"; } + +.fa-right-to-bracket::before { + content: "\f2f6"; } + +.fa-sign-in-alt::before { + content: "\f2f6"; } + +.fa-venus::before { + content: "\f221"; } + +.fa-passport::before { + content: "\f5ab"; } + +.fa-heart-pulse::before { + content: "\f21e"; } + +.fa-heartbeat::before { + content: "\f21e"; } + +.fa-people-carry-box::before { + content: "\f4ce"; } + +.fa-people-carry::before { + content: "\f4ce"; } + +.fa-temperature-high::before { + content: "\f769"; } + +.fa-microchip::before { + content: "\f2db"; } + +.fa-crown::before { + content: "\f521"; } + +.fa-weight-hanging::before { + content: "\f5cd"; } + +.fa-xmarks-lines::before { + content: "\e59a"; } + +.fa-file-prescription::before { + content: "\f572"; } + +.fa-weight-scale::before { + content: "\f496"; } + +.fa-weight::before { + content: "\f496"; } + +.fa-user-group::before { + content: "\f500"; } + +.fa-user-friends::before { + content: "\f500"; } + +.fa-arrow-up-a-z::before { + content: "\f15e"; } + +.fa-sort-alpha-up::before { + content: "\f15e"; } + +.fa-chess-knight::before { + content: "\f441"; } + +.fa-face-laugh-squint::before { + content: "\f59b"; } + +.fa-laugh-squint::before { + content: "\f59b"; } + +.fa-wheelchair::before { + content: "\f193"; } + +.fa-circle-arrow-up::before { + content: "\f0aa"; } + +.fa-arrow-circle-up::before { + content: "\f0aa"; } + +.fa-toggle-on::before { + content: "\f205"; } + +.fa-person-walking::before { + content: "\f554"; } + +.fa-walking::before { + content: "\f554"; } + +.fa-l::before { + content: "\4c"; } + +.fa-fire::before { + content: "\f06d"; } + +.fa-bed-pulse::before { + content: "\f487"; } + +.fa-procedures::before { + content: "\f487"; } + +.fa-shuttle-space::before { + content: "\f197"; } + +.fa-space-shuttle::before { + content: "\f197"; } + +.fa-face-laugh::before { + content: "\f599"; } + +.fa-laugh::before { + content: "\f599"; } + +.fa-folder-open::before { + content: "\f07c"; } + +.fa-heart-circle-plus::before { + content: "\e500"; } + +.fa-code-fork::before { + content: "\e13b"; } + +.fa-city::before { + content: "\f64f"; } + +.fa-microphone-lines::before { + content: "\f3c9"; } + +.fa-microphone-alt::before { + content: "\f3c9"; } + +.fa-pepper-hot::before { + content: "\f816"; } + +.fa-unlock::before { + content: "\f09c"; } + +.fa-colon-sign::before { + content: "\e140"; } + +.fa-headset::before { + content: "\f590"; } + +.fa-store-slash::before { + content: "\e071"; } + +.fa-road-circle-xmark::before { + content: "\e566"; } + +.fa-user-minus::before { + content: "\f503"; } + +.fa-mars-stroke-up::before { + content: "\f22a"; } + +.fa-mars-stroke-v::before { + content: "\f22a"; } + +.fa-champagne-glasses::before { + content: "\f79f"; } + +.fa-glass-cheers::before { + content: "\f79f"; } + +.fa-clipboard::before { + content: "\f328"; } + +.fa-house-circle-exclamation::before { + content: "\e50a"; } + +.fa-file-arrow-up::before { + content: "\f574"; } + +.fa-file-upload::before { + content: "\f574"; } + +.fa-wifi::before { + content: "\f1eb"; } + +.fa-wifi-3::before { + content: "\f1eb"; } + +.fa-wifi-strong::before { + content: "\f1eb"; } + +.fa-bath::before { + content: "\f2cd"; } + +.fa-bathtub::before { + content: "\f2cd"; } + +.fa-underline::before { + content: "\f0cd"; } + +.fa-user-pen::before { + content: "\f4ff"; } + +.fa-user-edit::before { + content: "\f4ff"; } + +.fa-signature::before { + content: "\f5b7"; } + +.fa-stroopwafel::before { + content: "\f551"; } + +.fa-bold::before { + content: "\f032"; } + +.fa-anchor-lock::before { + content: "\e4ad"; } + +.fa-building-ngo::before { + content: "\e4d7"; } + +.fa-manat-sign::before { + content: "\e1d5"; } + +.fa-not-equal::before { + content: "\f53e"; } + +.fa-border-top-left::before { + content: "\f853"; } + +.fa-border-style::before { + content: "\f853"; } + +.fa-map-location-dot::before { + content: "\f5a0"; } + +.fa-map-marked-alt::before { + content: "\f5a0"; } + +.fa-jedi::before { + content: "\f669"; } + +.fa-square-poll-vertical::before { + content: "\f681"; } + +.fa-poll::before { + content: "\f681"; } + +.fa-mug-hot::before { + content: "\f7b6"; } + +.fa-car-battery::before { + content: "\f5df"; } + +.fa-battery-car::before { + content: "\f5df"; } + +.fa-gift::before { + content: "\f06b"; } + +.fa-dice-two::before { + content: "\f528"; } + +.fa-chess-queen::before { + content: "\f445"; } + +.fa-glasses::before { + content: "\f530"; } + +.fa-chess-board::before { + content: "\f43c"; } + +.fa-building-circle-check::before { + content: "\e4d2"; } + +.fa-person-chalkboard::before { + content: "\e53d"; } + +.fa-mars-stroke-right::before { + content: "\f22b"; } + +.fa-mars-stroke-h::before { + content: "\f22b"; } + +.fa-hand-back-fist::before { + content: "\f255"; } + +.fa-hand-rock::before { + content: "\f255"; } + +.fa-square-caret-up::before { + content: "\f151"; } + +.fa-caret-square-up::before { + content: "\f151"; } + +.fa-cloud-showers-water::before { + content: "\e4e4"; } + +.fa-chart-bar::before { + content: "\f080"; } + +.fa-bar-chart::before { + content: "\f080"; } + +.fa-hands-bubbles::before { + content: "\e05e"; } + +.fa-hands-wash::before { + content: "\e05e"; } + +.fa-less-than-equal::before { + content: "\f537"; } + +.fa-train::before { + content: "\f238"; } + +.fa-eye-low-vision::before { + content: "\f2a8"; } + +.fa-low-vision::before { + content: "\f2a8"; } + +.fa-crow::before { + content: "\f520"; } + +.fa-sailboat::before { + content: "\e445"; } + +.fa-window-restore::before { + content: "\f2d2"; } + +.fa-square-plus::before { + content: "\f0fe"; } + +.fa-plus-square::before { + content: "\f0fe"; } + +.fa-torii-gate::before { + content: "\f6a1"; } + +.fa-frog::before { + content: "\f52e"; } + +.fa-bucket::before { + content: "\e4cf"; } + +.fa-image::before { + content: "\f03e"; } + +.fa-microphone::before { + content: "\f130"; } + +.fa-cow::before { + content: "\f6c8"; } + +.fa-caret-up::before { + content: "\f0d8"; } + +.fa-screwdriver::before { + content: "\f54a"; } + +.fa-folder-closed::before { + content: "\e185"; } + +.fa-house-tsunami::before { + content: "\e515"; } + +.fa-square-nfi::before { + content: "\e576"; } + +.fa-arrow-up-from-ground-water::before { + content: "\e4b5"; } + +.fa-martini-glass::before { + content: "\f57b"; } + +.fa-glass-martini-alt::before { + content: "\f57b"; } + +.fa-rotate-left::before { + content: "\f2ea"; } + +.fa-rotate-back::before { + content: "\f2ea"; } + +.fa-rotate-backward::before { + content: "\f2ea"; } + +.fa-undo-alt::before { + content: "\f2ea"; } + +.fa-table-columns::before { + content: "\f0db"; } + +.fa-columns::before { + content: "\f0db"; } + +.fa-lemon::before { + content: "\f094"; } + +.fa-head-side-mask::before { + content: "\e063"; } + +.fa-handshake::before { + content: "\f2b5"; } + +.fa-gem::before { + content: "\f3a5"; } + +.fa-dolly::before { + content: "\f472"; } + +.fa-dolly-box::before { + content: "\f472"; } + +.fa-smoking::before { + content: "\f48d"; } + +.fa-minimize::before { + content: "\f78c"; } + +.fa-compress-arrows-alt::before { + content: "\f78c"; } + +.fa-monument::before { + content: "\f5a6"; } + +.fa-snowplow::before { + content: "\f7d2"; } + +.fa-angles-right::before { + content: "\f101"; } + +.fa-angle-double-right::before { + content: "\f101"; } + +.fa-cannabis::before { + content: "\f55f"; } + +.fa-circle-play::before { + content: "\f144"; } + +.fa-play-circle::before { + content: "\f144"; } + +.fa-tablets::before { + content: "\f490"; } + +.fa-ethernet::before { + content: "\f796"; } + +.fa-euro-sign::before { + content: "\f153"; } + +.fa-eur::before { + content: "\f153"; } + +.fa-euro::before { + content: "\f153"; } + +.fa-chair::before { + content: "\f6c0"; } + +.fa-circle-check::before { + content: "\f058"; } + +.fa-check-circle::before { + content: "\f058"; } + +.fa-circle-stop::before { + content: "\f28d"; } + +.fa-stop-circle::before { + content: "\f28d"; } + +.fa-compass-drafting::before { + content: "\f568"; } + +.fa-drafting-compass::before { + content: "\f568"; } + +.fa-plate-wheat::before { + content: "\e55a"; } + +.fa-icicles::before { + content: "\f7ad"; } + +.fa-person-shelter::before { + content: "\e54f"; } + +.fa-neuter::before { + content: "\f22c"; } + +.fa-id-badge::before { + content: "\f2c1"; } + +.fa-marker::before { + content: "\f5a1"; } + +.fa-face-laugh-beam::before { + content: "\f59a"; } + +.fa-laugh-beam::before { + content: "\f59a"; } + +.fa-helicopter-symbol::before { + content: "\e502"; } + +.fa-universal-access::before { + content: "\f29a"; } + +.fa-circle-chevron-up::before { + content: "\f139"; } + +.fa-chevron-circle-up::before { + content: "\f139"; } + +.fa-lari-sign::before { + content: "\e1c8"; } + +.fa-volcano::before { + content: "\f770"; } + +.fa-person-walking-dashed-line-arrow-right::before { + content: "\e553"; } + +.fa-sterling-sign::before { + content: "\f154"; } + +.fa-gbp::before { + content: "\f154"; } + +.fa-pound-sign::before { + content: "\f154"; } + +.fa-viruses::before { + content: "\e076"; } + +.fa-square-person-confined::before { + content: "\e577"; } + +.fa-user-tie::before { + content: "\f508"; } + +.fa-arrow-down-long::before { + content: "\f175"; } + +.fa-long-arrow-down::before { + content: "\f175"; } + +.fa-tent-arrow-down-to-line::before { + content: "\e57e"; } + +.fa-certificate::before { + content: "\f0a3"; } + +.fa-reply-all::before { + content: "\f122"; } + +.fa-mail-reply-all::before { + content: "\f122"; } + +.fa-suitcase::before { + content: "\f0f2"; } + +.fa-person-skating::before { + content: "\f7c5"; } + +.fa-skating::before { + content: "\f7c5"; } + +.fa-filter-circle-dollar::before { + content: "\f662"; } + +.fa-funnel-dollar::before { + content: "\f662"; } + +.fa-camera-retro::before { + content: "\f083"; } + +.fa-circle-arrow-down::before { + content: "\f0ab"; } + +.fa-arrow-circle-down::before { + content: "\f0ab"; } + +.fa-file-import::before { + content: "\f56f"; } + +.fa-arrow-right-to-file::before { + content: "\f56f"; } + +.fa-square-arrow-up-right::before { + content: "\f14c"; } + +.fa-external-link-square::before { + content: "\f14c"; } + +.fa-box-open::before { + content: "\f49e"; } + +.fa-scroll::before { + content: "\f70e"; } + +.fa-spa::before { + content: "\f5bb"; } + +.fa-location-pin-lock::before { + content: "\e51f"; } + +.fa-pause::before { + content: "\f04c"; } + +.fa-hill-avalanche::before { + content: "\e507"; } + +.fa-temperature-empty::before { + content: "\f2cb"; } + +.fa-temperature-0::before { + content: "\f2cb"; } + +.fa-thermometer-0::before { + content: "\f2cb"; } + +.fa-thermometer-empty::before { + content: "\f2cb"; } + +.fa-bomb::before { + content: "\f1e2"; } + +.fa-registered::before { + content: "\f25d"; } + +.fa-address-card::before { + content: "\f2bb"; } + +.fa-contact-card::before { + content: "\f2bb"; } + +.fa-vcard::before { + content: "\f2bb"; } + +.fa-scale-unbalanced-flip::before { + content: "\f516"; } + +.fa-balance-scale-right::before { + content: "\f516"; } + +.fa-subscript::before { + content: "\f12c"; } + +.fa-diamond-turn-right::before { + content: "\f5eb"; } + +.fa-directions::before { + content: "\f5eb"; } + +.fa-burst::before { + content: "\e4dc"; } + +.fa-house-laptop::before { + content: "\e066"; } + +.fa-laptop-house::before { + content: "\e066"; } + +.fa-face-tired::before { + content: "\f5c8"; } + +.fa-tired::before { + content: "\f5c8"; } + +.fa-money-bills::before { + content: "\e1f3"; } + +.fa-smog::before { + content: "\f75f"; } + +.fa-crutch::before { + content: "\f7f7"; } + +.fa-cloud-arrow-up::before { + content: "\f0ee"; } + +.fa-cloud-upload::before { + content: "\f0ee"; } + +.fa-cloud-upload-alt::before { + content: "\f0ee"; } + +.fa-palette::before { + content: "\f53f"; } + +.fa-arrows-turn-right::before { + content: "\e4c0"; } + +.fa-vest::before { + content: "\e085"; } + +.fa-ferry::before { + content: "\e4ea"; } + +.fa-arrows-down-to-people::before { + content: "\e4b9"; } + +.fa-seedling::before { + content: "\f4d8"; } + +.fa-sprout::before { + content: "\f4d8"; } + +.fa-left-right::before { + content: "\f337"; } + +.fa-arrows-alt-h::before { + content: "\f337"; } + +.fa-boxes-packing::before { + content: "\e4c7"; } + +.fa-circle-arrow-left::before { + content: "\f0a8"; } + +.fa-arrow-circle-left::before { + content: "\f0a8"; } + +.fa-group-arrows-rotate::before { + content: "\e4f6"; } + +.fa-bowl-food::before { + content: "\e4c6"; } + +.fa-candy-cane::before { + content: "\f786"; } + +.fa-arrow-down-wide-short::before { + content: "\f160"; } + +.fa-sort-amount-asc::before { + content: "\f160"; } + +.fa-sort-amount-down::before { + content: "\f160"; } + +.fa-cloud-bolt::before { + content: "\f76c"; } + +.fa-thunderstorm::before { + content: "\f76c"; } + +.fa-text-slash::before { + content: "\f87d"; } + +.fa-remove-format::before { + content: "\f87d"; } + +.fa-face-smile-wink::before { + content: "\f4da"; } + +.fa-smile-wink::before { + content: "\f4da"; } + +.fa-file-word::before { + content: "\f1c2"; } + +.fa-file-powerpoint::before { + content: "\f1c4"; } + +.fa-arrows-left-right::before { + content: "\f07e"; } + +.fa-arrows-h::before { + content: "\f07e"; } + +.fa-house-lock::before { + content: "\e510"; } + +.fa-cloud-arrow-down::before { + content: "\f0ed"; } + +.fa-cloud-download::before { + content: "\f0ed"; } + +.fa-cloud-download-alt::before { + content: "\f0ed"; } + +.fa-children::before { + content: "\e4e1"; } + +.fa-chalkboard::before { + content: "\f51b"; } + +.fa-blackboard::before { + content: "\f51b"; } + +.fa-user-large-slash::before { + content: "\f4fa"; } + +.fa-user-alt-slash::before { + content: "\f4fa"; } + +.fa-envelope-open::before { + content: "\f2b6"; } + +.fa-handshake-simple-slash::before { + content: "\e05f"; } + +.fa-handshake-alt-slash::before { + content: "\e05f"; } + +.fa-mattress-pillow::before { + content: "\e525"; } + +.fa-guarani-sign::before { + content: "\e19a"; } + +.fa-arrows-rotate::before { + content: "\f021"; } + +.fa-refresh::before { + content: "\f021"; } + +.fa-sync::before { + content: "\f021"; } + +.fa-fire-extinguisher::before { + content: "\f134"; } + +.fa-cruzeiro-sign::before { + content: "\e152"; } + +.fa-greater-than-equal::before { + content: "\f532"; } + +.fa-shield-halved::before { + content: "\f3ed"; } + +.fa-shield-alt::before { + content: "\f3ed"; } + +.fa-book-atlas::before { + content: "\f558"; } + +.fa-atlas::before { + content: "\f558"; } + +.fa-virus::before { + content: "\e074"; } + +.fa-envelope-circle-check::before { + content: "\e4e8"; } + +.fa-layer-group::before { + content: "\f5fd"; } + +.fa-arrows-to-dot::before { + content: "\e4be"; } + +.fa-archway::before { + content: "\f557"; } + +.fa-heart-circle-check::before { + content: "\e4fd"; } + +.fa-house-chimney-crack::before { + content: "\f6f1"; } + +.fa-house-damage::before { + content: "\f6f1"; } + +.fa-file-zipper::before { + content: "\f1c6"; } + +.fa-file-archive::before { + content: "\f1c6"; } + +.fa-square::before { + content: "\f0c8"; } + +.fa-martini-glass-empty::before { + content: "\f000"; } + +.fa-glass-martini::before { + content: "\f000"; } + +.fa-couch::before { + content: "\f4b8"; } + +.fa-cedi-sign::before { + content: "\e0df"; } + +.fa-italic::before { + content: "\f033"; } + +.fa-table-cells-column-lock::before { + content: "\e678"; } + +.fa-church::before { + content: "\f51d"; } + +.fa-comments-dollar::before { + content: "\f653"; } + +.fa-democrat::before { + content: "\f747"; } + +.fa-z::before { + content: "\5a"; } + +.fa-person-skiing::before { + content: "\f7c9"; } + +.fa-skiing::before { + content: "\f7c9"; } + +.fa-road-lock::before { + content: "\e567"; } + +.fa-a::before { + content: "\41"; } + +.fa-temperature-arrow-down::before { + content: "\e03f"; } + +.fa-temperature-down::before { + content: "\e03f"; } + +.fa-feather-pointed::before { + content: "\f56b"; } + +.fa-feather-alt::before { + content: "\f56b"; } + +.fa-p::before { + content: "\50"; } + +.fa-snowflake::before { + content: "\f2dc"; } + +.fa-newspaper::before { + content: "\f1ea"; } + +.fa-rectangle-ad::before { + content: "\f641"; } + +.fa-ad::before { + content: "\f641"; } + +.fa-circle-arrow-right::before { + content: "\f0a9"; } + +.fa-arrow-circle-right::before { + content: "\f0a9"; } + +.fa-filter-circle-xmark::before { + content: "\e17b"; } + +.fa-locust::before { + content: "\e520"; } + +.fa-sort::before { + content: "\f0dc"; } + +.fa-unsorted::before { + content: "\f0dc"; } + +.fa-list-ol::before { + content: "\f0cb"; } + +.fa-list-1-2::before { + content: "\f0cb"; } + +.fa-list-numeric::before { + content: "\f0cb"; } + +.fa-person-dress-burst::before { + content: "\e544"; } + +.fa-money-check-dollar::before { + content: "\f53d"; } + +.fa-money-check-alt::before { + content: "\f53d"; } + +.fa-vector-square::before { + content: "\f5cb"; } + +.fa-bread-slice::before { + content: "\f7ec"; } + +.fa-language::before { + content: "\f1ab"; } + +.fa-face-kiss-wink-heart::before { + content: "\f598"; } + +.fa-kiss-wink-heart::before { + content: "\f598"; } + +.fa-filter::before { + content: "\f0b0"; } + +.fa-question::before { + content: "\3f"; } + +.fa-file-signature::before { + content: "\f573"; } + +.fa-up-down-left-right::before { + content: "\f0b2"; } + +.fa-arrows-alt::before { + content: "\f0b2"; } + +.fa-house-chimney-user::before { + content: "\e065"; } + +.fa-hand-holding-heart::before { + content: "\f4be"; } + +.fa-puzzle-piece::before { + content: "\f12e"; } + +.fa-money-check::before { + content: "\f53c"; } + +.fa-star-half-stroke::before { + content: "\f5c0"; } + +.fa-star-half-alt::before { + content: "\f5c0"; } + +.fa-code::before { + content: "\f121"; } + +.fa-whiskey-glass::before { + content: "\f7a0"; } + +.fa-glass-whiskey::before { + content: "\f7a0"; } + +.fa-building-circle-exclamation::before { + content: "\e4d3"; } + +.fa-magnifying-glass-chart::before { + content: "\e522"; } + +.fa-arrow-up-right-from-square::before { + content: "\f08e"; } + +.fa-external-link::before { + content: "\f08e"; } + +.fa-cubes-stacked::before { + content: "\e4e6"; } + +.fa-won-sign::before { + content: "\f159"; } + +.fa-krw::before { + content: "\f159"; } + +.fa-won::before { + content: "\f159"; } + +.fa-virus-covid::before { + content: "\e4a8"; } + +.fa-austral-sign::before { + content: "\e0a9"; } + +.fa-f::before { + content: "\46"; } + +.fa-leaf::before { + content: "\f06c"; } + +.fa-road::before { + content: "\f018"; } + +.fa-taxi::before { + content: "\f1ba"; } + +.fa-cab::before { + content: "\f1ba"; } + +.fa-person-circle-plus::before { + content: "\e541"; } + +.fa-chart-pie::before { + content: "\f200"; } + +.fa-pie-chart::before { + content: "\f200"; } + +.fa-bolt-lightning::before { + content: "\e0b7"; } + +.fa-sack-xmark::before { + content: "\e56a"; } + +.fa-file-excel::before { + content: "\f1c3"; } + +.fa-file-contract::before { + content: "\f56c"; } + +.fa-fish-fins::before { + content: "\e4f2"; } + +.fa-building-flag::before { + content: "\e4d5"; } + +.fa-face-grin-beam::before { + content: "\f582"; } + +.fa-grin-beam::before { + content: "\f582"; } + +.fa-object-ungroup::before { + content: "\f248"; } + +.fa-poop::before { + content: "\f619"; } + +.fa-location-pin::before { + content: "\f041"; } + +.fa-map-marker::before { + content: "\f041"; } + +.fa-kaaba::before { + content: "\f66b"; } + +.fa-toilet-paper::before { + content: "\f71e"; } + +.fa-helmet-safety::before { + content: "\f807"; } + +.fa-hard-hat::before { + content: "\f807"; } + +.fa-hat-hard::before { + content: "\f807"; } + +.fa-eject::before { + content: "\f052"; } + +.fa-circle-right::before { + content: "\f35a"; } + +.fa-arrow-alt-circle-right::before { + content: "\f35a"; } + +.fa-plane-circle-check::before { + content: "\e555"; } + +.fa-face-rolling-eyes::before { + content: "\f5a5"; } + +.fa-meh-rolling-eyes::before { + content: "\f5a5"; } + +.fa-object-group::before { + content: "\f247"; } + +.fa-chart-line::before { + content: "\f201"; } + +.fa-line-chart::before { + content: "\f201"; } + +.fa-mask-ventilator::before { + content: "\e524"; } + +.fa-arrow-right::before { + content: "\f061"; } + +.fa-signs-post::before { + content: "\f277"; } + +.fa-map-signs::before { + content: "\f277"; } + +.fa-cash-register::before { + content: "\f788"; } + +.fa-person-circle-question::before { + content: "\e542"; } + +.fa-h::before { + content: "\48"; } + +.fa-tarp::before { + content: "\e57b"; } + +.fa-screwdriver-wrench::before { + content: "\f7d9"; } + +.fa-tools::before { + content: "\f7d9"; } + +.fa-arrows-to-eye::before { + content: "\e4bf"; } + +.fa-plug-circle-bolt::before { + content: "\e55b"; } + +.fa-heart::before { + content: "\f004"; } + +.fa-mars-and-venus::before { + content: "\f224"; } + +.fa-house-user::before { + content: "\e1b0"; } + +.fa-home-user::before { + content: "\e1b0"; } + +.fa-dumpster-fire::before { + content: "\f794"; } + +.fa-house-crack::before { + content: "\e3b1"; } + +.fa-martini-glass-citrus::before { + content: "\f561"; } + +.fa-cocktail::before { + content: "\f561"; } + +.fa-face-surprise::before { + content: "\f5c2"; } + +.fa-surprise::before { + content: "\f5c2"; } + +.fa-bottle-water::before { + content: "\e4c5"; } + +.fa-circle-pause::before { + content: "\f28b"; } + +.fa-pause-circle::before { + content: "\f28b"; } + +.fa-toilet-paper-slash::before { + content: "\e072"; } + +.fa-apple-whole::before { + content: "\f5d1"; } + +.fa-apple-alt::before { + content: "\f5d1"; } + +.fa-kitchen-set::before { + content: "\e51a"; } + +.fa-r::before { + content: "\52"; } + +.fa-temperature-quarter::before { + content: "\f2ca"; } + +.fa-temperature-1::before { + content: "\f2ca"; } + +.fa-thermometer-1::before { + content: "\f2ca"; } + +.fa-thermometer-quarter::before { + content: "\f2ca"; } + +.fa-cube::before { + content: "\f1b2"; } + +.fa-bitcoin-sign::before { + content: "\e0b4"; } + +.fa-shield-dog::before { + content: "\e573"; } + +.fa-solar-panel::before { + content: "\f5ba"; } + +.fa-lock-open::before { + content: "\f3c1"; } + +.fa-elevator::before { + content: "\e16d"; } + +.fa-money-bill-transfer::before { + content: "\e528"; } + +.fa-money-bill-trend-up::before { + content: "\e529"; } + +.fa-house-flood-water-circle-arrow-right::before { + content: "\e50f"; } + +.fa-square-poll-horizontal::before { + content: "\f682"; } + +.fa-poll-h::before { + content: "\f682"; } + +.fa-circle::before { + content: "\f111"; } + +.fa-backward-fast::before { + content: "\f049"; } + +.fa-fast-backward::before { + content: "\f049"; } + +.fa-recycle::before { + content: "\f1b8"; } + +.fa-user-astronaut::before { + content: "\f4fb"; } + +.fa-plane-slash::before { + content: "\e069"; } + +.fa-trademark::before { + content: "\f25c"; } + +.fa-basketball::before { + content: "\f434"; } + +.fa-basketball-ball::before { + content: "\f434"; } + +.fa-satellite-dish::before { + content: "\f7c0"; } + +.fa-circle-up::before { + content: "\f35b"; } + +.fa-arrow-alt-circle-up::before { + content: "\f35b"; } + +.fa-mobile-screen-button::before { + content: "\f3cd"; } + +.fa-mobile-alt::before { + content: "\f3cd"; } + +.fa-volume-high::before { + content: "\f028"; } + +.fa-volume-up::before { + content: "\f028"; } + +.fa-users-rays::before { + content: "\e593"; } + +.fa-wallet::before { + content: "\f555"; } + +.fa-clipboard-check::before { + content: "\f46c"; } + +.fa-file-audio::before { + content: "\f1c7"; } + +.fa-burger::before { + content: "\f805"; } + +.fa-hamburger::before { + content: "\f805"; } + +.fa-wrench::before { + content: "\f0ad"; } + +.fa-bugs::before { + content: "\e4d0"; } + +.fa-rupee-sign::before { + content: "\f156"; } + +.fa-rupee::before { + content: "\f156"; } + +.fa-file-image::before { + content: "\f1c5"; } + +.fa-circle-question::before { + content: "\f059"; } + +.fa-question-circle::before { + content: "\f059"; } + +.fa-plane-departure::before { + content: "\f5b0"; } + +.fa-handshake-slash::before { + content: "\e060"; } + +.fa-book-bookmark::before { + content: "\e0bb"; } + +.fa-code-branch::before { + content: "\f126"; } + +.fa-hat-cowboy::before { + content: "\f8c0"; } + +.fa-bridge::before { + content: "\e4c8"; } + +.fa-phone-flip::before { + content: "\f879"; } + +.fa-phone-alt::before { + content: "\f879"; } + +.fa-truck-front::before { + content: "\e2b7"; } + +.fa-cat::before { + content: "\f6be"; } + +.fa-anchor-circle-exclamation::before { + content: "\e4ab"; } + +.fa-truck-field::before { + content: "\e58d"; } + +.fa-route::before { + content: "\f4d7"; } + +.fa-clipboard-question::before { + content: "\e4e3"; } + +.fa-panorama::before { + content: "\e209"; } + +.fa-comment-medical::before { + content: "\f7f5"; } + +.fa-teeth-open::before { + content: "\f62f"; } + +.fa-file-circle-minus::before { + content: "\e4ed"; } + +.fa-tags::before { + content: "\f02c"; } + +.fa-wine-glass::before { + content: "\f4e3"; } + +.fa-forward-fast::before { + content: "\f050"; } + +.fa-fast-forward::before { + content: "\f050"; } + +.fa-face-meh-blank::before { + content: "\f5a4"; } + +.fa-meh-blank::before { + content: "\f5a4"; } + +.fa-square-parking::before { + content: "\f540"; } + +.fa-parking::before { + content: "\f540"; } + +.fa-house-signal::before { + content: "\e012"; } + +.fa-bars-progress::before { + content: "\f828"; } + +.fa-tasks-alt::before { + content: "\f828"; } + +.fa-faucet-drip::before { + content: "\e006"; } + +.fa-cart-flatbed::before { + content: "\f474"; } + +.fa-dolly-flatbed::before { + content: "\f474"; } + +.fa-ban-smoking::before { + content: "\f54d"; } + +.fa-smoking-ban::before { + content: "\f54d"; } + +.fa-terminal::before { + content: "\f120"; } + +.fa-mobile-button::before { + content: "\f10b"; } + +.fa-house-medical-flag::before { + content: "\e514"; } + +.fa-basket-shopping::before { + content: "\f291"; } + +.fa-shopping-basket::before { + content: "\f291"; } + +.fa-tape::before { + content: "\f4db"; } + +.fa-bus-simple::before { + content: "\f55e"; } + +.fa-bus-alt::before { + content: "\f55e"; } + +.fa-eye::before { + content: "\f06e"; } + +.fa-face-sad-cry::before { + content: "\f5b3"; } + +.fa-sad-cry::before { + content: "\f5b3"; } + +.fa-audio-description::before { + content: "\f29e"; } + +.fa-person-military-to-person::before { + content: "\e54c"; } + +.fa-file-shield::before { + content: "\e4f0"; } + +.fa-user-slash::before { + content: "\f506"; } + +.fa-pen::before { + content: "\f304"; } + +.fa-tower-observation::before { + content: "\e586"; } + +.fa-file-code::before { + content: "\f1c9"; } + +.fa-signal::before { + content: "\f012"; } + +.fa-signal-5::before { + content: "\f012"; } + +.fa-signal-perfect::before { + content: "\f012"; } + +.fa-bus::before { + content: "\f207"; } + +.fa-heart-circle-xmark::before { + content: "\e501"; } + +.fa-house-chimney::before { + content: "\e3af"; } + +.fa-home-lg::before { + content: "\e3af"; } + +.fa-window-maximize::before { + content: "\f2d0"; } + +.fa-face-frown::before { + content: "\f119"; } + +.fa-frown::before { + content: "\f119"; } + +.fa-prescription::before { + content: "\f5b1"; } + +.fa-shop::before { + content: "\f54f"; } + +.fa-store-alt::before { + content: "\f54f"; } + +.fa-floppy-disk::before { + content: "\f0c7"; } + +.fa-save::before { + content: "\f0c7"; } + +.fa-vihara::before { + content: "\f6a7"; } + +.fa-scale-unbalanced::before { + content: "\f515"; } + +.fa-balance-scale-left::before { + content: "\f515"; } + +.fa-sort-up::before { + content: "\f0de"; } + +.fa-sort-asc::before { + content: "\f0de"; } + +.fa-comment-dots::before { + content: "\f4ad"; } + +.fa-commenting::before { + content: "\f4ad"; } + +.fa-plant-wilt::before { + content: "\e5aa"; } + +.fa-diamond::before { + content: "\f219"; } + +.fa-face-grin-squint::before { + content: "\f585"; } + +.fa-grin-squint::before { + content: "\f585"; } + +.fa-hand-holding-dollar::before { + content: "\f4c0"; } + +.fa-hand-holding-usd::before { + content: "\f4c0"; } + +.fa-bacterium::before { + content: "\e05a"; } + +.fa-hand-pointer::before { + content: "\f25a"; } + +.fa-drum-steelpan::before { + content: "\f56a"; } + +.fa-hand-scissors::before { + content: "\f257"; } + +.fa-hands-praying::before { + content: "\f684"; } + +.fa-praying-hands::before { + content: "\f684"; } + +.fa-arrow-rotate-right::before { + content: "\f01e"; } + +.fa-arrow-right-rotate::before { + content: "\f01e"; } + +.fa-arrow-rotate-forward::before { + content: "\f01e"; } + +.fa-redo::before { + content: "\f01e"; } + +.fa-biohazard::before { + content: "\f780"; } + +.fa-location-crosshairs::before { + content: "\f601"; } + +.fa-location::before { + content: "\f601"; } + +.fa-mars-double::before { + content: "\f227"; } + +.fa-child-dress::before { + content: "\e59c"; } + +.fa-users-between-lines::before { + content: "\e591"; } + +.fa-lungs-virus::before { + content: "\e067"; } + +.fa-face-grin-tears::before { + content: "\f588"; } + +.fa-grin-tears::before { + content: "\f588"; } + +.fa-phone::before { + content: "\f095"; } + +.fa-calendar-xmark::before { + content: "\f273"; } + +.fa-calendar-times::before { + content: "\f273"; } + +.fa-child-reaching::before { + content: "\e59d"; } + +.fa-head-side-virus::before { + content: "\e064"; } + +.fa-user-gear::before { + content: "\f4fe"; } + +.fa-user-cog::before { + content: "\f4fe"; } + +.fa-arrow-up-1-9::before { + content: "\f163"; } + +.fa-sort-numeric-up::before { + content: "\f163"; } + +.fa-door-closed::before { + content: "\f52a"; } + +.fa-shield-virus::before { + content: "\e06c"; } + +.fa-dice-six::before { + content: "\f526"; } + +.fa-mosquito-net::before { + content: "\e52c"; } + +.fa-bridge-water::before { + content: "\e4ce"; } + +.fa-person-booth::before { + content: "\f756"; } + +.fa-text-width::before { + content: "\f035"; } + +.fa-hat-wizard::before { + content: "\f6e8"; } + +.fa-pen-fancy::before { + content: "\f5ac"; } + +.fa-person-digging::before { + content: "\f85e"; } + +.fa-digging::before { + content: "\f85e"; } + +.fa-trash::before { + content: "\f1f8"; } + +.fa-gauge-simple::before { + content: "\f629"; } + +.fa-gauge-simple-med::before { + content: "\f629"; } + +.fa-tachometer-average::before { + content: "\f629"; } + +.fa-book-medical::before { + content: "\f7e6"; } + +.fa-poo::before { + content: "\f2fe"; } + +.fa-quote-right::before { + content: "\f10e"; } + +.fa-quote-right-alt::before { + content: "\f10e"; } + +.fa-shirt::before { + content: "\f553"; } + +.fa-t-shirt::before { + content: "\f553"; } + +.fa-tshirt::before { + content: "\f553"; } + +.fa-cubes::before { + content: "\f1b3"; } + +.fa-divide::before { + content: "\f529"; } + +.fa-tenge-sign::before { + content: "\f7d7"; } + +.fa-tenge::before { + content: "\f7d7"; } + +.fa-headphones::before { + content: "\f025"; } + +.fa-hands-holding::before { + content: "\f4c2"; } + +.fa-hands-clapping::before { + content: "\e1a8"; } + +.fa-republican::before { + content: "\f75e"; } + +.fa-arrow-left::before { + content: "\f060"; } + +.fa-person-circle-xmark::before { + content: "\e543"; } + +.fa-ruler::before { + content: "\f545"; } + +.fa-align-left::before { + content: "\f036"; } + +.fa-dice-d6::before { + content: "\f6d1"; } + +.fa-restroom::before { + content: "\f7bd"; } + +.fa-j::before { + content: "\4a"; } + +.fa-users-viewfinder::before { + content: "\e595"; } + +.fa-file-video::before { + content: "\f1c8"; } + +.fa-up-right-from-square::before { + content: "\f35d"; } + +.fa-external-link-alt::before { + content: "\f35d"; } + +.fa-table-cells::before { + content: "\f00a"; } + +.fa-th::before { + content: "\f00a"; } + +.fa-file-pdf::before { + content: "\f1c1"; } + +.fa-book-bible::before { + content: "\f647"; } + +.fa-bible::before { + content: "\f647"; } + +.fa-o::before { + content: "\4f"; } + +.fa-suitcase-medical::before { + content: "\f0fa"; } + +.fa-medkit::before { + content: "\f0fa"; } + +.fa-user-secret::before { + content: "\f21b"; } + +.fa-otter::before { + content: "\f700"; } + +.fa-person-dress::before { + content: "\f182"; } + +.fa-female::before { + content: "\f182"; } + +.fa-comment-dollar::before { + content: "\f651"; } + +.fa-business-time::before { + content: "\f64a"; } + +.fa-briefcase-clock::before { + content: "\f64a"; } + +.fa-table-cells-large::before { + content: "\f009"; } + +.fa-th-large::before { + content: "\f009"; } + +.fa-book-tanakh::before { + content: "\f827"; } + +.fa-tanakh::before { + content: "\f827"; } + +.fa-phone-volume::before { + content: "\f2a0"; } + +.fa-volume-control-phone::before { + content: "\f2a0"; } + +.fa-hat-cowboy-side::before { + content: "\f8c1"; } + +.fa-clipboard-user::before { + content: "\f7f3"; } + +.fa-child::before { + content: "\f1ae"; } + +.fa-lira-sign::before { + content: "\f195"; } + +.fa-satellite::before { + content: "\f7bf"; } + +.fa-plane-lock::before { + content: "\e558"; } + +.fa-tag::before { + content: "\f02b"; } + +.fa-comment::before { + content: "\f075"; } + +.fa-cake-candles::before { + content: "\f1fd"; } + +.fa-birthday-cake::before { + content: "\f1fd"; } + +.fa-cake::before { + content: "\f1fd"; } + +.fa-envelope::before { + content: "\f0e0"; } + +.fa-angles-up::before { + content: "\f102"; } + +.fa-angle-double-up::before { + content: "\f102"; } + +.fa-paperclip::before { + content: "\f0c6"; } + +.fa-arrow-right-to-city::before { + content: "\e4b3"; } + +.fa-ribbon::before { + content: "\f4d6"; } + +.fa-lungs::before { + content: "\f604"; } + +.fa-arrow-up-9-1::before { + content: "\f887"; } + +.fa-sort-numeric-up-alt::before { + content: "\f887"; } + +.fa-litecoin-sign::before { + content: "\e1d3"; } + +.fa-border-none::before { + content: "\f850"; } + +.fa-circle-nodes::before { + content: "\e4e2"; } + +.fa-parachute-box::before { + content: "\f4cd"; } + +.fa-indent::before { + content: "\f03c"; } + +.fa-truck-field-un::before { + content: "\e58e"; } + +.fa-hourglass::before { + content: "\f254"; } + +.fa-hourglass-empty::before { + content: "\f254"; } + +.fa-mountain::before { + content: "\f6fc"; } + +.fa-user-doctor::before { + content: "\f0f0"; } + +.fa-user-md::before { + content: "\f0f0"; } + +.fa-circle-info::before { + content: "\f05a"; } + +.fa-info-circle::before { + content: "\f05a"; } + +.fa-cloud-meatball::before { + content: "\f73b"; } + +.fa-camera::before { + content: "\f030"; } + +.fa-camera-alt::before { + content: "\f030"; } + +.fa-square-virus::before { + content: "\e578"; } + +.fa-meteor::before { + content: "\f753"; } + +.fa-car-on::before { + content: "\e4dd"; } + +.fa-sleigh::before { + content: "\f7cc"; } + +.fa-arrow-down-1-9::before { + content: "\f162"; } + +.fa-sort-numeric-asc::before { + content: "\f162"; } + +.fa-sort-numeric-down::before { + content: "\f162"; } + +.fa-hand-holding-droplet::before { + content: "\f4c1"; } + +.fa-hand-holding-water::before { + content: "\f4c1"; } + +.fa-water::before { + content: "\f773"; } + +.fa-calendar-check::before { + content: "\f274"; } + +.fa-braille::before { + content: "\f2a1"; } + +.fa-prescription-bottle-medical::before { + content: "\f486"; } + +.fa-prescription-bottle-alt::before { + content: "\f486"; } + +.fa-landmark::before { + content: "\f66f"; } + +.fa-truck::before { + content: "\f0d1"; } + +.fa-crosshairs::before { + content: "\f05b"; } + +.fa-person-cane::before { + content: "\e53c"; } + +.fa-tent::before { + content: "\e57d"; } + +.fa-vest-patches::before { + content: "\e086"; } + +.fa-check-double::before { + content: "\f560"; } + +.fa-arrow-down-a-z::before { + content: "\f15d"; } + +.fa-sort-alpha-asc::before { + content: "\f15d"; } + +.fa-sort-alpha-down::before { + content: "\f15d"; } + +.fa-money-bill-wheat::before { + content: "\e52a"; } + +.fa-cookie::before { + content: "\f563"; } + +.fa-arrow-rotate-left::before { + content: "\f0e2"; } + +.fa-arrow-left-rotate::before { + content: "\f0e2"; } + +.fa-arrow-rotate-back::before { + content: "\f0e2"; } + +.fa-arrow-rotate-backward::before { + content: "\f0e2"; } + +.fa-undo::before { + content: "\f0e2"; } + +.fa-hard-drive::before { + content: "\f0a0"; } + +.fa-hdd::before { + content: "\f0a0"; } + +.fa-face-grin-squint-tears::before { + content: "\f586"; } + +.fa-grin-squint-tears::before { + content: "\f586"; } + +.fa-dumbbell::before { + content: "\f44b"; } + +.fa-rectangle-list::before { + content: "\f022"; } + +.fa-list-alt::before { + content: "\f022"; } + +.fa-tarp-droplet::before { + content: "\e57c"; } + +.fa-house-medical-circle-check::before { + content: "\e511"; } + +.fa-person-skiing-nordic::before { + content: "\f7ca"; } + +.fa-skiing-nordic::before { + content: "\f7ca"; } + +.fa-calendar-plus::before { + content: "\f271"; } + +.fa-plane-arrival::before { + content: "\f5af"; } + +.fa-circle-left::before { + content: "\f359"; } + +.fa-arrow-alt-circle-left::before { + content: "\f359"; } + +.fa-train-subway::before { + content: "\f239"; } + +.fa-subway::before { + content: "\f239"; } + +.fa-chart-gantt::before { + content: "\e0e4"; } + +.fa-indian-rupee-sign::before { + content: "\e1bc"; } + +.fa-indian-rupee::before { + content: "\e1bc"; } + +.fa-inr::before { + content: "\e1bc"; } + +.fa-crop-simple::before { + content: "\f565"; } + +.fa-crop-alt::before { + content: "\f565"; } + +.fa-money-bill-1::before { + content: "\f3d1"; } + +.fa-money-bill-alt::before { + content: "\f3d1"; } + +.fa-left-long::before { + content: "\f30a"; } + +.fa-long-arrow-alt-left::before { + content: "\f30a"; } + +.fa-dna::before { + content: "\f471"; } + +.fa-virus-slash::before { + content: "\e075"; } + +.fa-minus::before { + content: "\f068"; } + +.fa-subtract::before { + content: "\f068"; } + +.fa-chess::before { + content: "\f439"; } + +.fa-arrow-left-long::before { + content: "\f177"; } + +.fa-long-arrow-left::before { + content: "\f177"; } + +.fa-plug-circle-check::before { + content: "\e55c"; } + +.fa-street-view::before { + content: "\f21d"; } + +.fa-franc-sign::before { + content: "\e18f"; } + +.fa-volume-off::before { + content: "\f026"; } + +.fa-hands-asl-interpreting::before { + content: "\f2a3"; } + +.fa-american-sign-language-interpreting::before { + content: "\f2a3"; } + +.fa-asl-interpreting::before { + content: "\f2a3"; } + +.fa-hands-american-sign-language-interpreting::before { + content: "\f2a3"; } + +.fa-gear::before { + content: "\f013"; } + +.fa-cog::before { + content: "\f013"; } + +.fa-droplet-slash::before { + content: "\f5c7"; } + +.fa-tint-slash::before { + content: "\f5c7"; } + +.fa-mosque::before { + content: "\f678"; } + +.fa-mosquito::before { + content: "\e52b"; } + +.fa-star-of-david::before { + content: "\f69a"; } + +.fa-person-military-rifle::before { + content: "\e54b"; } + +.fa-cart-shopping::before { + content: "\f07a"; } + +.fa-shopping-cart::before { + content: "\f07a"; } + +.fa-vials::before { + content: "\f493"; } + +.fa-plug-circle-plus::before { + content: "\e55f"; } + +.fa-place-of-worship::before { + content: "\f67f"; } + +.fa-grip-vertical::before { + content: "\f58e"; } + +.fa-arrow-turn-up::before { + content: "\f148"; } + +.fa-level-up::before { + content: "\f148"; } + +.fa-u::before { + content: "\55"; } + +.fa-square-root-variable::before { + content: "\f698"; } + +.fa-square-root-alt::before { + content: "\f698"; } + +.fa-clock::before { + content: "\f017"; } + +.fa-clock-four::before { + content: "\f017"; } + +.fa-backward-step::before { + content: "\f048"; } + +.fa-step-backward::before { + content: "\f048"; } + +.fa-pallet::before { + content: "\f482"; } + +.fa-faucet::before { + content: "\e005"; } + +.fa-baseball-bat-ball::before { + content: "\f432"; } + +.fa-s::before { + content: "\53"; } + +.fa-timeline::before { + content: "\e29c"; } + +.fa-keyboard::before { + content: "\f11c"; } + +.fa-caret-down::before { + content: "\f0d7"; } + +.fa-house-chimney-medical::before { + content: "\f7f2"; } + +.fa-clinic-medical::before { + content: "\f7f2"; } + +.fa-temperature-three-quarters::before { + content: "\f2c8"; } + +.fa-temperature-3::before { + content: "\f2c8"; } + +.fa-thermometer-3::before { + content: "\f2c8"; } + +.fa-thermometer-three-quarters::before { + content: "\f2c8"; } + +.fa-mobile-screen::before { + content: "\f3cf"; } + +.fa-mobile-android-alt::before { + content: "\f3cf"; } + +.fa-plane-up::before { + content: "\e22d"; } + +.fa-piggy-bank::before { + content: "\f4d3"; } + +.fa-battery-half::before { + content: "\f242"; } + +.fa-battery-3::before { + content: "\f242"; } + +.fa-mountain-city::before { + content: "\e52e"; } + +.fa-coins::before { + content: "\f51e"; } + +.fa-khanda::before { + content: "\f66d"; } + +.fa-sliders::before { + content: "\f1de"; } + +.fa-sliders-h::before { + content: "\f1de"; } + +.fa-folder-tree::before { + content: "\f802"; } + +.fa-network-wired::before { + content: "\f6ff"; } + +.fa-map-pin::before { + content: "\f276"; } + +.fa-hamsa::before { + content: "\f665"; } + +.fa-cent-sign::before { + content: "\e3f5"; } + +.fa-flask::before { + content: "\f0c3"; } + +.fa-person-pregnant::before { + content: "\e31e"; } + +.fa-wand-sparkles::before { + content: "\f72b"; } + +.fa-ellipsis-vertical::before { + content: "\f142"; } + +.fa-ellipsis-v::before { + content: "\f142"; } + +.fa-ticket::before { + content: "\f145"; } + +.fa-power-off::before { + content: "\f011"; } + +.fa-right-long::before { + content: "\f30b"; } + +.fa-long-arrow-alt-right::before { + content: "\f30b"; } + +.fa-flag-usa::before { + content: "\f74d"; } + +.fa-laptop-file::before { + content: "\e51d"; } + +.fa-tty::before { + content: "\f1e4"; } + +.fa-teletype::before { + content: "\f1e4"; } + +.fa-diagram-next::before { + content: "\e476"; } + +.fa-person-rifle::before { + content: "\e54e"; } + +.fa-house-medical-circle-exclamation::before { + content: "\e512"; } + +.fa-closed-captioning::before { + content: "\f20a"; } + +.fa-person-hiking::before { + content: "\f6ec"; } + +.fa-hiking::before { + content: "\f6ec"; } + +.fa-venus-double::before { + content: "\f226"; } + +.fa-images::before { + content: "\f302"; } + +.fa-calculator::before { + content: "\f1ec"; } + +.fa-people-pulling::before { + content: "\e535"; } + +.fa-n::before { + content: "\4e"; } + +.fa-cable-car::before { + content: "\f7da"; } + +.fa-tram::before { + content: "\f7da"; } + +.fa-cloud-rain::before { + content: "\f73d"; } + +.fa-building-circle-xmark::before { + content: "\e4d4"; } + +.fa-ship::before { + content: "\f21a"; } + +.fa-arrows-down-to-line::before { + content: "\e4b8"; } + +.fa-download::before { + content: "\f019"; } + +.fa-face-grin::before { + content: "\f580"; } + +.fa-grin::before { + content: "\f580"; } + +.fa-delete-left::before { + content: "\f55a"; } + +.fa-backspace::before { + content: "\f55a"; } + +.fa-eye-dropper::before { + content: "\f1fb"; } + +.fa-eye-dropper-empty::before { + content: "\f1fb"; } + +.fa-eyedropper::before { + content: "\f1fb"; } + +.fa-file-circle-check::before { + content: "\e5a0"; } + +.fa-forward::before { + content: "\f04e"; } + +.fa-mobile::before { + content: "\f3ce"; } + +.fa-mobile-android::before { + content: "\f3ce"; } + +.fa-mobile-phone::before { + content: "\f3ce"; } + +.fa-face-meh::before { + content: "\f11a"; } + +.fa-meh::before { + content: "\f11a"; } + +.fa-align-center::before { + content: "\f037"; } + +.fa-book-skull::before { + content: "\f6b7"; } + +.fa-book-dead::before { + content: "\f6b7"; } + +.fa-id-card::before { + content: "\f2c2"; } + +.fa-drivers-license::before { + content: "\f2c2"; } + +.fa-outdent::before { + content: "\f03b"; } + +.fa-dedent::before { + content: "\f03b"; } + +.fa-heart-circle-exclamation::before { + content: "\e4fe"; } + +.fa-house::before { + content: "\f015"; } + +.fa-home::before { + content: "\f015"; } + +.fa-home-alt::before { + content: "\f015"; } + +.fa-home-lg-alt::before { + content: "\f015"; } + +.fa-calendar-week::before { + content: "\f784"; } + +.fa-laptop-medical::before { + content: "\f812"; } + +.fa-b::before { + content: "\42"; } + +.fa-file-medical::before { + content: "\f477"; } + +.fa-dice-one::before { + content: "\f525"; } + +.fa-kiwi-bird::before { + content: "\f535"; } + +.fa-arrow-right-arrow-left::before { + content: "\f0ec"; } + +.fa-exchange::before { + content: "\f0ec"; } + +.fa-rotate-right::before { + content: "\f2f9"; } + +.fa-redo-alt::before { + content: "\f2f9"; } + +.fa-rotate-forward::before { + content: "\f2f9"; } + +.fa-utensils::before { + content: "\f2e7"; } + +.fa-cutlery::before { + content: "\f2e7"; } + +.fa-arrow-up-wide-short::before { + content: "\f161"; } + +.fa-sort-amount-up::before { + content: "\f161"; } + +.fa-mill-sign::before { + content: "\e1ed"; } + +.fa-bowl-rice::before { + content: "\e2eb"; } + +.fa-skull::before { + content: "\f54c"; } + +.fa-tower-broadcast::before { + content: "\f519"; } + +.fa-broadcast-tower::before { + content: "\f519"; } + +.fa-truck-pickup::before { + content: "\f63c"; } + +.fa-up-long::before { + content: "\f30c"; } + +.fa-long-arrow-alt-up::before { + content: "\f30c"; } + +.fa-stop::before { + content: "\f04d"; } + +.fa-code-merge::before { + content: "\f387"; } + +.fa-upload::before { + content: "\f093"; } + +.fa-hurricane::before { + content: "\f751"; } + +.fa-mound::before { + content: "\e52d"; } + +.fa-toilet-portable::before { + content: "\e583"; } + +.fa-compact-disc::before { + content: "\f51f"; } + +.fa-file-arrow-down::before { + content: "\f56d"; } + +.fa-file-download::before { + content: "\f56d"; } + +.fa-caravan::before { + content: "\f8ff"; } + +.fa-shield-cat::before { + content: "\e572"; } + +.fa-bolt::before { + content: "\f0e7"; } + +.fa-zap::before { + content: "\f0e7"; } + +.fa-glass-water::before { + content: "\e4f4"; } + +.fa-oil-well::before { + content: "\e532"; } + +.fa-vault::before { + content: "\e2c5"; } + +.fa-mars::before { + content: "\f222"; } + +.fa-toilet::before { + content: "\f7d8"; } + +.fa-plane-circle-xmark::before { + content: "\e557"; } + +.fa-yen-sign::before { + content: "\f157"; } + +.fa-cny::before { + content: "\f157"; } + +.fa-jpy::before { + content: "\f157"; } + +.fa-rmb::before { + content: "\f157"; } + +.fa-yen::before { + content: "\f157"; } + +.fa-ruble-sign::before { + content: "\f158"; } + +.fa-rouble::before { + content: "\f158"; } + +.fa-rub::before { + content: "\f158"; } + +.fa-ruble::before { + content: "\f158"; } + +.fa-sun::before { + content: "\f185"; } + +.fa-guitar::before { + content: "\f7a6"; } + +.fa-face-laugh-wink::before { + content: "\f59c"; } + +.fa-laugh-wink::before { + content: "\f59c"; } + +.fa-horse-head::before { + content: "\f7ab"; } + +.fa-bore-hole::before { + content: "\e4c3"; } + +.fa-industry::before { + content: "\f275"; } + +.fa-circle-down::before { + content: "\f358"; } + +.fa-arrow-alt-circle-down::before { + content: "\f358"; } + +.fa-arrows-turn-to-dots::before { + content: "\e4c1"; } + +.fa-florin-sign::before { + content: "\e184"; } + +.fa-arrow-down-short-wide::before { + content: "\f884"; } + +.fa-sort-amount-desc::before { + content: "\f884"; } + +.fa-sort-amount-down-alt::before { + content: "\f884"; } + +.fa-less-than::before { + content: "\3c"; } + +.fa-angle-down::before { + content: "\f107"; } + +.fa-car-tunnel::before { + content: "\e4de"; } + +.fa-head-side-cough::before { + content: "\e061"; } + +.fa-grip-lines::before { + content: "\f7a4"; } + +.fa-thumbs-down::before { + content: "\f165"; } + +.fa-user-lock::before { + content: "\f502"; } + +.fa-arrow-right-long::before { + content: "\f178"; } + +.fa-long-arrow-right::before { + content: "\f178"; } + +.fa-anchor-circle-xmark::before { + content: "\e4ac"; } + +.fa-ellipsis::before { + content: "\f141"; } + +.fa-ellipsis-h::before { + content: "\f141"; } + +.fa-chess-pawn::before { + content: "\f443"; } + +.fa-kit-medical::before { + content: "\f479"; } + +.fa-first-aid::before { + content: "\f479"; } + +.fa-person-through-window::before { + content: "\e5a9"; } + +.fa-toolbox::before { + content: "\f552"; } + +.fa-hands-holding-circle::before { + content: "\e4fb"; } + +.fa-bug::before { + content: "\f188"; } + +.fa-credit-card::before { + content: "\f09d"; } + +.fa-credit-card-alt::before { + content: "\f09d"; } + +.fa-car::before { + content: "\f1b9"; } + +.fa-automobile::before { + content: "\f1b9"; } + +.fa-hand-holding-hand::before { + content: "\e4f7"; } + +.fa-book-open-reader::before { + content: "\f5da"; } + +.fa-book-reader::before { + content: "\f5da"; } + +.fa-mountain-sun::before { + content: "\e52f"; } + +.fa-arrows-left-right-to-line::before { + content: "\e4ba"; } + +.fa-dice-d20::before { + content: "\f6cf"; } + +.fa-truck-droplet::before { + content: "\e58c"; } + +.fa-file-circle-xmark::before { + content: "\e5a1"; } + +.fa-temperature-arrow-up::before { + content: "\e040"; } + +.fa-temperature-up::before { + content: "\e040"; } + +.fa-medal::before { + content: "\f5a2"; } + +.fa-bed::before { + content: "\f236"; } + +.fa-square-h::before { + content: "\f0fd"; } + +.fa-h-square::before { + content: "\f0fd"; } + +.fa-podcast::before { + content: "\f2ce"; } + +.fa-temperature-full::before { + content: "\f2c7"; } + +.fa-temperature-4::before { + content: "\f2c7"; } + +.fa-thermometer-4::before { + content: "\f2c7"; } + +.fa-thermometer-full::before { + content: "\f2c7"; } + +.fa-bell::before { + content: "\f0f3"; } + +.fa-superscript::before { + content: "\f12b"; } + +.fa-plug-circle-xmark::before { + content: "\e560"; } + +.fa-star-of-life::before { + content: "\f621"; } + +.fa-phone-slash::before { + content: "\f3dd"; } + +.fa-paint-roller::before { + content: "\f5aa"; } + +.fa-handshake-angle::before { + content: "\f4c4"; } + +.fa-hands-helping::before { + content: "\f4c4"; } + +.fa-location-dot::before { + content: "\f3c5"; } + +.fa-map-marker-alt::before { + content: "\f3c5"; } + +.fa-file::before { + content: "\f15b"; } + +.fa-greater-than::before { + content: "\3e"; } + +.fa-person-swimming::before { + content: "\f5c4"; } + +.fa-swimmer::before { + content: "\f5c4"; } + +.fa-arrow-down::before { + content: "\f063"; } + +.fa-droplet::before { + content: "\f043"; } + +.fa-tint::before { + content: "\f043"; } + +.fa-eraser::before { + content: "\f12d"; } + +.fa-earth-americas::before { + content: "\f57d"; } + +.fa-earth::before { + content: "\f57d"; } + +.fa-earth-america::before { + content: "\f57d"; } + +.fa-globe-americas::before { + content: "\f57d"; } + +.fa-person-burst::before { + content: "\e53b"; } + +.fa-dove::before { + content: "\f4ba"; } + +.fa-battery-empty::before { + content: "\f244"; } + +.fa-battery-0::before { + content: "\f244"; } + +.fa-socks::before { + content: "\f696"; } + +.fa-inbox::before { + content: "\f01c"; } + +.fa-section::before { + content: "\e447"; } + +.fa-gauge-high::before { + content: "\f625"; } + +.fa-tachometer-alt::before { + content: "\f625"; } + +.fa-tachometer-alt-fast::before { + content: "\f625"; } + +.fa-envelope-open-text::before { + content: "\f658"; } + +.fa-hospital::before { + content: "\f0f8"; } + +.fa-hospital-alt::before { + content: "\f0f8"; } + +.fa-hospital-wide::before { + content: "\f0f8"; } + +.fa-wine-bottle::before { + content: "\f72f"; } + +.fa-chess-rook::before { + content: "\f447"; } + +.fa-bars-staggered::before { + content: "\f550"; } + +.fa-reorder::before { + content: "\f550"; } + +.fa-stream::before { + content: "\f550"; } + +.fa-dharmachakra::before { + content: "\f655"; } + +.fa-hotdog::before { + content: "\f80f"; } + +.fa-person-walking-with-cane::before { + content: "\f29d"; } + +.fa-blind::before { + content: "\f29d"; } + +.fa-drum::before { + content: "\f569"; } + +.fa-ice-cream::before { + content: "\f810"; } + +.fa-heart-circle-bolt::before { + content: "\e4fc"; } + +.fa-fax::before { + content: "\f1ac"; } + +.fa-paragraph::before { + content: "\f1dd"; } + +.fa-check-to-slot::before { + content: "\f772"; } + +.fa-vote-yea::before { + content: "\f772"; } + +.fa-star-half::before { + content: "\f089"; } + +.fa-boxes-stacked::before { + content: "\f468"; } + +.fa-boxes::before { + content: "\f468"; } + +.fa-boxes-alt::before { + content: "\f468"; } + +.fa-link::before { + content: "\f0c1"; } + +.fa-chain::before { + content: "\f0c1"; } + +.fa-ear-listen::before { + content: "\f2a2"; } + +.fa-assistive-listening-systems::before { + content: "\f2a2"; } + +.fa-tree-city::before { + content: "\e587"; } + +.fa-play::before { + content: "\f04b"; } + +.fa-font::before { + content: "\f031"; } + +.fa-table-cells-row-lock::before { + content: "\e67a"; } + +.fa-rupiah-sign::before { + content: "\e23d"; } + +.fa-magnifying-glass::before { + content: "\f002"; } + +.fa-search::before { + content: "\f002"; } + +.fa-table-tennis-paddle-ball::before { + content: "\f45d"; } + +.fa-ping-pong-paddle-ball::before { + content: "\f45d"; } + +.fa-table-tennis::before { + content: "\f45d"; } + +.fa-person-dots-from-line::before { + content: "\f470"; } + +.fa-diagnoses::before { + content: "\f470"; } + +.fa-trash-can-arrow-up::before { + content: "\f82a"; } + +.fa-trash-restore-alt::before { + content: "\f82a"; } + +.fa-naira-sign::before { + content: "\e1f6"; } + +.fa-cart-arrow-down::before { + content: "\f218"; } + +.fa-walkie-talkie::before { + content: "\f8ef"; } + +.fa-file-pen::before { + content: "\f31c"; } + +.fa-file-edit::before { + content: "\f31c"; } + +.fa-receipt::before { + content: "\f543"; } + +.fa-square-pen::before { + content: "\f14b"; } + +.fa-pen-square::before { + content: "\f14b"; } + +.fa-pencil-square::before { + content: "\f14b"; } + +.fa-suitcase-rolling::before { + content: "\f5c1"; } + +.fa-person-circle-exclamation::before { + content: "\e53f"; } + +.fa-chevron-down::before { + content: "\f078"; } + +.fa-battery-full::before { + content: "\f240"; } + +.fa-battery::before { + content: "\f240"; } + +.fa-battery-5::before { + content: "\f240"; } + +.fa-skull-crossbones::before { + content: "\f714"; } + +.fa-code-compare::before { + content: "\e13a"; } + +.fa-list-ul::before { + content: "\f0ca"; } + +.fa-list-dots::before { + content: "\f0ca"; } + +.fa-school-lock::before { + content: "\e56f"; } + +.fa-tower-cell::before { + content: "\e585"; } + +.fa-down-long::before { + content: "\f309"; } + +.fa-long-arrow-alt-down::before { + content: "\f309"; } + +.fa-ranking-star::before { + content: "\e561"; } + +.fa-chess-king::before { + content: "\f43f"; } + +.fa-person-harassing::before { + content: "\e549"; } + +.fa-brazilian-real-sign::before { + content: "\e46c"; } + +.fa-landmark-dome::before { + content: "\f752"; } + +.fa-landmark-alt::before { + content: "\f752"; } + +.fa-arrow-up::before { + content: "\f062"; } + +.fa-tv::before { + content: "\f26c"; } + +.fa-television::before { + content: "\f26c"; } + +.fa-tv-alt::before { + content: "\f26c"; } + +.fa-shrimp::before { + content: "\e448"; } + +.fa-list-check::before { + content: "\f0ae"; } + +.fa-tasks::before { + content: "\f0ae"; } + +.fa-jug-detergent::before { + content: "\e519"; } + +.fa-circle-user::before { + content: "\f2bd"; } + +.fa-user-circle::before { + content: "\f2bd"; } + +.fa-user-shield::before { + content: "\f505"; } + +.fa-wind::before { + content: "\f72e"; } + +.fa-car-burst::before { + content: "\f5e1"; } + +.fa-car-crash::before { + content: "\f5e1"; } + +.fa-y::before { + content: "\59"; } + +.fa-person-snowboarding::before { + content: "\f7ce"; } + +.fa-snowboarding::before { + content: "\f7ce"; } + +.fa-truck-fast::before { + content: "\f48b"; } + +.fa-shipping-fast::before { + content: "\f48b"; } + +.fa-fish::before { + content: "\f578"; } + +.fa-user-graduate::before { + content: "\f501"; } + +.fa-circle-half-stroke::before { + content: "\f042"; } + +.fa-adjust::before { + content: "\f042"; } + +.fa-clapperboard::before { + content: "\e131"; } + +.fa-circle-radiation::before { + content: "\f7ba"; } + +.fa-radiation-alt::before { + content: "\f7ba"; } + +.fa-baseball::before { + content: "\f433"; } + +.fa-baseball-ball::before { + content: "\f433"; } + +.fa-jet-fighter-up::before { + content: "\e518"; } + +.fa-diagram-project::before { + content: "\f542"; } + +.fa-project-diagram::before { + content: "\f542"; } + +.fa-copy::before { + content: "\f0c5"; } + +.fa-volume-xmark::before { + content: "\f6a9"; } + +.fa-volume-mute::before { + content: "\f6a9"; } + +.fa-volume-times::before { + content: "\f6a9"; } + +.fa-hand-sparkles::before { + content: "\e05d"; } + +.fa-grip::before { + content: "\f58d"; } + +.fa-grip-horizontal::before { + content: "\f58d"; } + +.fa-share-from-square::before { + content: "\f14d"; } + +.fa-share-square::before { + content: "\f14d"; } + +.fa-child-combatant::before { + content: "\e4e0"; } + +.fa-child-rifle::before { + content: "\e4e0"; } + +.fa-gun::before { + content: "\e19b"; } + +.fa-square-phone::before { + content: "\f098"; } + +.fa-phone-square::before { + content: "\f098"; } + +.fa-plus::before { + content: "\2b"; } + +.fa-add::before { + content: "\2b"; } + +.fa-expand::before { + content: "\f065"; } + +.fa-computer::before { + content: "\e4e5"; } + +.fa-xmark::before { + content: "\f00d"; } + +.fa-close::before { + content: "\f00d"; } + +.fa-multiply::before { + content: "\f00d"; } + +.fa-remove::before { + content: "\f00d"; } + +.fa-times::before { + content: "\f00d"; } + +.fa-arrows-up-down-left-right::before { + content: "\f047"; } + +.fa-arrows::before { + content: "\f047"; } + +.fa-chalkboard-user::before { + content: "\f51c"; } + +.fa-chalkboard-teacher::before { + content: "\f51c"; } + +.fa-peso-sign::before { + content: "\e222"; } + +.fa-building-shield::before { + content: "\e4d8"; } + +.fa-baby::before { + content: "\f77c"; } + +.fa-users-line::before { + content: "\e592"; } + +.fa-quote-left::before { + content: "\f10d"; } + +.fa-quote-left-alt::before { + content: "\f10d"; } + +.fa-tractor::before { + content: "\f722"; } + +.fa-trash-arrow-up::before { + content: "\f829"; } + +.fa-trash-restore::before { + content: "\f829"; } + +.fa-arrow-down-up-lock::before { + content: "\e4b0"; } + +.fa-lines-leaning::before { + content: "\e51e"; } + +.fa-ruler-combined::before { + content: "\f546"; } + +.fa-copyright::before { + content: "\f1f9"; } + +.fa-equals::before { + content: "\3d"; } + +.fa-blender::before { + content: "\f517"; } + +.fa-teeth::before { + content: "\f62e"; } + +.fa-shekel-sign::before { + content: "\f20b"; } + +.fa-ils::before { + content: "\f20b"; } + +.fa-shekel::before { + content: "\f20b"; } + +.fa-sheqel::before { + content: "\f20b"; } + +.fa-sheqel-sign::before { + content: "\f20b"; } + +.fa-map::before { + content: "\f279"; } + +.fa-rocket::before { + content: "\f135"; } + +.fa-photo-film::before { + content: "\f87c"; } + +.fa-photo-video::before { + content: "\f87c"; } + +.fa-folder-minus::before { + content: "\f65d"; } + +.fa-store::before { + content: "\f54e"; } + +.fa-arrow-trend-up::before { + content: "\e098"; } + +.fa-plug-circle-minus::before { + content: "\e55e"; } + +.fa-sign-hanging::before { + content: "\f4d9"; } + +.fa-sign::before { + content: "\f4d9"; } + +.fa-bezier-curve::before { + content: "\f55b"; } + +.fa-bell-slash::before { + content: "\f1f6"; } + +.fa-tablet::before { + content: "\f3fb"; } + +.fa-tablet-android::before { + content: "\f3fb"; } + +.fa-school-flag::before { + content: "\e56e"; } + +.fa-fill::before { + content: "\f575"; } + +.fa-angle-up::before { + content: "\f106"; } + +.fa-drumstick-bite::before { + content: "\f6d7"; } + +.fa-holly-berry::before { + content: "\f7aa"; } + +.fa-chevron-left::before { + content: "\f053"; } + +.fa-bacteria::before { + content: "\e059"; } + +.fa-hand-lizard::before { + content: "\f258"; } + +.fa-notdef::before { + content: "\e1fe"; } + +.fa-disease::before { + content: "\f7fa"; } + +.fa-briefcase-medical::before { + content: "\f469"; } + +.fa-genderless::before { + content: "\f22d"; } + +.fa-chevron-right::before { + content: "\f054"; } + +.fa-retweet::before { + content: "\f079"; } + +.fa-car-rear::before { + content: "\f5de"; } + +.fa-car-alt::before { + content: "\f5de"; } + +.fa-pump-soap::before { + content: "\e06b"; } + +.fa-video-slash::before { + content: "\f4e2"; } + +.fa-battery-quarter::before { + content: "\f243"; } + +.fa-battery-2::before { + content: "\f243"; } + +.fa-radio::before { + content: "\f8d7"; } + +.fa-baby-carriage::before { + content: "\f77d"; } + +.fa-carriage-baby::before { + content: "\f77d"; } + +.fa-traffic-light::before { + content: "\f637"; } + +.fa-thermometer::before { + content: "\f491"; } + +.fa-vr-cardboard::before { + content: "\f729"; } + +.fa-hand-middle-finger::before { + content: "\f806"; } + +.fa-percent::before { + content: "\25"; } + +.fa-percentage::before { + content: "\25"; } + +.fa-truck-moving::before { + content: "\f4df"; } + +.fa-glass-water-droplet::before { + content: "\e4f5"; } + +.fa-display::before { + content: "\e163"; } + +.fa-face-smile::before { + content: "\f118"; } + +.fa-smile::before { + content: "\f118"; } + +.fa-thumbtack::before { + content: "\f08d"; } + +.fa-thumb-tack::before { + content: "\f08d"; } + +.fa-trophy::before { + content: "\f091"; } + +.fa-person-praying::before { + content: "\f683"; } + +.fa-pray::before { + content: "\f683"; } + +.fa-hammer::before { + content: "\f6e3"; } + +.fa-hand-peace::before { + content: "\f25b"; } + +.fa-rotate::before { + content: "\f2f1"; } + +.fa-sync-alt::before { + content: "\f2f1"; } + +.fa-spinner::before { + content: "\f110"; } + +.fa-robot::before { + content: "\f544"; } + +.fa-peace::before { + content: "\f67c"; } + +.fa-gears::before { + content: "\f085"; } + +.fa-cogs::before { + content: "\f085"; } + +.fa-warehouse::before { + content: "\f494"; } + +.fa-arrow-up-right-dots::before { + content: "\e4b7"; } + +.fa-splotch::before { + content: "\f5bc"; } + +.fa-face-grin-hearts::before { + content: "\f584"; } + +.fa-grin-hearts::before { + content: "\f584"; } + +.fa-dice-four::before { + content: "\f524"; } + +.fa-sim-card::before { + content: "\f7c4"; } + +.fa-transgender::before { + content: "\f225"; } + +.fa-transgender-alt::before { + content: "\f225"; } + +.fa-mercury::before { + content: "\f223"; } + +.fa-arrow-turn-down::before { + content: "\f149"; } + +.fa-level-down::before { + content: "\f149"; } + +.fa-person-falling-burst::before { + content: "\e547"; } + +.fa-award::before { + content: "\f559"; } + +.fa-ticket-simple::before { + content: "\f3ff"; } + +.fa-ticket-alt::before { + content: "\f3ff"; } + +.fa-building::before { + content: "\f1ad"; } + +.fa-angles-left::before { + content: "\f100"; } + +.fa-angle-double-left::before { + content: "\f100"; } + +.fa-qrcode::before { + content: "\f029"; } + +.fa-clock-rotate-left::before { + content: "\f1da"; } + +.fa-history::before { + content: "\f1da"; } + +.fa-face-grin-beam-sweat::before { + content: "\f583"; } + +.fa-grin-beam-sweat::before { + content: "\f583"; } + +.fa-file-export::before { + content: "\f56e"; } + +.fa-arrow-right-from-file::before { + content: "\f56e"; } + +.fa-shield::before { + content: "\f132"; } + +.fa-shield-blank::before { + content: "\f132"; } + +.fa-arrow-up-short-wide::before { + content: "\f885"; } + +.fa-sort-amount-up-alt::before { + content: "\f885"; } + +.fa-house-medical::before { + content: "\e3b2"; } + +.fa-golf-ball-tee::before { + content: "\f450"; } + +.fa-golf-ball::before { + content: "\f450"; } + +.fa-circle-chevron-left::before { + content: "\f137"; } + +.fa-chevron-circle-left::before { + content: "\f137"; } + +.fa-house-chimney-window::before { + content: "\e00d"; } + +.fa-pen-nib::before { + content: "\f5ad"; } + +.fa-tent-arrow-turn-left::before { + content: "\e580"; } + +.fa-tents::before { + content: "\e582"; } + +.fa-wand-magic::before { + content: "\f0d0"; } + +.fa-magic::before { + content: "\f0d0"; } + +.fa-dog::before { + content: "\f6d3"; } + +.fa-carrot::before { + content: "\f787"; } + +.fa-moon::before { + content: "\f186"; } + +.fa-wine-glass-empty::before { + content: "\f5ce"; } + +.fa-wine-glass-alt::before { + content: "\f5ce"; } + +.fa-cheese::before { + content: "\f7ef"; } + +.fa-yin-yang::before { + content: "\f6ad"; } + +.fa-music::before { + content: "\f001"; } + +.fa-code-commit::before { + content: "\f386"; } + +.fa-temperature-low::before { + content: "\f76b"; } + +.fa-person-biking::before { + content: "\f84a"; } + +.fa-biking::before { + content: "\f84a"; } + +.fa-broom::before { + content: "\f51a"; } + +.fa-shield-heart::before { + content: "\e574"; } + +.fa-gopuram::before { + content: "\f664"; } + +.fa-earth-oceania::before { + content: "\e47b"; } + +.fa-globe-oceania::before { + content: "\e47b"; } + +.fa-square-xmark::before { + content: "\f2d3"; } + +.fa-times-square::before { + content: "\f2d3"; } + +.fa-xmark-square::before { + content: "\f2d3"; } + +.fa-hashtag::before { + content: "\23"; } + +.fa-up-right-and-down-left-from-center::before { + content: "\f424"; } + +.fa-expand-alt::before { + content: "\f424"; } + +.fa-oil-can::before { + content: "\f613"; } + +.fa-t::before { + content: "\54"; } + +.fa-hippo::before { + content: "\f6ed"; } + +.fa-chart-column::before { + content: "\e0e3"; } + +.fa-infinity::before { + content: "\f534"; } + +.fa-vial-circle-check::before { + content: "\e596"; } + +.fa-person-arrow-down-to-line::before { + content: "\e538"; } + +.fa-voicemail::before { + content: "\f897"; } + +.fa-fan::before { + content: "\f863"; } + +.fa-person-walking-luggage::before { + content: "\e554"; } + +.fa-up-down::before { + content: "\f338"; } + +.fa-arrows-alt-v::before { + content: "\f338"; } + +.fa-cloud-moon-rain::before { + content: "\f73c"; } + +.fa-calendar::before { + content: "\f133"; } + +.fa-trailer::before { + content: "\e041"; } + +.fa-bahai::before { + content: "\f666"; } + +.fa-haykal::before { + content: "\f666"; } + +.fa-sd-card::before { + content: "\f7c2"; } + +.fa-dragon::before { + content: "\f6d5"; } + +.fa-shoe-prints::before { + content: "\f54b"; } + +.fa-circle-plus::before { + content: "\f055"; } + +.fa-plus-circle::before { + content: "\f055"; } + +.fa-face-grin-tongue-wink::before { + content: "\f58b"; } + +.fa-grin-tongue-wink::before { + content: "\f58b"; } + +.fa-hand-holding::before { + content: "\f4bd"; } + +.fa-plug-circle-exclamation::before { + content: "\e55d"; } + +.fa-link-slash::before { + content: "\f127"; } + +.fa-chain-broken::before { + content: "\f127"; } + +.fa-chain-slash::before { + content: "\f127"; } + +.fa-unlink::before { + content: "\f127"; } + +.fa-clone::before { + content: "\f24d"; } + +.fa-person-walking-arrow-loop-left::before { + content: "\e551"; } + +.fa-arrow-up-z-a::before { + content: "\f882"; } + +.fa-sort-alpha-up-alt::before { + content: "\f882"; } + +.fa-fire-flame-curved::before { + content: "\f7e4"; } + +.fa-fire-alt::before { + content: "\f7e4"; } + +.fa-tornado::before { + content: "\f76f"; } + +.fa-file-circle-plus::before { + content: "\e494"; } + +.fa-book-quran::before { + content: "\f687"; } + +.fa-quran::before { + content: "\f687"; } + +.fa-anchor::before { + content: "\f13d"; } + +.fa-border-all::before { + content: "\f84c"; } + +.fa-face-angry::before { + content: "\f556"; } + +.fa-angry::before { + content: "\f556"; } + +.fa-cookie-bite::before { + content: "\f564"; } + +.fa-arrow-trend-down::before { + content: "\e097"; } + +.fa-rss::before { + content: "\f09e"; } + +.fa-feed::before { + content: "\f09e"; } + +.fa-draw-polygon::before { + content: "\f5ee"; } + +.fa-scale-balanced::before { + content: "\f24e"; } + +.fa-balance-scale::before { + content: "\f24e"; } + +.fa-gauge-simple-high::before { + content: "\f62a"; } + +.fa-tachometer::before { + content: "\f62a"; } + +.fa-tachometer-fast::before { + content: "\f62a"; } + +.fa-shower::before { + content: "\f2cc"; } + +.fa-desktop::before { + content: "\f390"; } + +.fa-desktop-alt::before { + content: "\f390"; } + +.fa-m::before { + content: "\4d"; } + +.fa-table-list::before { + content: "\f00b"; } + +.fa-th-list::before { + content: "\f00b"; } + +.fa-comment-sms::before { + content: "\f7cd"; } + +.fa-sms::before { + content: "\f7cd"; } + +.fa-book::before { + content: "\f02d"; } + +.fa-user-plus::before { + content: "\f234"; } + +.fa-check::before { + content: "\f00c"; } + +.fa-battery-three-quarters::before { + content: "\f241"; } + +.fa-battery-4::before { + content: "\f241"; } + +.fa-house-circle-check::before { + content: "\e509"; } + +.fa-angle-left::before { + content: "\f104"; } + +.fa-diagram-successor::before { + content: "\e47a"; } + +.fa-truck-arrow-right::before { + content: "\e58b"; } + +.fa-arrows-split-up-and-left::before { + content: "\e4bc"; } + +.fa-hand-fist::before { + content: "\f6de"; } + +.fa-fist-raised::before { + content: "\f6de"; } + +.fa-cloud-moon::before { + content: "\f6c3"; } + +.fa-briefcase::before { + content: "\f0b1"; } + +.fa-person-falling::before { + content: "\e546"; } + +.fa-image-portrait::before { + content: "\f3e0"; } + +.fa-portrait::before { + content: "\f3e0"; } + +.fa-user-tag::before { + content: "\f507"; } + +.fa-rug::before { + content: "\e569"; } + +.fa-earth-europe::before { + content: "\f7a2"; } + +.fa-globe-europe::before { + content: "\f7a2"; } + +.fa-cart-flatbed-suitcase::before { + content: "\f59d"; } + +.fa-luggage-cart::before { + content: "\f59d"; } + +.fa-rectangle-xmark::before { + content: "\f410"; } + +.fa-rectangle-times::before { + content: "\f410"; } + +.fa-times-rectangle::before { + content: "\f410"; } + +.fa-window-close::before { + content: "\f410"; } + +.fa-baht-sign::before { + content: "\e0ac"; } + +.fa-book-open::before { + content: "\f518"; } + +.fa-book-journal-whills::before { + content: "\f66a"; } + +.fa-journal-whills::before { + content: "\f66a"; } + +.fa-handcuffs::before { + content: "\e4f8"; } + +.fa-triangle-exclamation::before { + content: "\f071"; } + +.fa-exclamation-triangle::before { + content: "\f071"; } + +.fa-warning::before { + content: "\f071"; } + +.fa-database::before { + content: "\f1c0"; } + +.fa-share::before { + content: "\f064"; } + +.fa-mail-forward::before { + content: "\f064"; } + +.fa-bottle-droplet::before { + content: "\e4c4"; } + +.fa-mask-face::before { + content: "\e1d7"; } + +.fa-hill-rockslide::before { + content: "\e508"; } + +.fa-right-left::before { + content: "\f362"; } + +.fa-exchange-alt::before { + content: "\f362"; } + +.fa-paper-plane::before { + content: "\f1d8"; } + +.fa-road-circle-exclamation::before { + content: "\e565"; } + +.fa-dungeon::before { + content: "\f6d9"; } + +.fa-align-right::before { + content: "\f038"; } + +.fa-money-bill-1-wave::before { + content: "\f53b"; } + +.fa-money-bill-wave-alt::before { + content: "\f53b"; } + +.fa-life-ring::before { + content: "\f1cd"; } + +.fa-hands::before { + content: "\f2a7"; } + +.fa-sign-language::before { + content: "\f2a7"; } + +.fa-signing::before { + content: "\f2a7"; } + +.fa-calendar-day::before { + content: "\f783"; } + +.fa-water-ladder::before { + content: "\f5c5"; } + +.fa-ladder-water::before { + content: "\f5c5"; } + +.fa-swimming-pool::before { + content: "\f5c5"; } + +.fa-arrows-up-down::before { + content: "\f07d"; } + +.fa-arrows-v::before { + content: "\f07d"; } + +.fa-face-grimace::before { + content: "\f57f"; } + +.fa-grimace::before { + content: "\f57f"; } + +.fa-wheelchair-move::before { + content: "\e2ce"; } + +.fa-wheelchair-alt::before { + content: "\e2ce"; } + +.fa-turn-down::before { + content: "\f3be"; } + +.fa-level-down-alt::before { + content: "\f3be"; } + +.fa-person-walking-arrow-right::before { + content: "\e552"; } + +.fa-square-envelope::before { + content: "\f199"; } + +.fa-envelope-square::before { + content: "\f199"; } + +.fa-dice::before { + content: "\f522"; } + +.fa-bowling-ball::before { + content: "\f436"; } + +.fa-brain::before { + content: "\f5dc"; } + +.fa-bandage::before { + content: "\f462"; } + +.fa-band-aid::before { + content: "\f462"; } + +.fa-calendar-minus::before { + content: "\f272"; } + +.fa-circle-xmark::before { + content: "\f057"; } + +.fa-times-circle::before { + content: "\f057"; } + +.fa-xmark-circle::before { + content: "\f057"; } + +.fa-gifts::before { + content: "\f79c"; } + +.fa-hotel::before { + content: "\f594"; } + +.fa-earth-asia::before { + content: "\f57e"; } + +.fa-globe-asia::before { + content: "\f57e"; } + +.fa-id-card-clip::before { + content: "\f47f"; } + +.fa-id-card-alt::before { + content: "\f47f"; } + +.fa-magnifying-glass-plus::before { + content: "\f00e"; } + +.fa-search-plus::before { + content: "\f00e"; } + +.fa-thumbs-up::before { + content: "\f164"; } + +.fa-user-clock::before { + content: "\f4fd"; } + +.fa-hand-dots::before { + content: "\f461"; } + +.fa-allergies::before { + content: "\f461"; } + +.fa-file-invoice::before { + content: "\f570"; } + +.fa-window-minimize::before { + content: "\f2d1"; } + +.fa-mug-saucer::before { + content: "\f0f4"; } + +.fa-coffee::before { + content: "\f0f4"; } + +.fa-brush::before { + content: "\f55d"; } + +.fa-mask::before { + content: "\f6fa"; } + +.fa-magnifying-glass-minus::before { + content: "\f010"; } + +.fa-search-minus::before { + content: "\f010"; } + +.fa-ruler-vertical::before { + content: "\f548"; } + +.fa-user-large::before { + content: "\f406"; } + +.fa-user-alt::before { + content: "\f406"; } + +.fa-train-tram::before { + content: "\e5b4"; } + +.fa-user-nurse::before { + content: "\f82f"; } + +.fa-syringe::before { + content: "\f48e"; } + +.fa-cloud-sun::before { + content: "\f6c4"; } + +.fa-stopwatch-20::before { + content: "\e06f"; } + +.fa-square-full::before { + content: "\f45c"; } + +.fa-magnet::before { + content: "\f076"; } + +.fa-jar::before { + content: "\e516"; } + +.fa-note-sticky::before { + content: "\f249"; } + +.fa-sticky-note::before { + content: "\f249"; } + +.fa-bug-slash::before { + content: "\e490"; } + +.fa-arrow-up-from-water-pump::before { + content: "\e4b6"; } + +.fa-bone::before { + content: "\f5d7"; } + +.fa-user-injured::before { + content: "\f728"; } + +.fa-face-sad-tear::before { + content: "\f5b4"; } + +.fa-sad-tear::before { + content: "\f5b4"; } + +.fa-plane::before { + content: "\f072"; } + +.fa-tent-arrows-down::before { + content: "\e581"; } + +.fa-exclamation::before { + content: "\21"; } + +.fa-arrows-spin::before { + content: "\e4bb"; } + +.fa-print::before { + content: "\f02f"; } + +.fa-turkish-lira-sign::before { + content: "\e2bb"; } + +.fa-try::before { + content: "\e2bb"; } + +.fa-turkish-lira::before { + content: "\e2bb"; } + +.fa-dollar-sign::before { + content: "\24"; } + +.fa-dollar::before { + content: "\24"; } + +.fa-usd::before { + content: "\24"; } + +.fa-x::before { + content: "\58"; } + +.fa-magnifying-glass-dollar::before { + content: "\f688"; } + +.fa-search-dollar::before { + content: "\f688"; } + +.fa-users-gear::before { + content: "\f509"; } + +.fa-users-cog::before { + content: "\f509"; } + +.fa-person-military-pointing::before { + content: "\e54a"; } + +.fa-building-columns::before { + content: "\f19c"; } + +.fa-bank::before { + content: "\f19c"; } + +.fa-institution::before { + content: "\f19c"; } + +.fa-museum::before { + content: "\f19c"; } + +.fa-university::before { + content: "\f19c"; } + +.fa-umbrella::before { + content: "\f0e9"; } + +.fa-trowel::before { + content: "\e589"; } + +.fa-d::before { + content: "\44"; } + +.fa-stapler::before { + content: "\e5af"; } + +.fa-masks-theater::before { + content: "\f630"; } + +.fa-theater-masks::before { + content: "\f630"; } + +.fa-kip-sign::before { + content: "\e1c4"; } + +.fa-hand-point-left::before { + content: "\f0a5"; } + +.fa-handshake-simple::before { + content: "\f4c6"; } + +.fa-handshake-alt::before { + content: "\f4c6"; } + +.fa-jet-fighter::before { + content: "\f0fb"; } + +.fa-fighter-jet::before { + content: "\f0fb"; } + +.fa-square-share-nodes::before { + content: "\f1e1"; } + +.fa-share-alt-square::before { + content: "\f1e1"; } + +.fa-barcode::before { + content: "\f02a"; } + +.fa-plus-minus::before { + content: "\e43c"; } + +.fa-video::before { + content: "\f03d"; } + +.fa-video-camera::before { + content: "\f03d"; } + +.fa-graduation-cap::before { + content: "\f19d"; } + +.fa-mortar-board::before { + content: "\f19d"; } + +.fa-hand-holding-medical::before { + content: "\e05c"; } + +.fa-person-circle-check::before { + content: "\e53e"; } + +.fa-turn-up::before { + content: "\f3bf"; } + +.fa-level-up-alt::before { + content: "\f3bf"; } + +.sr-only, +.fa-sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; } + +.sr-only-focusable:not(:focus), +.fa-sr-only-focusable:not(:focus) { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; } +:root, :host { + --fa-style-family-brands: 'Font Awesome 6 Brands'; + --fa-font-brands: normal 400 1em/1 'Font Awesome 6 Brands'; } + +@font-face { + font-family: 'Font Awesome 6 Brands'; + font-style: normal; + font-weight: 400; + font-display: block; + src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); } + +.fab, +.fa-brands { + font-weight: 400; } + +.fa-monero:before { + content: "\f3d0"; } + +.fa-hooli:before { + content: "\f427"; } + +.fa-yelp:before { + content: "\f1e9"; } + +.fa-cc-visa:before { + content: "\f1f0"; } + +.fa-lastfm:before { + content: "\f202"; } + +.fa-shopware:before { + content: "\f5b5"; } + +.fa-creative-commons-nc:before { + content: "\f4e8"; } + +.fa-aws:before { + content: "\f375"; } + +.fa-redhat:before { + content: "\f7bc"; } + +.fa-yoast:before { + content: "\f2b1"; } + +.fa-cloudflare:before { + content: "\e07d"; } + +.fa-ups:before { + content: "\f7e0"; } + +.fa-pixiv:before { + content: "\e640"; } + +.fa-wpexplorer:before { + content: "\f2de"; } + +.fa-dyalog:before { + content: "\f399"; } + +.fa-bity:before { + content: "\f37a"; } + +.fa-stackpath:before { + content: "\f842"; } + +.fa-buysellads:before { + content: "\f20d"; } + +.fa-first-order:before { + content: "\f2b0"; } + +.fa-modx:before { + content: "\f285"; } + +.fa-guilded:before { + content: "\e07e"; } + +.fa-vnv:before { + content: "\f40b"; } + +.fa-square-js:before { + content: "\f3b9"; } + +.fa-js-square:before { + content: "\f3b9"; } + +.fa-microsoft:before { + content: "\f3ca"; } + +.fa-qq:before { + content: "\f1d6"; } + +.fa-orcid:before { + content: "\f8d2"; } + +.fa-java:before { + content: "\f4e4"; } + +.fa-invision:before { + content: "\f7b0"; } + +.fa-creative-commons-pd-alt:before { + content: "\f4ed"; } + +.fa-centercode:before { + content: "\f380"; } + +.fa-glide-g:before { + content: "\f2a6"; } + +.fa-drupal:before { + content: "\f1a9"; } + +.fa-jxl:before { + content: "\e67b"; } + +.fa-hire-a-helper:before { + content: "\f3b0"; } + +.fa-creative-commons-by:before { + content: "\f4e7"; } + +.fa-unity:before { + content: "\e049"; } + +.fa-whmcs:before { + content: "\f40d"; } + +.fa-rocketchat:before { + content: "\f3e8"; } + +.fa-vk:before { + content: "\f189"; } + +.fa-untappd:before { + content: "\f405"; } + +.fa-mailchimp:before { + content: "\f59e"; } + +.fa-css3-alt:before { + content: "\f38b"; } + +.fa-square-reddit:before { + content: "\f1a2"; } + +.fa-reddit-square:before { + content: "\f1a2"; } + +.fa-vimeo-v:before { + content: "\f27d"; } + +.fa-contao:before { + content: "\f26d"; } + +.fa-square-font-awesome:before { + content: "\e5ad"; } + +.fa-deskpro:before { + content: "\f38f"; } + +.fa-brave:before { + content: "\e63c"; } + +.fa-sistrix:before { + content: "\f3ee"; } + +.fa-square-instagram:before { + content: "\e055"; } + +.fa-instagram-square:before { + content: "\e055"; } + +.fa-battle-net:before { + content: "\f835"; } + +.fa-the-red-yeti:before { + content: "\f69d"; } + +.fa-square-hacker-news:before { + content: "\f3af"; } + +.fa-hacker-news-square:before { + content: "\f3af"; } + +.fa-edge:before { + content: "\f282"; } + +.fa-threads:before { + content: "\e618"; } + +.fa-napster:before { + content: "\f3d2"; } + +.fa-square-snapchat:before { + content: "\f2ad"; } + +.fa-snapchat-square:before { + content: "\f2ad"; } + +.fa-google-plus-g:before { + content: "\f0d5"; } + +.fa-artstation:before { + content: "\f77a"; } + +.fa-markdown:before { + content: "\f60f"; } + +.fa-sourcetree:before { + content: "\f7d3"; } + +.fa-google-plus:before { + content: "\f2b3"; } + +.fa-diaspora:before { + content: "\f791"; } + +.fa-foursquare:before { + content: "\f180"; } + +.fa-stack-overflow:before { + content: "\f16c"; } + +.fa-github-alt:before { + content: "\f113"; } + +.fa-phoenix-squadron:before { + content: "\f511"; } + +.fa-pagelines:before { + content: "\f18c"; } + +.fa-algolia:before { + content: "\f36c"; } + +.fa-red-river:before { + content: "\f3e3"; } + +.fa-creative-commons-sa:before { + content: "\f4ef"; } + +.fa-safari:before { + content: "\f267"; } + +.fa-google:before { + content: "\f1a0"; } + +.fa-square-font-awesome-stroke:before { + content: "\f35c"; } + +.fa-font-awesome-alt:before { + content: "\f35c"; } + +.fa-atlassian:before { + content: "\f77b"; } + +.fa-linkedin-in:before { + content: "\f0e1"; } + +.fa-digital-ocean:before { + content: "\f391"; } + +.fa-nimblr:before { + content: "\f5a8"; } + +.fa-chromecast:before { + content: "\f838"; } + +.fa-evernote:before { + content: "\f839"; } + +.fa-hacker-news:before { + content: "\f1d4"; } + +.fa-creative-commons-sampling:before { + content: "\f4f0"; } + +.fa-adversal:before { + content: "\f36a"; } + +.fa-creative-commons:before { + content: "\f25e"; } + +.fa-watchman-monitoring:before { + content: "\e087"; } + +.fa-fonticons:before { + content: "\f280"; } + +.fa-weixin:before { + content: "\f1d7"; } + +.fa-shirtsinbulk:before { + content: "\f214"; } + +.fa-codepen:before { + content: "\f1cb"; } + +.fa-git-alt:before { + content: "\f841"; } + +.fa-lyft:before { + content: "\f3c3"; } + +.fa-rev:before { + content: "\f5b2"; } + +.fa-windows:before { + content: "\f17a"; } + +.fa-wizards-of-the-coast:before { + content: "\f730"; } + +.fa-square-viadeo:before { + content: "\f2aa"; } + +.fa-viadeo-square:before { + content: "\f2aa"; } + +.fa-meetup:before { + content: "\f2e0"; } + +.fa-centos:before { + content: "\f789"; } + +.fa-adn:before { + content: "\f170"; } + +.fa-cloudsmith:before { + content: "\f384"; } + +.fa-opensuse:before { + content: "\e62b"; } + +.fa-pied-piper-alt:before { + content: "\f1a8"; } + +.fa-square-dribbble:before { + content: "\f397"; } + +.fa-dribbble-square:before { + content: "\f397"; } + +.fa-codiepie:before { + content: "\f284"; } + +.fa-node:before { + content: "\f419"; } + +.fa-mix:before { + content: "\f3cb"; } + +.fa-steam:before { + content: "\f1b6"; } + +.fa-cc-apple-pay:before { + content: "\f416"; } + +.fa-scribd:before { + content: "\f28a"; } + +.fa-debian:before { + content: "\e60b"; } + +.fa-openid:before { + content: "\f19b"; } + +.fa-instalod:before { + content: "\e081"; } + +.fa-expeditedssl:before { + content: "\f23e"; } + +.fa-sellcast:before { + content: "\f2da"; } + +.fa-square-twitter:before { + content: "\f081"; } + +.fa-twitter-square:before { + content: "\f081"; } + +.fa-r-project:before { + content: "\f4f7"; } + +.fa-delicious:before { + content: "\f1a5"; } + +.fa-freebsd:before { + content: "\f3a4"; } + +.fa-vuejs:before { + content: "\f41f"; } + +.fa-accusoft:before { + content: "\f369"; } + +.fa-ioxhost:before { + content: "\f208"; } + +.fa-fonticons-fi:before { + content: "\f3a2"; } + +.fa-app-store:before { + content: "\f36f"; } + +.fa-cc-mastercard:before { + content: "\f1f1"; } + +.fa-itunes-note:before { + content: "\f3b5"; } + +.fa-golang:before { + content: "\e40f"; } + +.fa-kickstarter:before { + content: "\f3bb"; } + +.fa-square-kickstarter:before { + content: "\f3bb"; } + +.fa-grav:before { + content: "\f2d6"; } + +.fa-weibo:before { + content: "\f18a"; } + +.fa-uncharted:before { + content: "\e084"; } + +.fa-firstdraft:before { + content: "\f3a1"; } + +.fa-square-youtube:before { + content: "\f431"; } + +.fa-youtube-square:before { + content: "\f431"; } + +.fa-wikipedia-w:before { + content: "\f266"; } + +.fa-wpressr:before { + content: "\f3e4"; } + +.fa-rendact:before { + content: "\f3e4"; } + +.fa-angellist:before { + content: "\f209"; } + +.fa-galactic-republic:before { + content: "\f50c"; } + +.fa-nfc-directional:before { + content: "\e530"; } + +.fa-skype:before { + content: "\f17e"; } + +.fa-joget:before { + content: "\f3b7"; } + +.fa-fedora:before { + content: "\f798"; } + +.fa-stripe-s:before { + content: "\f42a"; } + +.fa-meta:before { + content: "\e49b"; } + +.fa-laravel:before { + content: "\f3bd"; } + +.fa-hotjar:before { + content: "\f3b1"; } + +.fa-bluetooth-b:before { + content: "\f294"; } + +.fa-square-letterboxd:before { + content: "\e62e"; } + +.fa-sticker-mule:before { + content: "\f3f7"; } + +.fa-creative-commons-zero:before { + content: "\f4f3"; } + +.fa-hips:before { + content: "\f452"; } + +.fa-behance:before { + content: "\f1b4"; } + +.fa-reddit:before { + content: "\f1a1"; } + +.fa-discord:before { + content: "\f392"; } + +.fa-chrome:before { + content: "\f268"; } + +.fa-app-store-ios:before { + content: "\f370"; } + +.fa-cc-discover:before { + content: "\f1f2"; } + +.fa-wpbeginner:before { + content: "\f297"; } + +.fa-confluence:before { + content: "\f78d"; } + +.fa-shoelace:before { + content: "\e60c"; } + +.fa-mdb:before { + content: "\f8ca"; } + +.fa-dochub:before { + content: "\f394"; } + +.fa-accessible-icon:before { + content: "\f368"; } + +.fa-ebay:before { + content: "\f4f4"; } + +.fa-amazon:before { + content: "\f270"; } + +.fa-unsplash:before { + content: "\e07c"; } + +.fa-yarn:before { + content: "\f7e3"; } + +.fa-square-steam:before { + content: "\f1b7"; } + +.fa-steam-square:before { + content: "\f1b7"; } + +.fa-500px:before { + content: "\f26e"; } + +.fa-square-vimeo:before { + content: "\f194"; } + +.fa-vimeo-square:before { + content: "\f194"; } + +.fa-asymmetrik:before { + content: "\f372"; } + +.fa-font-awesome:before { + content: "\f2b4"; } + +.fa-font-awesome-flag:before { + content: "\f2b4"; } + +.fa-font-awesome-logo-full:before { + content: "\f2b4"; } + +.fa-gratipay:before { + content: "\f184"; } + +.fa-apple:before { + content: "\f179"; } + +.fa-hive:before { + content: "\e07f"; } + +.fa-gitkraken:before { + content: "\f3a6"; } + +.fa-keybase:before { + content: "\f4f5"; } + +.fa-apple-pay:before { + content: "\f415"; } + +.fa-padlet:before { + content: "\e4a0"; } + +.fa-amazon-pay:before { + content: "\f42c"; } + +.fa-square-github:before { + content: "\f092"; } + +.fa-github-square:before { + content: "\f092"; } + +.fa-stumbleupon:before { + content: "\f1a4"; } + +.fa-fedex:before { + content: "\f797"; } + +.fa-phoenix-framework:before { + content: "\f3dc"; } + +.fa-shopify:before { + content: "\e057"; } + +.fa-neos:before { + content: "\f612"; } + +.fa-square-threads:before { + content: "\e619"; } + +.fa-hackerrank:before { + content: "\f5f7"; } + +.fa-researchgate:before { + content: "\f4f8"; } + +.fa-swift:before { + content: "\f8e1"; } + +.fa-angular:before { + content: "\f420"; } + +.fa-speakap:before { + content: "\f3f3"; } + +.fa-angrycreative:before { + content: "\f36e"; } + +.fa-y-combinator:before { + content: "\f23b"; } + +.fa-empire:before { + content: "\f1d1"; } + +.fa-envira:before { + content: "\f299"; } + +.fa-google-scholar:before { + content: "\e63b"; } + +.fa-square-gitlab:before { + content: "\e5ae"; } + +.fa-gitlab-square:before { + content: "\e5ae"; } + +.fa-studiovinari:before { + content: "\f3f8"; } + +.fa-pied-piper:before { + content: "\f2ae"; } + +.fa-wordpress:before { + content: "\f19a"; } + +.fa-product-hunt:before { + content: "\f288"; } + +.fa-firefox:before { + content: "\f269"; } + +.fa-linode:before { + content: "\f2b8"; } + +.fa-goodreads:before { + content: "\f3a8"; } + +.fa-square-odnoklassniki:before { + content: "\f264"; } + +.fa-odnoklassniki-square:before { + content: "\f264"; } + +.fa-jsfiddle:before { + content: "\f1cc"; } + +.fa-sith:before { + content: "\f512"; } + +.fa-themeisle:before { + content: "\f2b2"; } + +.fa-page4:before { + content: "\f3d7"; } + +.fa-hashnode:before { + content: "\e499"; } + +.fa-react:before { + content: "\f41b"; } + +.fa-cc-paypal:before { + content: "\f1f4"; } + +.fa-squarespace:before { + content: "\f5be"; } + +.fa-cc-stripe:before { + content: "\f1f5"; } + +.fa-creative-commons-share:before { + content: "\f4f2"; } + +.fa-bitcoin:before { + content: "\f379"; } + +.fa-keycdn:before { + content: "\f3ba"; } + +.fa-opera:before { + content: "\f26a"; } + +.fa-itch-io:before { + content: "\f83a"; } + +.fa-umbraco:before { + content: "\f8e8"; } + +.fa-galactic-senate:before { + content: "\f50d"; } + +.fa-ubuntu:before { + content: "\f7df"; } + +.fa-draft2digital:before { + content: "\f396"; } + +.fa-stripe:before { + content: "\f429"; } + +.fa-houzz:before { + content: "\f27c"; } + +.fa-gg:before { + content: "\f260"; } + +.fa-dhl:before { + content: "\f790"; } + +.fa-square-pinterest:before { + content: "\f0d3"; } + +.fa-pinterest-square:before { + content: "\f0d3"; } + +.fa-xing:before { + content: "\f168"; } + +.fa-blackberry:before { + content: "\f37b"; } + +.fa-creative-commons-pd:before { + content: "\f4ec"; } + +.fa-playstation:before { + content: "\f3df"; } + +.fa-quinscape:before { + content: "\f459"; } + +.fa-less:before { + content: "\f41d"; } + +.fa-blogger-b:before { + content: "\f37d"; } + +.fa-opencart:before { + content: "\f23d"; } + +.fa-vine:before { + content: "\f1ca"; } + +.fa-signal-messenger:before { + content: "\e663"; } + +.fa-paypal:before { + content: "\f1ed"; } + +.fa-gitlab:before { + content: "\f296"; } + +.fa-typo3:before { + content: "\f42b"; } + +.fa-reddit-alien:before { + content: "\f281"; } + +.fa-yahoo:before { + content: "\f19e"; } + +.fa-dailymotion:before { + content: "\e052"; } + +.fa-affiliatetheme:before { + content: "\f36b"; } + +.fa-pied-piper-pp:before { + content: "\f1a7"; } + +.fa-bootstrap:before { + content: "\f836"; } + +.fa-odnoklassniki:before { + content: "\f263"; } + +.fa-nfc-symbol:before { + content: "\e531"; } + +.fa-mintbit:before { + content: "\e62f"; } + +.fa-ethereum:before { + content: "\f42e"; } + +.fa-speaker-deck:before { + content: "\f83c"; } + +.fa-creative-commons-nc-eu:before { + content: "\f4e9"; } + +.fa-patreon:before { + content: "\f3d9"; } + +.fa-avianex:before { + content: "\f374"; } + +.fa-ello:before { + content: "\f5f1"; } + +.fa-gofore:before { + content: "\f3a7"; } + +.fa-bimobject:before { + content: "\f378"; } + +.fa-brave-reverse:before { + content: "\e63d"; } + +.fa-facebook-f:before { + content: "\f39e"; } + +.fa-square-google-plus:before { + content: "\f0d4"; } + +.fa-google-plus-square:before { + content: "\f0d4"; } + +.fa-web-awesome:before { + content: "\e682"; } + +.fa-mandalorian:before { + content: "\f50f"; } + +.fa-first-order-alt:before { + content: "\f50a"; } + +.fa-osi:before { + content: "\f41a"; } + +.fa-google-wallet:before { + content: "\f1ee"; } + +.fa-d-and-d-beyond:before { + content: "\f6ca"; } + +.fa-periscope:before { + content: "\f3da"; } + +.fa-fulcrum:before { + content: "\f50b"; } + +.fa-cloudscale:before { + content: "\f383"; } + +.fa-forumbee:before { + content: "\f211"; } + +.fa-mizuni:before { + content: "\f3cc"; } + +.fa-schlix:before { + content: "\f3ea"; } + +.fa-square-xing:before { + content: "\f169"; } + +.fa-xing-square:before { + content: "\f169"; } + +.fa-bandcamp:before { + content: "\f2d5"; } + +.fa-wpforms:before { + content: "\f298"; } + +.fa-cloudversify:before { + content: "\f385"; } + +.fa-usps:before { + content: "\f7e1"; } + +.fa-megaport:before { + content: "\f5a3"; } + +.fa-magento:before { + content: "\f3c4"; } + +.fa-spotify:before { + content: "\f1bc"; } + +.fa-optin-monster:before { + content: "\f23c"; } + +.fa-fly:before { + content: "\f417"; } + +.fa-aviato:before { + content: "\f421"; } + +.fa-itunes:before { + content: "\f3b4"; } + +.fa-cuttlefish:before { + content: "\f38c"; } + +.fa-blogger:before { + content: "\f37c"; } + +.fa-flickr:before { + content: "\f16e"; } + +.fa-viber:before { + content: "\f409"; } + +.fa-soundcloud:before { + content: "\f1be"; } + +.fa-digg:before { + content: "\f1a6"; } + +.fa-tencent-weibo:before { + content: "\f1d5"; } + +.fa-letterboxd:before { + content: "\e62d"; } + +.fa-symfony:before { + content: "\f83d"; } + +.fa-maxcdn:before { + content: "\f136"; } + +.fa-etsy:before { + content: "\f2d7"; } + +.fa-facebook-messenger:before { + content: "\f39f"; } + +.fa-audible:before { + content: "\f373"; } + +.fa-think-peaks:before { + content: "\f731"; } + +.fa-bilibili:before { + content: "\e3d9"; } + +.fa-erlang:before { + content: "\f39d"; } + +.fa-x-twitter:before { + content: "\e61b"; } + +.fa-cotton-bureau:before { + content: "\f89e"; } + +.fa-dashcube:before { + content: "\f210"; } + +.fa-42-group:before { + content: "\e080"; } + +.fa-innosoft:before { + content: "\e080"; } + +.fa-stack-exchange:before { + content: "\f18d"; } + +.fa-elementor:before { + content: "\f430"; } + +.fa-square-pied-piper:before { + content: "\e01e"; } + +.fa-pied-piper-square:before { + content: "\e01e"; } + +.fa-creative-commons-nd:before { + content: "\f4eb"; } + +.fa-palfed:before { + content: "\f3d8"; } + +.fa-superpowers:before { + content: "\f2dd"; } + +.fa-resolving:before { + content: "\f3e7"; } + +.fa-xbox:before { + content: "\f412"; } + +.fa-square-web-awesome-stroke:before { + content: "\e684"; } + +.fa-searchengin:before { + content: "\f3eb"; } + +.fa-tiktok:before { + content: "\e07b"; } + +.fa-square-facebook:before { + content: "\f082"; } + +.fa-facebook-square:before { + content: "\f082"; } + +.fa-renren:before { + content: "\f18b"; } + +.fa-linux:before { + content: "\f17c"; } + +.fa-glide:before { + content: "\f2a5"; } + +.fa-linkedin:before { + content: "\f08c"; } + +.fa-hubspot:before { + content: "\f3b2"; } + +.fa-deploydog:before { + content: "\f38e"; } + +.fa-twitch:before { + content: "\f1e8"; } + +.fa-ravelry:before { + content: "\f2d9"; } + +.fa-mixer:before { + content: "\e056"; } + +.fa-square-lastfm:before { + content: "\f203"; } + +.fa-lastfm-square:before { + content: "\f203"; } + +.fa-vimeo:before { + content: "\f40a"; } + +.fa-mendeley:before { + content: "\f7b3"; } + +.fa-uniregistry:before { + content: "\f404"; } + +.fa-figma:before { + content: "\f799"; } + +.fa-creative-commons-remix:before { + content: "\f4ee"; } + +.fa-cc-amazon-pay:before { + content: "\f42d"; } + +.fa-dropbox:before { + content: "\f16b"; } + +.fa-instagram:before { + content: "\f16d"; } + +.fa-cmplid:before { + content: "\e360"; } + +.fa-upwork:before { + content: "\e641"; } + +.fa-facebook:before { + content: "\f09a"; } + +.fa-gripfire:before { + content: "\f3ac"; } + +.fa-jedi-order:before { + content: "\f50e"; } + +.fa-uikit:before { + content: "\f403"; } + +.fa-fort-awesome-alt:before { + content: "\f3a3"; } + +.fa-phabricator:before { + content: "\f3db"; } + +.fa-ussunnah:before { + content: "\f407"; } + +.fa-earlybirds:before { + content: "\f39a"; } + +.fa-trade-federation:before { + content: "\f513"; } + +.fa-autoprefixer:before { + content: "\f41c"; } + +.fa-whatsapp:before { + content: "\f232"; } + +.fa-square-upwork:before { + content: "\e67c"; } + +.fa-slideshare:before { + content: "\f1e7"; } + +.fa-google-play:before { + content: "\f3ab"; } + +.fa-viadeo:before { + content: "\f2a9"; } + +.fa-line:before { + content: "\f3c0"; } + +.fa-google-drive:before { + content: "\f3aa"; } + +.fa-servicestack:before { + content: "\f3ec"; } + +.fa-simplybuilt:before { + content: "\f215"; } + +.fa-bitbucket:before { + content: "\f171"; } + +.fa-imdb:before { + content: "\f2d8"; } + +.fa-deezer:before { + content: "\e077"; } + +.fa-raspberry-pi:before { + content: "\f7bb"; } + +.fa-jira:before { + content: "\f7b1"; } + +.fa-docker:before { + content: "\f395"; } + +.fa-screenpal:before { + content: "\e570"; } + +.fa-bluetooth:before { + content: "\f293"; } + +.fa-gitter:before { + content: "\f426"; } + +.fa-d-and-d:before { + content: "\f38d"; } + +.fa-microblog:before { + content: "\e01a"; } + +.fa-cc-diners-club:before { + content: "\f24c"; } + +.fa-gg-circle:before { + content: "\f261"; } + +.fa-pied-piper-hat:before { + content: "\f4e5"; } + +.fa-kickstarter-k:before { + content: "\f3bc"; } + +.fa-yandex:before { + content: "\f413"; } + +.fa-readme:before { + content: "\f4d5"; } + +.fa-html5:before { + content: "\f13b"; } + +.fa-sellsy:before { + content: "\f213"; } + +.fa-square-web-awesome:before { + content: "\e683"; } + +.fa-sass:before { + content: "\f41e"; } + +.fa-wirsindhandwerk:before { + content: "\e2d0"; } + +.fa-wsh:before { + content: "\e2d0"; } + +.fa-buromobelexperte:before { + content: "\f37f"; } + +.fa-salesforce:before { + content: "\f83b"; } + +.fa-octopus-deploy:before { + content: "\e082"; } + +.fa-medapps:before { + content: "\f3c6"; } + +.fa-ns8:before { + content: "\f3d5"; } + +.fa-pinterest-p:before { + content: "\f231"; } + +.fa-apper:before { + content: "\f371"; } + +.fa-fort-awesome:before { + content: "\f286"; } + +.fa-waze:before { + content: "\f83f"; } + +.fa-bluesky:before { + content: "\e671"; } + +.fa-cc-jcb:before { + content: "\f24b"; } + +.fa-snapchat:before { + content: "\f2ab"; } + +.fa-snapchat-ghost:before { + content: "\f2ab"; } + +.fa-fantasy-flight-games:before { + content: "\f6dc"; } + +.fa-rust:before { + content: "\e07a"; } + +.fa-wix:before { + content: "\f5cf"; } + +.fa-square-behance:before { + content: "\f1b5"; } + +.fa-behance-square:before { + content: "\f1b5"; } + +.fa-supple:before { + content: "\f3f9"; } + +.fa-webflow:before { + content: "\e65c"; } + +.fa-rebel:before { + content: "\f1d0"; } + +.fa-css3:before { + content: "\f13c"; } + +.fa-staylinked:before { + content: "\f3f5"; } + +.fa-kaggle:before { + content: "\f5fa"; } + +.fa-space-awesome:before { + content: "\e5ac"; } + +.fa-deviantart:before { + content: "\f1bd"; } + +.fa-cpanel:before { + content: "\f388"; } + +.fa-goodreads-g:before { + content: "\f3a9"; } + +.fa-square-git:before { + content: "\f1d2"; } + +.fa-git-square:before { + content: "\f1d2"; } + +.fa-square-tumblr:before { + content: "\f174"; } + +.fa-tumblr-square:before { + content: "\f174"; } + +.fa-trello:before { + content: "\f181"; } + +.fa-creative-commons-nc-jp:before { + content: "\f4ea"; } + +.fa-get-pocket:before { + content: "\f265"; } + +.fa-perbyte:before { + content: "\e083"; } + +.fa-grunt:before { + content: "\f3ad"; } + +.fa-weebly:before { + content: "\f5cc"; } + +.fa-connectdevelop:before { + content: "\f20e"; } + +.fa-leanpub:before { + content: "\f212"; } + +.fa-black-tie:before { + content: "\f27e"; } + +.fa-themeco:before { + content: "\f5c6"; } + +.fa-python:before { + content: "\f3e2"; } + +.fa-android:before { + content: "\f17b"; } + +.fa-bots:before { + content: "\e340"; } + +.fa-free-code-camp:before { + content: "\f2c5"; } + +.fa-hornbill:before { + content: "\f592"; } + +.fa-js:before { + content: "\f3b8"; } + +.fa-ideal:before { + content: "\e013"; } + +.fa-git:before { + content: "\f1d3"; } + +.fa-dev:before { + content: "\f6cc"; } + +.fa-sketch:before { + content: "\f7c6"; } + +.fa-yandex-international:before { + content: "\f414"; } + +.fa-cc-amex:before { + content: "\f1f3"; } + +.fa-uber:before { + content: "\f402"; } + +.fa-github:before { + content: "\f09b"; } + +.fa-php:before { + content: "\f457"; } + +.fa-alipay:before { + content: "\f642"; } + +.fa-youtube:before { + content: "\f167"; } + +.fa-skyatlas:before { + content: "\f216"; } + +.fa-firefox-browser:before { + content: "\e007"; } + +.fa-replyd:before { + content: "\f3e6"; } + +.fa-suse:before { + content: "\f7d6"; } + +.fa-jenkins:before { + content: "\f3b6"; } + +.fa-twitter:before { + content: "\f099"; } + +.fa-rockrms:before { + content: "\f3e9"; } + +.fa-pinterest:before { + content: "\f0d2"; } + +.fa-buffer:before { + content: "\f837"; } + +.fa-npm:before { + content: "\f3d4"; } + +.fa-yammer:before { + content: "\f840"; } + +.fa-btc:before { + content: "\f15a"; } + +.fa-dribbble:before { + content: "\f17d"; } + +.fa-stumbleupon-circle:before { + content: "\f1a3"; } + +.fa-internet-explorer:before { + content: "\f26b"; } + +.fa-stubber:before { + content: "\e5c7"; } + +.fa-telegram:before { + content: "\f2c6"; } + +.fa-telegram-plane:before { + content: "\f2c6"; } + +.fa-old-republic:before { + content: "\f510"; } + +.fa-odysee:before { + content: "\e5c6"; } + +.fa-square-whatsapp:before { + content: "\f40c"; } + +.fa-whatsapp-square:before { + content: "\f40c"; } + +.fa-node-js:before { + content: "\f3d3"; } + +.fa-edge-legacy:before { + content: "\e078"; } + +.fa-slack:before { + content: "\f198"; } + +.fa-slack-hash:before { + content: "\f198"; } + +.fa-medrt:before { + content: "\f3c8"; } + +.fa-usb:before { + content: "\f287"; } + +.fa-tumblr:before { + content: "\f173"; } + +.fa-vaadin:before { + content: "\f408"; } + +.fa-quora:before { + content: "\f2c4"; } + +.fa-square-x-twitter:before { + content: "\e61a"; } + +.fa-reacteurope:before { + content: "\f75d"; } + +.fa-medium:before { + content: "\f23a"; } + +.fa-medium-m:before { + content: "\f23a"; } + +.fa-amilia:before { + content: "\f36d"; } + +.fa-mixcloud:before { + content: "\f289"; } + +.fa-flipboard:before { + content: "\f44d"; } + +.fa-viacoin:before { + content: "\f237"; } + +.fa-critical-role:before { + content: "\f6c9"; } + +.fa-sitrox:before { + content: "\e44a"; } + +.fa-discourse:before { + content: "\f393"; } + +.fa-joomla:before { + content: "\f1aa"; } + +.fa-mastodon:before { + content: "\f4f6"; } + +.fa-airbnb:before { + content: "\f834"; } + +.fa-wolf-pack-battalion:before { + content: "\f514"; } + +.fa-buy-n-large:before { + content: "\f8a6"; } + +.fa-gulp:before { + content: "\f3ae"; } + +.fa-creative-commons-sampling-plus:before { + content: "\f4f1"; } + +.fa-strava:before { + content: "\f428"; } + +.fa-ember:before { + content: "\f423"; } + +.fa-canadian-maple-leaf:before { + content: "\f785"; } + +.fa-teamspeak:before { + content: "\f4f9"; } + +.fa-pushed:before { + content: "\f3e1"; } + +.fa-wordpress-simple:before { + content: "\f411"; } + +.fa-nutritionix:before { + content: "\f3d6"; } + +.fa-wodu:before { + content: "\e088"; } + +.fa-google-pay:before { + content: "\e079"; } + +.fa-intercom:before { + content: "\f7af"; } + +.fa-zhihu:before { + content: "\f63f"; } + +.fa-korvue:before { + content: "\f42f"; } + +.fa-pix:before { + content: "\e43a"; } + +.fa-steam-symbol:before { + content: "\f3f6"; } +:root, :host { + --fa-style-family-classic: 'Font Awesome 6 Free'; + --fa-font-regular: normal 400 1em/1 'Font Awesome 6 Free'; } + +@font-face { + font-family: 'Font Awesome 6 Free'; + font-style: normal; + font-weight: 400; + font-display: block; + src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); } + +.far, +.fa-regular { + font-weight: 400; } +:root, :host { + --fa-style-family-classic: 'Font Awesome 6 Free'; + --fa-font-solid: normal 900 1em/1 'Font Awesome 6 Free'; } + +@font-face { + font-family: 'Font Awesome 6 Free'; + font-style: normal; + font-weight: 900; + font-display: block; + src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } + +.fas, +.fa-solid { + font-weight: 900; } +@font-face { + font-family: 'Font Awesome 5 Brands'; + font-display: block; + font-weight: 400; + src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); } + +@font-face { + font-family: 'Font Awesome 5 Free'; + font-display: block; + font-weight: 900; + src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } + +@font-face { + font-family: 'Font Awesome 5 Free'; + font-display: block; + font-weight: 400; + src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); } +@font-face { + font-family: 'FontAwesome'; + font-display: block; + src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } + +@font-face { + font-family: 'FontAwesome'; + font-display: block; + src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); } + +@font-face { + font-family: 'FontAwesome'; + font-display: block; + src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); } + +@font-face { + font-family: 'FontAwesome'; + font-display: block; + src: url("../webfonts/fa-v4compatibility.woff2") format("woff2"), url("../webfonts/fa-v4compatibility.ttf") format("truetype"); } diff --git a/docs/deps/font-awesome-6.5.2/css/all.min.css b/docs/deps/font-awesome-6.5.2/css/all.min.css new file mode 100644 index 00000000..269bceea --- /dev/null +++ b/docs/deps/font-awesome-6.5.2/css/all.min.css @@ -0,0 +1,9 @@ +/*! + * Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + * Copyright 2024 Fonticons, Inc. + */ +.fa{font-family:var(--fa-style-family,"Font Awesome 6 Free");font-weight:var(--fa-style,900)}.fa,.fa-brands,.fa-classic,.fa-regular,.fa-sharp,.fa-solid,.fab,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:var(--fa-display,inline-block);font-style:normal;font-variant:normal;line-height:1;text-rendering:auto}.fa-classic,.fa-regular,.fa-solid,.far,.fas{font-family:"Font Awesome 6 Free"}.fa-brands,.fab{font-family:"Font Awesome 6 Brands"}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-2xs{font-size:.625em;line-height:.1em;vertical-align:.225em}.fa-xs{font-size:.75em;line-height:.08333em;vertical-align:.125em}.fa-sm{font-size:.875em;line-height:.07143em;vertical-align:.05357em}.fa-lg{font-size:1.25em;line-height:.05em;vertical-align:-.075em}.fa-xl{font-size:1.5em;line-height:.04167em;vertical-align:-.125em}.fa-2xl{font-size:2em;line-height:.03125em;vertical-align:-.1875em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:var(--fa-li-margin,2.5em);padding-left:0}.fa-ul>li{position:relative}.fa-li{left:calc(var(--fa-li-width, 2em)*-1);position:absolute;text-align:center;width:var(--fa-li-width,2em);line-height:inherit}.fa-border{border-radius:var(--fa-border-radius,.1em);border:var(--fa-border-width,.08em) var(--fa-border-style,solid) var(--fa-border-color,#eee);padding:var(--fa-border-padding,.2em .25em .15em)}.fa-pull-left{float:left;margin-right:var(--fa-pull-margin,.3em)}.fa-pull-right{float:right;margin-left:var(--fa-pull-margin,.3em)}.fa-beat{-webkit-animation-name:fa-beat;animation-name:fa-beat;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,ease-in-out);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-bounce{-webkit-animation-name:fa-bounce;animation-name:fa-bounce;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1))}.fa-fade{-webkit-animation-name:fa-fade;animation-name:fa-fade;-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-beat-fade,.fa-fade{-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s)}.fa-beat-fade{-webkit-animation-name:fa-beat-fade;animation-name:fa-beat-fade;-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-flip{-webkit-animation-name:fa-flip;animation-name:fa-flip;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,ease-in-out);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-shake{-webkit-animation-name:fa-shake;animation-name:fa-shake;-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,linear);animation-timing-function:var(--fa-animation-timing,linear)}.fa-shake,.fa-spin{-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal)}.fa-spin{-webkit-animation-name:fa-spin;animation-name:fa-spin;-webkit-animation-duration:var(--fa-animation-duration,2s);animation-duration:var(--fa-animation-duration,2s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,linear);animation-timing-function:var(--fa-animation-timing,linear)}.fa-spin-reverse{--fa-animation-direction:reverse}.fa-pulse,.fa-spin-pulse{-webkit-animation-name:fa-spin;animation-name:fa-spin;-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,steps(8));animation-timing-function:var(--fa-animation-timing,steps(8))}@media (prefers-reduced-motion:reduce){.fa-beat,.fa-beat-fade,.fa-bounce,.fa-fade,.fa-flip,.fa-pulse,.fa-shake,.fa-spin,.fa-spin-pulse{-webkit-animation-delay:-1ms;animation-delay:-1ms;-webkit-animation-duration:1ms;animation-duration:1ms;-webkit-animation-iteration-count:1;animation-iteration-count:1;-webkit-transition-delay:0s;transition-delay:0s;-webkit-transition-duration:0s;transition-duration:0s}}@-webkit-keyframes fa-beat{0%,90%{-webkit-transform:scale(1);transform:scale(1)}45%{-webkit-transform:scale(var(--fa-beat-scale,1.25));transform:scale(var(--fa-beat-scale,1.25))}}@keyframes fa-beat{0%,90%{-webkit-transform:scale(1);transform:scale(1)}45%{-webkit-transform:scale(var(--fa-beat-scale,1.25));transform:scale(var(--fa-beat-scale,1.25))}}@-webkit-keyframes fa-bounce{0%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}10%{-webkit-transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0);transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{-webkit-transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em));transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{-webkit-transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0);transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{-webkit-transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em));transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em))}64%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}to{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}}@keyframes fa-bounce{0%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}10%{-webkit-transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0);transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{-webkit-transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em));transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{-webkit-transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0);transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{-webkit-transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em));transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em))}64%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}to{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}}@-webkit-keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@-webkit-keyframes fa-beat-fade{0%,to{opacity:var(--fa-beat-fade-opacity,.4);-webkit-transform:scale(1);transform:scale(1)}50%{opacity:1;-webkit-transform:scale(var(--fa-beat-fade-scale,1.125));transform:scale(var(--fa-beat-fade-scale,1.125))}}@keyframes fa-beat-fade{0%,to{opacity:var(--fa-beat-fade-opacity,.4);-webkit-transform:scale(1);transform:scale(1)}50%{opacity:1;-webkit-transform:scale(var(--fa-beat-fade-scale,1.125));transform:scale(var(--fa-beat-fade-scale,1.125))}}@-webkit-keyframes fa-flip{50%{-webkit-transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg));transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@keyframes fa-flip{50%{-webkit-transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg));transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@-webkit-keyframes fa-shake{0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}4%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}8%,24%{-webkit-transform:rotate(-18deg);transform:rotate(-18deg)}12%,28%{-webkit-transform:rotate(18deg);transform:rotate(18deg)}16%{-webkit-transform:rotate(-22deg);transform:rotate(-22deg)}20%{-webkit-transform:rotate(22deg);transform:rotate(22deg)}32%{-webkit-transform:rotate(-12deg);transform:rotate(-12deg)}36%{-webkit-transform:rotate(12deg);transform:rotate(12deg)}40%,to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@keyframes fa-shake{0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}4%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}8%,24%{-webkit-transform:rotate(-18deg);transform:rotate(-18deg)}12%,28%{-webkit-transform:rotate(18deg);transform:rotate(18deg)}16%{-webkit-transform:rotate(-22deg);transform:rotate(-22deg)}20%{-webkit-transform:rotate(22deg);transform:rotate(22deg)}32%{-webkit-transform:rotate(-12deg);transform:rotate(-12deg)}36%{-webkit-transform:rotate(12deg);transform:rotate(12deg)}40%,to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}.fa-rotate-by{-webkit-transform:rotate(var(--fa-rotate-angle,0));transform:rotate(var(--fa-rotate-angle,0))}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%;z-index:var(--fa-stack-z-index,auto)}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:var(--fa-inverse,#fff)} + +.fa-0:before{content:"\30"}.fa-1:before{content:"\31"}.fa-2:before{content:"\32"}.fa-3:before{content:"\33"}.fa-4:before{content:"\34"}.fa-5:before{content:"\35"}.fa-6:before{content:"\36"}.fa-7:before{content:"\37"}.fa-8:before{content:"\38"}.fa-9:before{content:"\39"}.fa-fill-drip:before{content:"\f576"}.fa-arrows-to-circle:before{content:"\e4bd"}.fa-chevron-circle-right:before,.fa-circle-chevron-right:before{content:"\f138"}.fa-at:before{content:"\40"}.fa-trash-alt:before,.fa-trash-can:before{content:"\f2ed"}.fa-text-height:before{content:"\f034"}.fa-user-times:before,.fa-user-xmark:before{content:"\f235"}.fa-stethoscope:before{content:"\f0f1"}.fa-comment-alt:before,.fa-message:before{content:"\f27a"}.fa-info:before{content:"\f129"}.fa-compress-alt:before,.fa-down-left-and-up-right-to-center:before{content:"\f422"}.fa-explosion:before{content:"\e4e9"}.fa-file-alt:before,.fa-file-lines:before,.fa-file-text:before{content:"\f15c"}.fa-wave-square:before{content:"\f83e"}.fa-ring:before{content:"\f70b"}.fa-building-un:before{content:"\e4d9"}.fa-dice-three:before{content:"\f527"}.fa-calendar-alt:before,.fa-calendar-days:before{content:"\f073"}.fa-anchor-circle-check:before{content:"\e4aa"}.fa-building-circle-arrow-right:before{content:"\e4d1"}.fa-volleyball-ball:before,.fa-volleyball:before{content:"\f45f"}.fa-arrows-up-to-line:before{content:"\e4c2"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-circle-minus:before,.fa-minus-circle:before{content:"\f056"}.fa-door-open:before{content:"\f52b"}.fa-right-from-bracket:before,.fa-sign-out-alt:before{content:"\f2f5"}.fa-atom:before{content:"\f5d2"}.fa-soap:before{content:"\e06e"}.fa-heart-music-camera-bolt:before,.fa-icons:before{content:"\f86d"}.fa-microphone-alt-slash:before,.fa-microphone-lines-slash:before{content:"\f539"}.fa-bridge-circle-check:before{content:"\e4c9"}.fa-pump-medical:before{content:"\e06a"}.fa-fingerprint:before{content:"\f577"}.fa-hand-point-right:before{content:"\f0a4"}.fa-magnifying-glass-location:before,.fa-search-location:before{content:"\f689"}.fa-forward-step:before,.fa-step-forward:before{content:"\f051"}.fa-face-smile-beam:before,.fa-smile-beam:before{content:"\f5b8"}.fa-flag-checkered:before{content:"\f11e"}.fa-football-ball:before,.fa-football:before{content:"\f44e"}.fa-school-circle-exclamation:before{content:"\e56c"}.fa-crop:before{content:"\f125"}.fa-angle-double-down:before,.fa-angles-down:before{content:"\f103"}.fa-users-rectangle:before{content:"\e594"}.fa-people-roof:before{content:"\e537"}.fa-people-line:before{content:"\e534"}.fa-beer-mug-empty:before,.fa-beer:before{content:"\f0fc"}.fa-diagram-predecessor:before{content:"\e477"}.fa-arrow-up-long:before,.fa-long-arrow-up:before{content:"\f176"}.fa-burn:before,.fa-fire-flame-simple:before{content:"\f46a"}.fa-male:before,.fa-person:before{content:"\f183"}.fa-laptop:before{content:"\f109"}.fa-file-csv:before{content:"\f6dd"}.fa-menorah:before{content:"\f676"}.fa-truck-plane:before{content:"\e58f"}.fa-record-vinyl:before{content:"\f8d9"}.fa-face-grin-stars:before,.fa-grin-stars:before{content:"\f587"}.fa-bong:before{content:"\f55c"}.fa-pastafarianism:before,.fa-spaghetti-monster-flying:before{content:"\f67b"}.fa-arrow-down-up-across-line:before{content:"\e4af"}.fa-spoon:before,.fa-utensil-spoon:before{content:"\f2e5"}.fa-jar-wheat:before{content:"\e517"}.fa-envelopes-bulk:before,.fa-mail-bulk:before{content:"\f674"}.fa-file-circle-exclamation:before{content:"\e4eb"}.fa-circle-h:before,.fa-hospital-symbol:before{content:"\f47e"}.fa-pager:before{content:"\f815"}.fa-address-book:before,.fa-contact-book:before{content:"\f2b9"}.fa-strikethrough:before{content:"\f0cc"}.fa-k:before{content:"\4b"}.fa-landmark-flag:before{content:"\e51c"}.fa-pencil-alt:before,.fa-pencil:before{content:"\f303"}.fa-backward:before{content:"\f04a"}.fa-caret-right:before{content:"\f0da"}.fa-comments:before{content:"\f086"}.fa-file-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-code-pull-request:before{content:"\e13c"}.fa-clipboard-list:before{content:"\f46d"}.fa-truck-loading:before,.fa-truck-ramp-box:before{content:"\f4de"}.fa-user-check:before{content:"\f4fc"}.fa-vial-virus:before{content:"\e597"}.fa-sheet-plastic:before{content:"\e571"}.fa-blog:before{content:"\f781"}.fa-user-ninja:before{content:"\f504"}.fa-person-arrow-up-from-line:before{content:"\e539"}.fa-scroll-torah:before,.fa-torah:before{content:"\f6a0"}.fa-broom-ball:before,.fa-quidditch-broom-ball:before,.fa-quidditch:before{content:"\f458"}.fa-toggle-off:before{content:"\f204"}.fa-archive:before,.fa-box-archive:before{content:"\f187"}.fa-person-drowning:before{content:"\e545"}.fa-arrow-down-9-1:before,.fa-sort-numeric-desc:before,.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-face-grin-tongue-squint:before,.fa-grin-tongue-squint:before{content:"\f58a"}.fa-spray-can:before{content:"\f5bd"}.fa-truck-monster:before{content:"\f63b"}.fa-w:before{content:"\57"}.fa-earth-africa:before,.fa-globe-africa:before{content:"\f57c"}.fa-rainbow:before{content:"\f75b"}.fa-circle-notch:before{content:"\f1ce"}.fa-tablet-alt:before,.fa-tablet-screen-button:before{content:"\f3fa"}.fa-paw:before{content:"\f1b0"}.fa-cloud:before{content:"\f0c2"}.fa-trowel-bricks:before{content:"\e58a"}.fa-face-flushed:before,.fa-flushed:before{content:"\f579"}.fa-hospital-user:before{content:"\f80d"}.fa-tent-arrow-left-right:before{content:"\e57f"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-binoculars:before{content:"\f1e5"}.fa-microphone-slash:before{content:"\f131"}.fa-box-tissue:before{content:"\e05b"}.fa-motorcycle:before{content:"\f21c"}.fa-bell-concierge:before,.fa-concierge-bell:before{content:"\f562"}.fa-pen-ruler:before,.fa-pencil-ruler:before{content:"\f5ae"}.fa-people-arrows-left-right:before,.fa-people-arrows:before{content:"\e068"}.fa-mars-and-venus-burst:before{content:"\e523"}.fa-caret-square-right:before,.fa-square-caret-right:before{content:"\f152"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-sun-plant-wilt:before{content:"\e57a"}.fa-toilets-portable:before{content:"\e584"}.fa-hockey-puck:before{content:"\f453"}.fa-table:before{content:"\f0ce"}.fa-magnifying-glass-arrow-right:before{content:"\e521"}.fa-digital-tachograph:before,.fa-tachograph-digital:before{content:"\f566"}.fa-users-slash:before{content:"\e073"}.fa-clover:before{content:"\e139"}.fa-mail-reply:before,.fa-reply:before{content:"\f3e5"}.fa-star-and-crescent:before{content:"\f699"}.fa-house-fire:before{content:"\e50c"}.fa-minus-square:before,.fa-square-minus:before{content:"\f146"}.fa-helicopter:before{content:"\f533"}.fa-compass:before{content:"\f14e"}.fa-caret-square-down:before,.fa-square-caret-down:before{content:"\f150"}.fa-file-circle-question:before{content:"\e4ef"}.fa-laptop-code:before{content:"\f5fc"}.fa-swatchbook:before{content:"\f5c3"}.fa-prescription-bottle:before{content:"\f485"}.fa-bars:before,.fa-navicon:before{content:"\f0c9"}.fa-people-group:before{content:"\e533"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-heart-broken:before,.fa-heart-crack:before{content:"\f7a9"}.fa-external-link-square-alt:before,.fa-square-up-right:before{content:"\f360"}.fa-face-kiss-beam:before,.fa-kiss-beam:before{content:"\f597"}.fa-film:before{content:"\f008"}.fa-ruler-horizontal:before{content:"\f547"}.fa-people-robbery:before{content:"\e536"}.fa-lightbulb:before{content:"\f0eb"}.fa-caret-left:before{content:"\f0d9"}.fa-circle-exclamation:before,.fa-exclamation-circle:before{content:"\f06a"}.fa-school-circle-xmark:before{content:"\e56d"}.fa-arrow-right-from-bracket:before,.fa-sign-out:before{content:"\f08b"}.fa-chevron-circle-down:before,.fa-circle-chevron-down:before{content:"\f13a"}.fa-unlock-alt:before,.fa-unlock-keyhole:before{content:"\f13e"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-headphones-alt:before,.fa-headphones-simple:before{content:"\f58f"}.fa-sitemap:before{content:"\f0e8"}.fa-circle-dollar-to-slot:before,.fa-donate:before{content:"\f4b9"}.fa-memory:before{content:"\f538"}.fa-road-spikes:before{content:"\e568"}.fa-fire-burner:before{content:"\e4f1"}.fa-flag:before{content:"\f024"}.fa-hanukiah:before{content:"\f6e6"}.fa-feather:before{content:"\f52d"}.fa-volume-down:before,.fa-volume-low:before{content:"\f027"}.fa-comment-slash:before{content:"\f4b3"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-compress:before{content:"\f066"}.fa-wheat-alt:before,.fa-wheat-awn:before{content:"\e2cd"}.fa-ankh:before{content:"\f644"}.fa-hands-holding-child:before{content:"\e4fa"}.fa-asterisk:before{content:"\2a"}.fa-check-square:before,.fa-square-check:before{content:"\f14a"}.fa-peseta-sign:before{content:"\e221"}.fa-header:before,.fa-heading:before{content:"\f1dc"}.fa-ghost:before{content:"\f6e2"}.fa-list-squares:before,.fa-list:before{content:"\f03a"}.fa-phone-square-alt:before,.fa-square-phone-flip:before{content:"\f87b"}.fa-cart-plus:before{content:"\f217"}.fa-gamepad:before{content:"\f11b"}.fa-circle-dot:before,.fa-dot-circle:before{content:"\f192"}.fa-dizzy:before,.fa-face-dizzy:before{content:"\f567"}.fa-egg:before{content:"\f7fb"}.fa-house-medical-circle-xmark:before{content:"\e513"}.fa-campground:before{content:"\f6bb"}.fa-folder-plus:before{content:"\f65e"}.fa-futbol-ball:before,.fa-futbol:before,.fa-soccer-ball:before{content:"\f1e3"}.fa-paint-brush:before,.fa-paintbrush:before{content:"\f1fc"}.fa-lock:before{content:"\f023"}.fa-gas-pump:before{content:"\f52f"}.fa-hot-tub-person:before,.fa-hot-tub:before{content:"\f593"}.fa-map-location:before,.fa-map-marked:before{content:"\f59f"}.fa-house-flood-water:before{content:"\e50e"}.fa-tree:before{content:"\f1bb"}.fa-bridge-lock:before{content:"\e4cc"}.fa-sack-dollar:before{content:"\f81d"}.fa-edit:before,.fa-pen-to-square:before{content:"\f044"}.fa-car-side:before{content:"\f5e4"}.fa-share-alt:before,.fa-share-nodes:before{content:"\f1e0"}.fa-heart-circle-minus:before{content:"\e4ff"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-microscope:before{content:"\f610"}.fa-sink:before{content:"\e06d"}.fa-bag-shopping:before,.fa-shopping-bag:before{content:"\f290"}.fa-arrow-down-z-a:before,.fa-sort-alpha-desc:before,.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-mitten:before{content:"\f7b5"}.fa-person-rays:before{content:"\e54d"}.fa-users:before{content:"\f0c0"}.fa-eye-slash:before{content:"\f070"}.fa-flask-vial:before{content:"\e4f3"}.fa-hand-paper:before,.fa-hand:before{content:"\f256"}.fa-om:before{content:"\f679"}.fa-worm:before{content:"\e599"}.fa-house-circle-xmark:before{content:"\e50b"}.fa-plug:before{content:"\f1e6"}.fa-chevron-up:before{content:"\f077"}.fa-hand-spock:before{content:"\f259"}.fa-stopwatch:before{content:"\f2f2"}.fa-face-kiss:before,.fa-kiss:before{content:"\f596"}.fa-bridge-circle-xmark:before{content:"\e4cb"}.fa-face-grin-tongue:before,.fa-grin-tongue:before{content:"\f589"}.fa-chess-bishop:before{content:"\f43a"}.fa-face-grin-wink:before,.fa-grin-wink:before{content:"\f58c"}.fa-deaf:before,.fa-deafness:before,.fa-ear-deaf:before,.fa-hard-of-hearing:before{content:"\f2a4"}.fa-road-circle-check:before{content:"\e564"}.fa-dice-five:before{content:"\f523"}.fa-rss-square:before,.fa-square-rss:before{content:"\f143"}.fa-land-mine-on:before{content:"\e51b"}.fa-i-cursor:before{content:"\f246"}.fa-stamp:before{content:"\f5bf"}.fa-stairs:before{content:"\e289"}.fa-i:before{content:"\49"}.fa-hryvnia-sign:before,.fa-hryvnia:before{content:"\f6f2"}.fa-pills:before{content:"\f484"}.fa-face-grin-wide:before,.fa-grin-alt:before{content:"\f581"}.fa-tooth:before{content:"\f5c9"}.fa-v:before{content:"\56"}.fa-bangladeshi-taka-sign:before{content:"\e2e6"}.fa-bicycle:before{content:"\f206"}.fa-rod-asclepius:before,.fa-rod-snake:before,.fa-staff-aesculapius:before,.fa-staff-snake:before{content:"\e579"}.fa-head-side-cough-slash:before{content:"\e062"}.fa-ambulance:before,.fa-truck-medical:before{content:"\f0f9"}.fa-wheat-awn-circle-exclamation:before{content:"\e598"}.fa-snowman:before{content:"\f7d0"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-road-barrier:before{content:"\e562"}.fa-school:before{content:"\f549"}.fa-igloo:before{content:"\f7ae"}.fa-joint:before{content:"\f595"}.fa-angle-right:before{content:"\f105"}.fa-horse:before{content:"\f6f0"}.fa-q:before{content:"\51"}.fa-g:before{content:"\47"}.fa-notes-medical:before{content:"\f481"}.fa-temperature-2:before,.fa-temperature-half:before,.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-dong-sign:before{content:"\e169"}.fa-capsules:before{content:"\f46b"}.fa-poo-bolt:before,.fa-poo-storm:before{content:"\f75a"}.fa-face-frown-open:before,.fa-frown-open:before{content:"\f57a"}.fa-hand-point-up:before{content:"\f0a6"}.fa-money-bill:before{content:"\f0d6"}.fa-bookmark:before{content:"\f02e"}.fa-align-justify:before{content:"\f039"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-helmet-un:before{content:"\e503"}.fa-bullseye:before{content:"\f140"}.fa-bacon:before{content:"\f7e5"}.fa-hand-point-down:before{content:"\f0a7"}.fa-arrow-up-from-bracket:before{content:"\e09a"}.fa-folder-blank:before,.fa-folder:before{content:"\f07b"}.fa-file-medical-alt:before,.fa-file-waveform:before{content:"\f478"}.fa-radiation:before{content:"\f7b9"}.fa-chart-simple:before{content:"\e473"}.fa-mars-stroke:before{content:"\f229"}.fa-vial:before{content:"\f492"}.fa-dashboard:before,.fa-gauge-med:before,.fa-gauge:before,.fa-tachometer-alt-average:before{content:"\f624"}.fa-magic-wand-sparkles:before,.fa-wand-magic-sparkles:before{content:"\e2ca"}.fa-e:before{content:"\45"}.fa-pen-alt:before,.fa-pen-clip:before{content:"\f305"}.fa-bridge-circle-exclamation:before{content:"\e4ca"}.fa-user:before{content:"\f007"}.fa-school-circle-check:before{content:"\e56b"}.fa-dumpster:before{content:"\f793"}.fa-shuttle-van:before,.fa-van-shuttle:before{content:"\f5b6"}.fa-building-user:before{content:"\e4da"}.fa-caret-square-left:before,.fa-square-caret-left:before{content:"\f191"}.fa-highlighter:before{content:"\f591"}.fa-key:before{content:"\f084"}.fa-bullhorn:before{content:"\f0a1"}.fa-globe:before{content:"\f0ac"}.fa-synagogue:before{content:"\f69b"}.fa-person-half-dress:before{content:"\e548"}.fa-road-bridge:before{content:"\e563"}.fa-location-arrow:before{content:"\f124"}.fa-c:before{content:"\43"}.fa-tablet-button:before{content:"\f10a"}.fa-building-lock:before{content:"\e4d6"}.fa-pizza-slice:before{content:"\f818"}.fa-money-bill-wave:before{content:"\f53a"}.fa-area-chart:before,.fa-chart-area:before{content:"\f1fe"}.fa-house-flag:before{content:"\e50d"}.fa-person-circle-minus:before{content:"\e540"}.fa-ban:before,.fa-cancel:before{content:"\f05e"}.fa-camera-rotate:before{content:"\e0d8"}.fa-air-freshener:before,.fa-spray-can-sparkles:before{content:"\f5d0"}.fa-star:before{content:"\f005"}.fa-repeat:before{content:"\f363"}.fa-cross:before{content:"\f654"}.fa-box:before{content:"\f466"}.fa-venus-mars:before{content:"\f228"}.fa-arrow-pointer:before,.fa-mouse-pointer:before{content:"\f245"}.fa-expand-arrows-alt:before,.fa-maximize:before{content:"\f31e"}.fa-charging-station:before{content:"\f5e7"}.fa-shapes:before,.fa-triangle-circle-square:before{content:"\f61f"}.fa-random:before,.fa-shuffle:before{content:"\f074"}.fa-person-running:before,.fa-running:before{content:"\f70c"}.fa-mobile-retro:before{content:"\e527"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-spider:before{content:"\f717"}.fa-hands-bound:before{content:"\e4f9"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-plane-circle-exclamation:before{content:"\e556"}.fa-x-ray:before{content:"\f497"}.fa-spell-check:before{content:"\f891"}.fa-slash:before{content:"\f715"}.fa-computer-mouse:before,.fa-mouse:before{content:"\f8cc"}.fa-arrow-right-to-bracket:before,.fa-sign-in:before{content:"\f090"}.fa-shop-slash:before,.fa-store-alt-slash:before{content:"\e070"}.fa-server:before{content:"\f233"}.fa-virus-covid-slash:before{content:"\e4a9"}.fa-shop-lock:before{content:"\e4a5"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-blender-phone:before{content:"\f6b6"}.fa-building-wheat:before{content:"\e4db"}.fa-person-breastfeeding:before{content:"\e53a"}.fa-right-to-bracket:before,.fa-sign-in-alt:before{content:"\f2f6"}.fa-venus:before{content:"\f221"}.fa-passport:before{content:"\f5ab"}.fa-heart-pulse:before,.fa-heartbeat:before{content:"\f21e"}.fa-people-carry-box:before,.fa-people-carry:before{content:"\f4ce"}.fa-temperature-high:before{content:"\f769"}.fa-microchip:before{content:"\f2db"}.fa-crown:before{content:"\f521"}.fa-weight-hanging:before{content:"\f5cd"}.fa-xmarks-lines:before{content:"\e59a"}.fa-file-prescription:before{content:"\f572"}.fa-weight-scale:before,.fa-weight:before{content:"\f496"}.fa-user-friends:before,.fa-user-group:before{content:"\f500"}.fa-arrow-up-a-z:before,.fa-sort-alpha-up:before{content:"\f15e"}.fa-chess-knight:before{content:"\f441"}.fa-face-laugh-squint:before,.fa-laugh-squint:before{content:"\f59b"}.fa-wheelchair:before{content:"\f193"}.fa-arrow-circle-up:before,.fa-circle-arrow-up:before{content:"\f0aa"}.fa-toggle-on:before{content:"\f205"}.fa-person-walking:before,.fa-walking:before{content:"\f554"}.fa-l:before{content:"\4c"}.fa-fire:before{content:"\f06d"}.fa-bed-pulse:before,.fa-procedures:before{content:"\f487"}.fa-shuttle-space:before,.fa-space-shuttle:before{content:"\f197"}.fa-face-laugh:before,.fa-laugh:before{content:"\f599"}.fa-folder-open:before{content:"\f07c"}.fa-heart-circle-plus:before{content:"\e500"}.fa-code-fork:before{content:"\e13b"}.fa-city:before{content:"\f64f"}.fa-microphone-alt:before,.fa-microphone-lines:before{content:"\f3c9"}.fa-pepper-hot:before{content:"\f816"}.fa-unlock:before{content:"\f09c"}.fa-colon-sign:before{content:"\e140"}.fa-headset:before{content:"\f590"}.fa-store-slash:before{content:"\e071"}.fa-road-circle-xmark:before{content:"\e566"}.fa-user-minus:before{content:"\f503"}.fa-mars-stroke-up:before,.fa-mars-stroke-v:before{content:"\f22a"}.fa-champagne-glasses:before,.fa-glass-cheers:before{content:"\f79f"}.fa-clipboard:before{content:"\f328"}.fa-house-circle-exclamation:before{content:"\e50a"}.fa-file-arrow-up:before,.fa-file-upload:before{content:"\f574"}.fa-wifi-3:before,.fa-wifi-strong:before,.fa-wifi:before{content:"\f1eb"}.fa-bath:before,.fa-bathtub:before{content:"\f2cd"}.fa-underline:before{content:"\f0cd"}.fa-user-edit:before,.fa-user-pen:before{content:"\f4ff"}.fa-signature:before{content:"\f5b7"}.fa-stroopwafel:before{content:"\f551"}.fa-bold:before{content:"\f032"}.fa-anchor-lock:before{content:"\e4ad"}.fa-building-ngo:before{content:"\e4d7"}.fa-manat-sign:before{content:"\e1d5"}.fa-not-equal:before{content:"\f53e"}.fa-border-style:before,.fa-border-top-left:before{content:"\f853"}.fa-map-location-dot:before,.fa-map-marked-alt:before{content:"\f5a0"}.fa-jedi:before{content:"\f669"}.fa-poll:before,.fa-square-poll-vertical:before{content:"\f681"}.fa-mug-hot:before{content:"\f7b6"}.fa-battery-car:before,.fa-car-battery:before{content:"\f5df"}.fa-gift:before{content:"\f06b"}.fa-dice-two:before{content:"\f528"}.fa-chess-queen:before{content:"\f445"}.fa-glasses:before{content:"\f530"}.fa-chess-board:before{content:"\f43c"}.fa-building-circle-check:before{content:"\e4d2"}.fa-person-chalkboard:before{content:"\e53d"}.fa-mars-stroke-h:before,.fa-mars-stroke-right:before{content:"\f22b"}.fa-hand-back-fist:before,.fa-hand-rock:before{content:"\f255"}.fa-caret-square-up:before,.fa-square-caret-up:before{content:"\f151"}.fa-cloud-showers-water:before{content:"\e4e4"}.fa-bar-chart:before,.fa-chart-bar:before{content:"\f080"}.fa-hands-bubbles:before,.fa-hands-wash:before{content:"\e05e"}.fa-less-than-equal:before{content:"\f537"}.fa-train:before{content:"\f238"}.fa-eye-low-vision:before,.fa-low-vision:before{content:"\f2a8"}.fa-crow:before{content:"\f520"}.fa-sailboat:before{content:"\e445"}.fa-window-restore:before{content:"\f2d2"}.fa-plus-square:before,.fa-square-plus:before{content:"\f0fe"}.fa-torii-gate:before{content:"\f6a1"}.fa-frog:before{content:"\f52e"}.fa-bucket:before{content:"\e4cf"}.fa-image:before{content:"\f03e"}.fa-microphone:before{content:"\f130"}.fa-cow:before{content:"\f6c8"}.fa-caret-up:before{content:"\f0d8"}.fa-screwdriver:before{content:"\f54a"}.fa-folder-closed:before{content:"\e185"}.fa-house-tsunami:before{content:"\e515"}.fa-square-nfi:before{content:"\e576"}.fa-arrow-up-from-ground-water:before{content:"\e4b5"}.fa-glass-martini-alt:before,.fa-martini-glass:before{content:"\f57b"}.fa-rotate-back:before,.fa-rotate-backward:before,.fa-rotate-left:before,.fa-undo-alt:before{content:"\f2ea"}.fa-columns:before,.fa-table-columns:before{content:"\f0db"}.fa-lemon:before{content:"\f094"}.fa-head-side-mask:before{content:"\e063"}.fa-handshake:before{content:"\f2b5"}.fa-gem:before{content:"\f3a5"}.fa-dolly-box:before,.fa-dolly:before{content:"\f472"}.fa-smoking:before{content:"\f48d"}.fa-compress-arrows-alt:before,.fa-minimize:before{content:"\f78c"}.fa-monument:before{content:"\f5a6"}.fa-snowplow:before{content:"\f7d2"}.fa-angle-double-right:before,.fa-angles-right:before{content:"\f101"}.fa-cannabis:before{content:"\f55f"}.fa-circle-play:before,.fa-play-circle:before{content:"\f144"}.fa-tablets:before{content:"\f490"}.fa-ethernet:before{content:"\f796"}.fa-eur:before,.fa-euro-sign:before,.fa-euro:before{content:"\f153"}.fa-chair:before{content:"\f6c0"}.fa-check-circle:before,.fa-circle-check:before{content:"\f058"}.fa-circle-stop:before,.fa-stop-circle:before{content:"\f28d"}.fa-compass-drafting:before,.fa-drafting-compass:before{content:"\f568"}.fa-plate-wheat:before{content:"\e55a"}.fa-icicles:before{content:"\f7ad"}.fa-person-shelter:before{content:"\e54f"}.fa-neuter:before{content:"\f22c"}.fa-id-badge:before{content:"\f2c1"}.fa-marker:before{content:"\f5a1"}.fa-face-laugh-beam:before,.fa-laugh-beam:before{content:"\f59a"}.fa-helicopter-symbol:before{content:"\e502"}.fa-universal-access:before{content:"\f29a"}.fa-chevron-circle-up:before,.fa-circle-chevron-up:before{content:"\f139"}.fa-lari-sign:before{content:"\e1c8"}.fa-volcano:before{content:"\f770"}.fa-person-walking-dashed-line-arrow-right:before{content:"\e553"}.fa-gbp:before,.fa-pound-sign:before,.fa-sterling-sign:before{content:"\f154"}.fa-viruses:before{content:"\e076"}.fa-square-person-confined:before{content:"\e577"}.fa-user-tie:before{content:"\f508"}.fa-arrow-down-long:before,.fa-long-arrow-down:before{content:"\f175"}.fa-tent-arrow-down-to-line:before{content:"\e57e"}.fa-certificate:before{content:"\f0a3"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-suitcase:before{content:"\f0f2"}.fa-person-skating:before,.fa-skating:before{content:"\f7c5"}.fa-filter-circle-dollar:before,.fa-funnel-dollar:before{content:"\f662"}.fa-camera-retro:before{content:"\f083"}.fa-arrow-circle-down:before,.fa-circle-arrow-down:before{content:"\f0ab"}.fa-arrow-right-to-file:before,.fa-file-import:before{content:"\f56f"}.fa-external-link-square:before,.fa-square-arrow-up-right:before{content:"\f14c"}.fa-box-open:before{content:"\f49e"}.fa-scroll:before{content:"\f70e"}.fa-spa:before{content:"\f5bb"}.fa-location-pin-lock:before{content:"\e51f"}.fa-pause:before{content:"\f04c"}.fa-hill-avalanche:before{content:"\e507"}.fa-temperature-0:before,.fa-temperature-empty:before,.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-bomb:before{content:"\f1e2"}.fa-registered:before{content:"\f25d"}.fa-address-card:before,.fa-contact-card:before,.fa-vcard:before{content:"\f2bb"}.fa-balance-scale-right:before,.fa-scale-unbalanced-flip:before{content:"\f516"}.fa-subscript:before{content:"\f12c"}.fa-diamond-turn-right:before,.fa-directions:before{content:"\f5eb"}.fa-burst:before{content:"\e4dc"}.fa-house-laptop:before,.fa-laptop-house:before{content:"\e066"}.fa-face-tired:before,.fa-tired:before{content:"\f5c8"}.fa-money-bills:before{content:"\e1f3"}.fa-smog:before{content:"\f75f"}.fa-crutch:before{content:"\f7f7"}.fa-cloud-arrow-up:before,.fa-cloud-upload-alt:before,.fa-cloud-upload:before{content:"\f0ee"}.fa-palette:before{content:"\f53f"}.fa-arrows-turn-right:before{content:"\e4c0"}.fa-vest:before{content:"\e085"}.fa-ferry:before{content:"\e4ea"}.fa-arrows-down-to-people:before{content:"\e4b9"}.fa-seedling:before,.fa-sprout:before{content:"\f4d8"}.fa-arrows-alt-h:before,.fa-left-right:before{content:"\f337"}.fa-boxes-packing:before{content:"\e4c7"}.fa-arrow-circle-left:before,.fa-circle-arrow-left:before{content:"\f0a8"}.fa-group-arrows-rotate:before{content:"\e4f6"}.fa-bowl-food:before{content:"\e4c6"}.fa-candy-cane:before{content:"\f786"}.fa-arrow-down-wide-short:before,.fa-sort-amount-asc:before,.fa-sort-amount-down:before{content:"\f160"}.fa-cloud-bolt:before,.fa-thunderstorm:before{content:"\f76c"}.fa-remove-format:before,.fa-text-slash:before{content:"\f87d"}.fa-face-smile-wink:before,.fa-smile-wink:before{content:"\f4da"}.fa-file-word:before{content:"\f1c2"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-arrows-h:before,.fa-arrows-left-right:before{content:"\f07e"}.fa-house-lock:before{content:"\e510"}.fa-cloud-arrow-down:before,.fa-cloud-download-alt:before,.fa-cloud-download:before{content:"\f0ed"}.fa-children:before{content:"\e4e1"}.fa-blackboard:before,.fa-chalkboard:before{content:"\f51b"}.fa-user-alt-slash:before,.fa-user-large-slash:before{content:"\f4fa"}.fa-envelope-open:before{content:"\f2b6"}.fa-handshake-alt-slash:before,.fa-handshake-simple-slash:before{content:"\e05f"}.fa-mattress-pillow:before{content:"\e525"}.fa-guarani-sign:before{content:"\e19a"}.fa-arrows-rotate:before,.fa-refresh:before,.fa-sync:before{content:"\f021"}.fa-fire-extinguisher:before{content:"\f134"}.fa-cruzeiro-sign:before{content:"\e152"}.fa-greater-than-equal:before{content:"\f532"}.fa-shield-alt:before,.fa-shield-halved:before{content:"\f3ed"}.fa-atlas:before,.fa-book-atlas:before{content:"\f558"}.fa-virus:before{content:"\e074"}.fa-envelope-circle-check:before{content:"\e4e8"}.fa-layer-group:before{content:"\f5fd"}.fa-arrows-to-dot:before{content:"\e4be"}.fa-archway:before{content:"\f557"}.fa-heart-circle-check:before{content:"\e4fd"}.fa-house-chimney-crack:before,.fa-house-damage:before{content:"\f6f1"}.fa-file-archive:before,.fa-file-zipper:before{content:"\f1c6"}.fa-square:before{content:"\f0c8"}.fa-glass-martini:before,.fa-martini-glass-empty:before{content:"\f000"}.fa-couch:before{content:"\f4b8"}.fa-cedi-sign:before{content:"\e0df"}.fa-italic:before{content:"\f033"}.fa-table-cells-column-lock:before{content:"\e678"}.fa-church:before{content:"\f51d"}.fa-comments-dollar:before{content:"\f653"}.fa-democrat:before{content:"\f747"}.fa-z:before{content:"\5a"}.fa-person-skiing:before,.fa-skiing:before{content:"\f7c9"}.fa-road-lock:before{content:"\e567"}.fa-a:before{content:"\41"}.fa-temperature-arrow-down:before,.fa-temperature-down:before{content:"\e03f"}.fa-feather-alt:before,.fa-feather-pointed:before{content:"\f56b"}.fa-p:before{content:"\50"}.fa-snowflake:before{content:"\f2dc"}.fa-newspaper:before{content:"\f1ea"}.fa-ad:before,.fa-rectangle-ad:before{content:"\f641"}.fa-arrow-circle-right:before,.fa-circle-arrow-right:before{content:"\f0a9"}.fa-filter-circle-xmark:before{content:"\e17b"}.fa-locust:before{content:"\e520"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-list-1-2:before,.fa-list-numeric:before,.fa-list-ol:before{content:"\f0cb"}.fa-person-dress-burst:before{content:"\e544"}.fa-money-check-alt:before,.fa-money-check-dollar:before{content:"\f53d"}.fa-vector-square:before{content:"\f5cb"}.fa-bread-slice:before{content:"\f7ec"}.fa-language:before{content:"\f1ab"}.fa-face-kiss-wink-heart:before,.fa-kiss-wink-heart:before{content:"\f598"}.fa-filter:before{content:"\f0b0"}.fa-question:before{content:"\3f"}.fa-file-signature:before{content:"\f573"}.fa-arrows-alt:before,.fa-up-down-left-right:before{content:"\f0b2"}.fa-house-chimney-user:before{content:"\e065"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-puzzle-piece:before{content:"\f12e"}.fa-money-check:before{content:"\f53c"}.fa-star-half-alt:before,.fa-star-half-stroke:before{content:"\f5c0"}.fa-code:before{content:"\f121"}.fa-glass-whiskey:before,.fa-whiskey-glass:before{content:"\f7a0"}.fa-building-circle-exclamation:before{content:"\e4d3"}.fa-magnifying-glass-chart:before{content:"\e522"}.fa-arrow-up-right-from-square:before,.fa-external-link:before{content:"\f08e"}.fa-cubes-stacked:before{content:"\e4e6"}.fa-krw:before,.fa-won-sign:before,.fa-won:before{content:"\f159"}.fa-virus-covid:before{content:"\e4a8"}.fa-austral-sign:before{content:"\e0a9"}.fa-f:before{content:"\46"}.fa-leaf:before{content:"\f06c"}.fa-road:before{content:"\f018"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-person-circle-plus:before{content:"\e541"}.fa-chart-pie:before,.fa-pie-chart:before{content:"\f200"}.fa-bolt-lightning:before{content:"\e0b7"}.fa-sack-xmark:before{content:"\e56a"}.fa-file-excel:before{content:"\f1c3"}.fa-file-contract:before{content:"\f56c"}.fa-fish-fins:before{content:"\e4f2"}.fa-building-flag:before{content:"\e4d5"}.fa-face-grin-beam:before,.fa-grin-beam:before{content:"\f582"}.fa-object-ungroup:before{content:"\f248"}.fa-poop:before{content:"\f619"}.fa-location-pin:before,.fa-map-marker:before{content:"\f041"}.fa-kaaba:before{content:"\f66b"}.fa-toilet-paper:before{content:"\f71e"}.fa-hard-hat:before,.fa-hat-hard:before,.fa-helmet-safety:before{content:"\f807"}.fa-eject:before{content:"\f052"}.fa-arrow-alt-circle-right:before,.fa-circle-right:before{content:"\f35a"}.fa-plane-circle-check:before{content:"\e555"}.fa-face-rolling-eyes:before,.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-object-group:before{content:"\f247"}.fa-chart-line:before,.fa-line-chart:before{content:"\f201"}.fa-mask-ventilator:before{content:"\e524"}.fa-arrow-right:before{content:"\f061"}.fa-map-signs:before,.fa-signs-post:before{content:"\f277"}.fa-cash-register:before{content:"\f788"}.fa-person-circle-question:before{content:"\e542"}.fa-h:before{content:"\48"}.fa-tarp:before{content:"\e57b"}.fa-screwdriver-wrench:before,.fa-tools:before{content:"\f7d9"}.fa-arrows-to-eye:before{content:"\e4bf"}.fa-plug-circle-bolt:before{content:"\e55b"}.fa-heart:before{content:"\f004"}.fa-mars-and-venus:before{content:"\f224"}.fa-home-user:before,.fa-house-user:before{content:"\e1b0"}.fa-dumpster-fire:before{content:"\f794"}.fa-house-crack:before{content:"\e3b1"}.fa-cocktail:before,.fa-martini-glass-citrus:before{content:"\f561"}.fa-face-surprise:before,.fa-surprise:before{content:"\f5c2"}.fa-bottle-water:before{content:"\e4c5"}.fa-circle-pause:before,.fa-pause-circle:before{content:"\f28b"}.fa-toilet-paper-slash:before{content:"\e072"}.fa-apple-alt:before,.fa-apple-whole:before{content:"\f5d1"}.fa-kitchen-set:before{content:"\e51a"}.fa-r:before{content:"\52"}.fa-temperature-1:before,.fa-temperature-quarter:before,.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-cube:before{content:"\f1b2"}.fa-bitcoin-sign:before{content:"\e0b4"}.fa-shield-dog:before{content:"\e573"}.fa-solar-panel:before{content:"\f5ba"}.fa-lock-open:before{content:"\f3c1"}.fa-elevator:before{content:"\e16d"}.fa-money-bill-transfer:before{content:"\e528"}.fa-money-bill-trend-up:before{content:"\e529"}.fa-house-flood-water-circle-arrow-right:before{content:"\e50f"}.fa-poll-h:before,.fa-square-poll-horizontal:before{content:"\f682"}.fa-circle:before{content:"\f111"}.fa-backward-fast:before,.fa-fast-backward:before{content:"\f049"}.fa-recycle:before{content:"\f1b8"}.fa-user-astronaut:before{content:"\f4fb"}.fa-plane-slash:before{content:"\e069"}.fa-trademark:before{content:"\f25c"}.fa-basketball-ball:before,.fa-basketball:before{content:"\f434"}.fa-satellite-dish:before{content:"\f7c0"}.fa-arrow-alt-circle-up:before,.fa-circle-up:before{content:"\f35b"}.fa-mobile-alt:before,.fa-mobile-screen-button:before{content:"\f3cd"}.fa-volume-high:before,.fa-volume-up:before{content:"\f028"}.fa-users-rays:before{content:"\e593"}.fa-wallet:before{content:"\f555"}.fa-clipboard-check:before{content:"\f46c"}.fa-file-audio:before{content:"\f1c7"}.fa-burger:before,.fa-hamburger:before{content:"\f805"}.fa-wrench:before{content:"\f0ad"}.fa-bugs:before{content:"\e4d0"}.fa-rupee-sign:before,.fa-rupee:before{content:"\f156"}.fa-file-image:before{content:"\f1c5"}.fa-circle-question:before,.fa-question-circle:before{content:"\f059"}.fa-plane-departure:before{content:"\f5b0"}.fa-handshake-slash:before{content:"\e060"}.fa-book-bookmark:before{content:"\e0bb"}.fa-code-branch:before{content:"\f126"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-bridge:before{content:"\e4c8"}.fa-phone-alt:before,.fa-phone-flip:before{content:"\f879"}.fa-truck-front:before{content:"\e2b7"}.fa-cat:before{content:"\f6be"}.fa-anchor-circle-exclamation:before{content:"\e4ab"}.fa-truck-field:before{content:"\e58d"}.fa-route:before{content:"\f4d7"}.fa-clipboard-question:before{content:"\e4e3"}.fa-panorama:before{content:"\e209"}.fa-comment-medical:before{content:"\f7f5"}.fa-teeth-open:before{content:"\f62f"}.fa-file-circle-minus:before{content:"\e4ed"}.fa-tags:before{content:"\f02c"}.fa-wine-glass:before{content:"\f4e3"}.fa-fast-forward:before,.fa-forward-fast:before{content:"\f050"}.fa-face-meh-blank:before,.fa-meh-blank:before{content:"\f5a4"}.fa-parking:before,.fa-square-parking:before{content:"\f540"}.fa-house-signal:before{content:"\e012"}.fa-bars-progress:before,.fa-tasks-alt:before{content:"\f828"}.fa-faucet-drip:before{content:"\e006"}.fa-cart-flatbed:before,.fa-dolly-flatbed:before{content:"\f474"}.fa-ban-smoking:before,.fa-smoking-ban:before{content:"\f54d"}.fa-terminal:before{content:"\f120"}.fa-mobile-button:before{content:"\f10b"}.fa-house-medical-flag:before{content:"\e514"}.fa-basket-shopping:before,.fa-shopping-basket:before{content:"\f291"}.fa-tape:before{content:"\f4db"}.fa-bus-alt:before,.fa-bus-simple:before{content:"\f55e"}.fa-eye:before{content:"\f06e"}.fa-face-sad-cry:before,.fa-sad-cry:before{content:"\f5b3"}.fa-audio-description:before{content:"\f29e"}.fa-person-military-to-person:before{content:"\e54c"}.fa-file-shield:before{content:"\e4f0"}.fa-user-slash:before{content:"\f506"}.fa-pen:before{content:"\f304"}.fa-tower-observation:before{content:"\e586"}.fa-file-code:before{content:"\f1c9"}.fa-signal-5:before,.fa-signal-perfect:before,.fa-signal:before{content:"\f012"}.fa-bus:before{content:"\f207"}.fa-heart-circle-xmark:before{content:"\e501"}.fa-home-lg:before,.fa-house-chimney:before{content:"\e3af"}.fa-window-maximize:before{content:"\f2d0"}.fa-face-frown:before,.fa-frown:before{content:"\f119"}.fa-prescription:before{content:"\f5b1"}.fa-shop:before,.fa-store-alt:before{content:"\f54f"}.fa-floppy-disk:before,.fa-save:before{content:"\f0c7"}.fa-vihara:before{content:"\f6a7"}.fa-balance-scale-left:before,.fa-scale-unbalanced:before{content:"\f515"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-comment-dots:before,.fa-commenting:before{content:"\f4ad"}.fa-plant-wilt:before{content:"\e5aa"}.fa-diamond:before{content:"\f219"}.fa-face-grin-squint:before,.fa-grin-squint:before{content:"\f585"}.fa-hand-holding-dollar:before,.fa-hand-holding-usd:before{content:"\f4c0"}.fa-bacterium:before{content:"\e05a"}.fa-hand-pointer:before{content:"\f25a"}.fa-drum-steelpan:before{content:"\f56a"}.fa-hand-scissors:before{content:"\f257"}.fa-hands-praying:before,.fa-praying-hands:before{content:"\f684"}.fa-arrow-right-rotate:before,.fa-arrow-rotate-forward:before,.fa-arrow-rotate-right:before,.fa-redo:before{content:"\f01e"}.fa-biohazard:before{content:"\f780"}.fa-location-crosshairs:before,.fa-location:before{content:"\f601"}.fa-mars-double:before{content:"\f227"}.fa-child-dress:before{content:"\e59c"}.fa-users-between-lines:before{content:"\e591"}.fa-lungs-virus:before{content:"\e067"}.fa-face-grin-tears:before,.fa-grin-tears:before{content:"\f588"}.fa-phone:before{content:"\f095"}.fa-calendar-times:before,.fa-calendar-xmark:before{content:"\f273"}.fa-child-reaching:before{content:"\e59d"}.fa-head-side-virus:before{content:"\e064"}.fa-user-cog:before,.fa-user-gear:before{content:"\f4fe"}.fa-arrow-up-1-9:before,.fa-sort-numeric-up:before{content:"\f163"}.fa-door-closed:before{content:"\f52a"}.fa-shield-virus:before{content:"\e06c"}.fa-dice-six:before{content:"\f526"}.fa-mosquito-net:before{content:"\e52c"}.fa-bridge-water:before{content:"\e4ce"}.fa-person-booth:before{content:"\f756"}.fa-text-width:before{content:"\f035"}.fa-hat-wizard:before{content:"\f6e8"}.fa-pen-fancy:before{content:"\f5ac"}.fa-digging:before,.fa-person-digging:before{content:"\f85e"}.fa-trash:before{content:"\f1f8"}.fa-gauge-simple-med:before,.fa-gauge-simple:before,.fa-tachometer-average:before{content:"\f629"}.fa-book-medical:before{content:"\f7e6"}.fa-poo:before{content:"\f2fe"}.fa-quote-right-alt:before,.fa-quote-right:before{content:"\f10e"}.fa-shirt:before,.fa-t-shirt:before,.fa-tshirt:before{content:"\f553"}.fa-cubes:before{content:"\f1b3"}.fa-divide:before{content:"\f529"}.fa-tenge-sign:before,.fa-tenge:before{content:"\f7d7"}.fa-headphones:before{content:"\f025"}.fa-hands-holding:before{content:"\f4c2"}.fa-hands-clapping:before{content:"\e1a8"}.fa-republican:before{content:"\f75e"}.fa-arrow-left:before{content:"\f060"}.fa-person-circle-xmark:before{content:"\e543"}.fa-ruler:before{content:"\f545"}.fa-align-left:before{content:"\f036"}.fa-dice-d6:before{content:"\f6d1"}.fa-restroom:before{content:"\f7bd"}.fa-j:before{content:"\4a"}.fa-users-viewfinder:before{content:"\e595"}.fa-file-video:before{content:"\f1c8"}.fa-external-link-alt:before,.fa-up-right-from-square:before{content:"\f35d"}.fa-table-cells:before,.fa-th:before{content:"\f00a"}.fa-file-pdf:before{content:"\f1c1"}.fa-bible:before,.fa-book-bible:before{content:"\f647"}.fa-o:before{content:"\4f"}.fa-medkit:before,.fa-suitcase-medical:before{content:"\f0fa"}.fa-user-secret:before{content:"\f21b"}.fa-otter:before{content:"\f700"}.fa-female:before,.fa-person-dress:before{content:"\f182"}.fa-comment-dollar:before{content:"\f651"}.fa-briefcase-clock:before,.fa-business-time:before{content:"\f64a"}.fa-table-cells-large:before,.fa-th-large:before{content:"\f009"}.fa-book-tanakh:before,.fa-tanakh:before{content:"\f827"}.fa-phone-volume:before,.fa-volume-control-phone:before{content:"\f2a0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-clipboard-user:before{content:"\f7f3"}.fa-child:before{content:"\f1ae"}.fa-lira-sign:before{content:"\f195"}.fa-satellite:before{content:"\f7bf"}.fa-plane-lock:before{content:"\e558"}.fa-tag:before{content:"\f02b"}.fa-comment:before{content:"\f075"}.fa-birthday-cake:before,.fa-cake-candles:before,.fa-cake:before{content:"\f1fd"}.fa-envelope:before{content:"\f0e0"}.fa-angle-double-up:before,.fa-angles-up:before{content:"\f102"}.fa-paperclip:before{content:"\f0c6"}.fa-arrow-right-to-city:before{content:"\e4b3"}.fa-ribbon:before{content:"\f4d6"}.fa-lungs:before{content:"\f604"}.fa-arrow-up-9-1:before,.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-litecoin-sign:before{content:"\e1d3"}.fa-border-none:before{content:"\f850"}.fa-circle-nodes:before{content:"\e4e2"}.fa-parachute-box:before{content:"\f4cd"}.fa-indent:before{content:"\f03c"}.fa-truck-field-un:before{content:"\e58e"}.fa-hourglass-empty:before,.fa-hourglass:before{content:"\f254"}.fa-mountain:before{content:"\f6fc"}.fa-user-doctor:before,.fa-user-md:before{content:"\f0f0"}.fa-circle-info:before,.fa-info-circle:before{content:"\f05a"}.fa-cloud-meatball:before{content:"\f73b"}.fa-camera-alt:before,.fa-camera:before{content:"\f030"}.fa-square-virus:before{content:"\e578"}.fa-meteor:before{content:"\f753"}.fa-car-on:before{content:"\e4dd"}.fa-sleigh:before{content:"\f7cc"}.fa-arrow-down-1-9:before,.fa-sort-numeric-asc:before,.fa-sort-numeric-down:before{content:"\f162"}.fa-hand-holding-droplet:before,.fa-hand-holding-water:before{content:"\f4c1"}.fa-water:before{content:"\f773"}.fa-calendar-check:before{content:"\f274"}.fa-braille:before{content:"\f2a1"}.fa-prescription-bottle-alt:before,.fa-prescription-bottle-medical:before{content:"\f486"}.fa-landmark:before{content:"\f66f"}.fa-truck:before{content:"\f0d1"}.fa-crosshairs:before{content:"\f05b"}.fa-person-cane:before{content:"\e53c"}.fa-tent:before{content:"\e57d"}.fa-vest-patches:before{content:"\e086"}.fa-check-double:before{content:"\f560"}.fa-arrow-down-a-z:before,.fa-sort-alpha-asc:before,.fa-sort-alpha-down:before{content:"\f15d"}.fa-money-bill-wheat:before{content:"\e52a"}.fa-cookie:before{content:"\f563"}.fa-arrow-left-rotate:before,.fa-arrow-rotate-back:before,.fa-arrow-rotate-backward:before,.fa-arrow-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-hard-drive:before,.fa-hdd:before{content:"\f0a0"}.fa-face-grin-squint-tears:before,.fa-grin-squint-tears:before{content:"\f586"}.fa-dumbbell:before{content:"\f44b"}.fa-list-alt:before,.fa-rectangle-list:before{content:"\f022"}.fa-tarp-droplet:before{content:"\e57c"}.fa-house-medical-circle-check:before{content:"\e511"}.fa-person-skiing-nordic:before,.fa-skiing-nordic:before{content:"\f7ca"}.fa-calendar-plus:before{content:"\f271"}.fa-plane-arrival:before{content:"\f5af"}.fa-arrow-alt-circle-left:before,.fa-circle-left:before{content:"\f359"}.fa-subway:before,.fa-train-subway:before{content:"\f239"}.fa-chart-gantt:before{content:"\e0e4"}.fa-indian-rupee-sign:before,.fa-indian-rupee:before,.fa-inr:before{content:"\e1bc"}.fa-crop-alt:before,.fa-crop-simple:before{content:"\f565"}.fa-money-bill-1:before,.fa-money-bill-alt:before{content:"\f3d1"}.fa-left-long:before,.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-dna:before{content:"\f471"}.fa-virus-slash:before{content:"\e075"}.fa-minus:before,.fa-subtract:before{content:"\f068"}.fa-chess:before{content:"\f439"}.fa-arrow-left-long:before,.fa-long-arrow-left:before{content:"\f177"}.fa-plug-circle-check:before{content:"\e55c"}.fa-street-view:before{content:"\f21d"}.fa-franc-sign:before{content:"\e18f"}.fa-volume-off:before{content:"\f026"}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before,.fa-hands-american-sign-language-interpreting:before,.fa-hands-asl-interpreting:before{content:"\f2a3"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-droplet-slash:before,.fa-tint-slash:before{content:"\f5c7"}.fa-mosque:before{content:"\f678"}.fa-mosquito:before{content:"\e52b"}.fa-star-of-david:before{content:"\f69a"}.fa-person-military-rifle:before{content:"\e54b"}.fa-cart-shopping:before,.fa-shopping-cart:before{content:"\f07a"}.fa-vials:before{content:"\f493"}.fa-plug-circle-plus:before{content:"\e55f"}.fa-place-of-worship:before{content:"\f67f"}.fa-grip-vertical:before{content:"\f58e"}.fa-arrow-turn-up:before,.fa-level-up:before{content:"\f148"}.fa-u:before{content:"\55"}.fa-square-root-alt:before,.fa-square-root-variable:before{content:"\f698"}.fa-clock-four:before,.fa-clock:before{content:"\f017"}.fa-backward-step:before,.fa-step-backward:before{content:"\f048"}.fa-pallet:before{content:"\f482"}.fa-faucet:before{content:"\e005"}.fa-baseball-bat-ball:before{content:"\f432"}.fa-s:before{content:"\53"}.fa-timeline:before{content:"\e29c"}.fa-keyboard:before{content:"\f11c"}.fa-caret-down:before{content:"\f0d7"}.fa-clinic-medical:before,.fa-house-chimney-medical:before{content:"\f7f2"}.fa-temperature-3:before,.fa-temperature-three-quarters:before,.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-mobile-android-alt:before,.fa-mobile-screen:before{content:"\f3cf"}.fa-plane-up:before{content:"\e22d"}.fa-piggy-bank:before{content:"\f4d3"}.fa-battery-3:before,.fa-battery-half:before{content:"\f242"}.fa-mountain-city:before{content:"\e52e"}.fa-coins:before{content:"\f51e"}.fa-khanda:before{content:"\f66d"}.fa-sliders-h:before,.fa-sliders:before{content:"\f1de"}.fa-folder-tree:before{content:"\f802"}.fa-network-wired:before{content:"\f6ff"}.fa-map-pin:before{content:"\f276"}.fa-hamsa:before{content:"\f665"}.fa-cent-sign:before{content:"\e3f5"}.fa-flask:before{content:"\f0c3"}.fa-person-pregnant:before{content:"\e31e"}.fa-wand-sparkles:before{content:"\f72b"}.fa-ellipsis-v:before,.fa-ellipsis-vertical:before{content:"\f142"}.fa-ticket:before{content:"\f145"}.fa-power-off:before{content:"\f011"}.fa-long-arrow-alt-right:before,.fa-right-long:before{content:"\f30b"}.fa-flag-usa:before{content:"\f74d"}.fa-laptop-file:before{content:"\e51d"}.fa-teletype:before,.fa-tty:before{content:"\f1e4"}.fa-diagram-next:before{content:"\e476"}.fa-person-rifle:before{content:"\e54e"}.fa-house-medical-circle-exclamation:before{content:"\e512"}.fa-closed-captioning:before{content:"\f20a"}.fa-hiking:before,.fa-person-hiking:before{content:"\f6ec"}.fa-venus-double:before{content:"\f226"}.fa-images:before{content:"\f302"}.fa-calculator:before{content:"\f1ec"}.fa-people-pulling:before{content:"\e535"}.fa-n:before{content:"\4e"}.fa-cable-car:before,.fa-tram:before{content:"\f7da"}.fa-cloud-rain:before{content:"\f73d"}.fa-building-circle-xmark:before{content:"\e4d4"}.fa-ship:before{content:"\f21a"}.fa-arrows-down-to-line:before{content:"\e4b8"}.fa-download:before{content:"\f019"}.fa-face-grin:before,.fa-grin:before{content:"\f580"}.fa-backspace:before,.fa-delete-left:before{content:"\f55a"}.fa-eye-dropper-empty:before,.fa-eye-dropper:before,.fa-eyedropper:before{content:"\f1fb"}.fa-file-circle-check:before{content:"\e5a0"}.fa-forward:before{content:"\f04e"}.fa-mobile-android:before,.fa-mobile-phone:before,.fa-mobile:before{content:"\f3ce"}.fa-face-meh:before,.fa-meh:before{content:"\f11a"}.fa-align-center:before{content:"\f037"}.fa-book-dead:before,.fa-book-skull:before{content:"\f6b7"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-heart-circle-exclamation:before{content:"\e4fe"}.fa-home-alt:before,.fa-home-lg-alt:before,.fa-home:before,.fa-house:before{content:"\f015"}.fa-calendar-week:before{content:"\f784"}.fa-laptop-medical:before{content:"\f812"}.fa-b:before{content:"\42"}.fa-file-medical:before{content:"\f477"}.fa-dice-one:before{content:"\f525"}.fa-kiwi-bird:before{content:"\f535"}.fa-arrow-right-arrow-left:before,.fa-exchange:before{content:"\f0ec"}.fa-redo-alt:before,.fa-rotate-forward:before,.fa-rotate-right:before{content:"\f2f9"}.fa-cutlery:before,.fa-utensils:before{content:"\f2e7"}.fa-arrow-up-wide-short:before,.fa-sort-amount-up:before{content:"\f161"}.fa-mill-sign:before{content:"\e1ed"}.fa-bowl-rice:before{content:"\e2eb"}.fa-skull:before{content:"\f54c"}.fa-broadcast-tower:before,.fa-tower-broadcast:before{content:"\f519"}.fa-truck-pickup:before{content:"\f63c"}.fa-long-arrow-alt-up:before,.fa-up-long:before{content:"\f30c"}.fa-stop:before{content:"\f04d"}.fa-code-merge:before{content:"\f387"}.fa-upload:before{content:"\f093"}.fa-hurricane:before{content:"\f751"}.fa-mound:before{content:"\e52d"}.fa-toilet-portable:before{content:"\e583"}.fa-compact-disc:before{content:"\f51f"}.fa-file-arrow-down:before,.fa-file-download:before{content:"\f56d"}.fa-caravan:before{content:"\f8ff"}.fa-shield-cat:before{content:"\e572"}.fa-bolt:before,.fa-zap:before{content:"\f0e7"}.fa-glass-water:before{content:"\e4f4"}.fa-oil-well:before{content:"\e532"}.fa-vault:before{content:"\e2c5"}.fa-mars:before{content:"\f222"}.fa-toilet:before{content:"\f7d8"}.fa-plane-circle-xmark:before{content:"\e557"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen-sign:before,.fa-yen:before{content:"\f157"}.fa-rouble:before,.fa-rub:before,.fa-ruble-sign:before,.fa-ruble:before{content:"\f158"}.fa-sun:before{content:"\f185"}.fa-guitar:before{content:"\f7a6"}.fa-face-laugh-wink:before,.fa-laugh-wink:before{content:"\f59c"}.fa-horse-head:before{content:"\f7ab"}.fa-bore-hole:before{content:"\e4c3"}.fa-industry:before{content:"\f275"}.fa-arrow-alt-circle-down:before,.fa-circle-down:before{content:"\f358"}.fa-arrows-turn-to-dots:before{content:"\e4c1"}.fa-florin-sign:before{content:"\e184"}.fa-arrow-down-short-wide:before,.fa-sort-amount-desc:before,.fa-sort-amount-down-alt:before{content:"\f884"}.fa-less-than:before{content:"\3c"}.fa-angle-down:before{content:"\f107"}.fa-car-tunnel:before{content:"\e4de"}.fa-head-side-cough:before{content:"\e061"}.fa-grip-lines:before{content:"\f7a4"}.fa-thumbs-down:before{content:"\f165"}.fa-user-lock:before{content:"\f502"}.fa-arrow-right-long:before,.fa-long-arrow-right:before{content:"\f178"}.fa-anchor-circle-xmark:before{content:"\e4ac"}.fa-ellipsis-h:before,.fa-ellipsis:before{content:"\f141"}.fa-chess-pawn:before{content:"\f443"}.fa-first-aid:before,.fa-kit-medical:before{content:"\f479"}.fa-person-through-window:before{content:"\e5a9"}.fa-toolbox:before{content:"\f552"}.fa-hands-holding-circle:before{content:"\e4fb"}.fa-bug:before{content:"\f188"}.fa-credit-card-alt:before,.fa-credit-card:before{content:"\f09d"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-hand-holding-hand:before{content:"\e4f7"}.fa-book-open-reader:before,.fa-book-reader:before{content:"\f5da"}.fa-mountain-sun:before{content:"\e52f"}.fa-arrows-left-right-to-line:before{content:"\e4ba"}.fa-dice-d20:before{content:"\f6cf"}.fa-truck-droplet:before{content:"\e58c"}.fa-file-circle-xmark:before{content:"\e5a1"}.fa-temperature-arrow-up:before,.fa-temperature-up:before{content:"\e040"}.fa-medal:before{content:"\f5a2"}.fa-bed:before{content:"\f236"}.fa-h-square:before,.fa-square-h:before{content:"\f0fd"}.fa-podcast:before{content:"\f2ce"}.fa-temperature-4:before,.fa-temperature-full:before,.fa-thermometer-4:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-bell:before{content:"\f0f3"}.fa-superscript:before{content:"\f12b"}.fa-plug-circle-xmark:before{content:"\e560"}.fa-star-of-life:before{content:"\f621"}.fa-phone-slash:before{content:"\f3dd"}.fa-paint-roller:before{content:"\f5aa"}.fa-hands-helping:before,.fa-handshake-angle:before{content:"\f4c4"}.fa-location-dot:before,.fa-map-marker-alt:before{content:"\f3c5"}.fa-file:before{content:"\f15b"}.fa-greater-than:before{content:"\3e"}.fa-person-swimming:before,.fa-swimmer:before{content:"\f5c4"}.fa-arrow-down:before{content:"\f063"}.fa-droplet:before,.fa-tint:before{content:"\f043"}.fa-eraser:before{content:"\f12d"}.fa-earth-america:before,.fa-earth-americas:before,.fa-earth:before,.fa-globe-americas:before{content:"\f57d"}.fa-person-burst:before{content:"\e53b"}.fa-dove:before{content:"\f4ba"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-socks:before{content:"\f696"}.fa-inbox:before{content:"\f01c"}.fa-section:before{content:"\e447"}.fa-gauge-high:before,.fa-tachometer-alt-fast:before,.fa-tachometer-alt:before{content:"\f625"}.fa-envelope-open-text:before{content:"\f658"}.fa-hospital-alt:before,.fa-hospital-wide:before,.fa-hospital:before{content:"\f0f8"}.fa-wine-bottle:before{content:"\f72f"}.fa-chess-rook:before{content:"\f447"}.fa-bars-staggered:before,.fa-reorder:before,.fa-stream:before{content:"\f550"}.fa-dharmachakra:before{content:"\f655"}.fa-hotdog:before{content:"\f80f"}.fa-blind:before,.fa-person-walking-with-cane:before{content:"\f29d"}.fa-drum:before{content:"\f569"}.fa-ice-cream:before{content:"\f810"}.fa-heart-circle-bolt:before{content:"\e4fc"}.fa-fax:before{content:"\f1ac"}.fa-paragraph:before{content:"\f1dd"}.fa-check-to-slot:before,.fa-vote-yea:before{content:"\f772"}.fa-star-half:before{content:"\f089"}.fa-boxes-alt:before,.fa-boxes-stacked:before,.fa-boxes:before{content:"\f468"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-assistive-listening-systems:before,.fa-ear-listen:before{content:"\f2a2"}.fa-tree-city:before{content:"\e587"}.fa-play:before{content:"\f04b"}.fa-font:before{content:"\f031"}.fa-table-cells-row-lock:before{content:"\e67a"}.fa-rupiah-sign:before{content:"\e23d"}.fa-magnifying-glass:before,.fa-search:before{content:"\f002"}.fa-ping-pong-paddle-ball:before,.fa-table-tennis-paddle-ball:before,.fa-table-tennis:before{content:"\f45d"}.fa-diagnoses:before,.fa-person-dots-from-line:before{content:"\f470"}.fa-trash-can-arrow-up:before,.fa-trash-restore-alt:before{content:"\f82a"}.fa-naira-sign:before{content:"\e1f6"}.fa-cart-arrow-down:before{content:"\f218"}.fa-walkie-talkie:before{content:"\f8ef"}.fa-file-edit:before,.fa-file-pen:before{content:"\f31c"}.fa-receipt:before{content:"\f543"}.fa-pen-square:before,.fa-pencil-square:before,.fa-square-pen:before{content:"\f14b"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-person-circle-exclamation:before{content:"\e53f"}.fa-chevron-down:before{content:"\f078"}.fa-battery-5:before,.fa-battery-full:before,.fa-battery:before{content:"\f240"}.fa-skull-crossbones:before{content:"\f714"}.fa-code-compare:before{content:"\e13a"}.fa-list-dots:before,.fa-list-ul:before{content:"\f0ca"}.fa-school-lock:before{content:"\e56f"}.fa-tower-cell:before{content:"\e585"}.fa-down-long:before,.fa-long-arrow-alt-down:before{content:"\f309"}.fa-ranking-star:before{content:"\e561"}.fa-chess-king:before{content:"\f43f"}.fa-person-harassing:before{content:"\e549"}.fa-brazilian-real-sign:before{content:"\e46c"}.fa-landmark-alt:before,.fa-landmark-dome:before{content:"\f752"}.fa-arrow-up:before{content:"\f062"}.fa-television:before,.fa-tv-alt:before,.fa-tv:before{content:"\f26c"}.fa-shrimp:before{content:"\e448"}.fa-list-check:before,.fa-tasks:before{content:"\f0ae"}.fa-jug-detergent:before{content:"\e519"}.fa-circle-user:before,.fa-user-circle:before{content:"\f2bd"}.fa-user-shield:before{content:"\f505"}.fa-wind:before{content:"\f72e"}.fa-car-burst:before,.fa-car-crash:before{content:"\f5e1"}.fa-y:before{content:"\59"}.fa-person-snowboarding:before,.fa-snowboarding:before{content:"\f7ce"}.fa-shipping-fast:before,.fa-truck-fast:before{content:"\f48b"}.fa-fish:before{content:"\f578"}.fa-user-graduate:before{content:"\f501"}.fa-adjust:before,.fa-circle-half-stroke:before{content:"\f042"}.fa-clapperboard:before{content:"\e131"}.fa-circle-radiation:before,.fa-radiation-alt:before{content:"\f7ba"}.fa-baseball-ball:before,.fa-baseball:before{content:"\f433"}.fa-jet-fighter-up:before{content:"\e518"}.fa-diagram-project:before,.fa-project-diagram:before{content:"\f542"}.fa-copy:before{content:"\f0c5"}.fa-volume-mute:before,.fa-volume-times:before,.fa-volume-xmark:before{content:"\f6a9"}.fa-hand-sparkles:before{content:"\e05d"}.fa-grip-horizontal:before,.fa-grip:before{content:"\f58d"}.fa-share-from-square:before,.fa-share-square:before{content:"\f14d"}.fa-child-combatant:before,.fa-child-rifle:before{content:"\e4e0"}.fa-gun:before{content:"\e19b"}.fa-phone-square:before,.fa-square-phone:before{content:"\f098"}.fa-add:before,.fa-plus:before{content:"\2b"}.fa-expand:before{content:"\f065"}.fa-computer:before{content:"\e4e5"}.fa-close:before,.fa-multiply:before,.fa-remove:before,.fa-times:before,.fa-xmark:before{content:"\f00d"}.fa-arrows-up-down-left-right:before,.fa-arrows:before{content:"\f047"}.fa-chalkboard-teacher:before,.fa-chalkboard-user:before{content:"\f51c"}.fa-peso-sign:before{content:"\e222"}.fa-building-shield:before{content:"\e4d8"}.fa-baby:before{content:"\f77c"}.fa-users-line:before{content:"\e592"}.fa-quote-left-alt:before,.fa-quote-left:before{content:"\f10d"}.fa-tractor:before{content:"\f722"}.fa-trash-arrow-up:before,.fa-trash-restore:before{content:"\f829"}.fa-arrow-down-up-lock:before{content:"\e4b0"}.fa-lines-leaning:before{content:"\e51e"}.fa-ruler-combined:before{content:"\f546"}.fa-copyright:before{content:"\f1f9"}.fa-equals:before{content:"\3d"}.fa-blender:before{content:"\f517"}.fa-teeth:before{content:"\f62e"}.fa-ils:before,.fa-shekel-sign:before,.fa-shekel:before,.fa-sheqel-sign:before,.fa-sheqel:before{content:"\f20b"}.fa-map:before{content:"\f279"}.fa-rocket:before{content:"\f135"}.fa-photo-film:before,.fa-photo-video:before{content:"\f87c"}.fa-folder-minus:before{content:"\f65d"}.fa-store:before{content:"\f54e"}.fa-arrow-trend-up:before{content:"\e098"}.fa-plug-circle-minus:before{content:"\e55e"}.fa-sign-hanging:before,.fa-sign:before{content:"\f4d9"}.fa-bezier-curve:before{content:"\f55b"}.fa-bell-slash:before{content:"\f1f6"}.fa-tablet-android:before,.fa-tablet:before{content:"\f3fb"}.fa-school-flag:before{content:"\e56e"}.fa-fill:before{content:"\f575"}.fa-angle-up:before{content:"\f106"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-holly-berry:before{content:"\f7aa"}.fa-chevron-left:before{content:"\f053"}.fa-bacteria:before{content:"\e059"}.fa-hand-lizard:before{content:"\f258"}.fa-notdef:before{content:"\e1fe"}.fa-disease:before{content:"\f7fa"}.fa-briefcase-medical:before{content:"\f469"}.fa-genderless:before{content:"\f22d"}.fa-chevron-right:before{content:"\f054"}.fa-retweet:before{content:"\f079"}.fa-car-alt:before,.fa-car-rear:before{content:"\f5de"}.fa-pump-soap:before{content:"\e06b"}.fa-video-slash:before{content:"\f4e2"}.fa-battery-2:before,.fa-battery-quarter:before{content:"\f243"}.fa-radio:before{content:"\f8d7"}.fa-baby-carriage:before,.fa-carriage-baby:before{content:"\f77d"}.fa-traffic-light:before{content:"\f637"}.fa-thermometer:before{content:"\f491"}.fa-vr-cardboard:before{content:"\f729"}.fa-hand-middle-finger:before{content:"\f806"}.fa-percent:before,.fa-percentage:before{content:"\25"}.fa-truck-moving:before{content:"\f4df"}.fa-glass-water-droplet:before{content:"\e4f5"}.fa-display:before{content:"\e163"}.fa-face-smile:before,.fa-smile:before{content:"\f118"}.fa-thumb-tack:before,.fa-thumbtack:before{content:"\f08d"}.fa-trophy:before{content:"\f091"}.fa-person-praying:before,.fa-pray:before{content:"\f683"}.fa-hammer:before{content:"\f6e3"}.fa-hand-peace:before{content:"\f25b"}.fa-rotate:before,.fa-sync-alt:before{content:"\f2f1"}.fa-spinner:before{content:"\f110"}.fa-robot:before{content:"\f544"}.fa-peace:before{content:"\f67c"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-warehouse:before{content:"\f494"}.fa-arrow-up-right-dots:before{content:"\e4b7"}.fa-splotch:before{content:"\f5bc"}.fa-face-grin-hearts:before,.fa-grin-hearts:before{content:"\f584"}.fa-dice-four:before{content:"\f524"}.fa-sim-card:before{content:"\f7c4"}.fa-transgender-alt:before,.fa-transgender:before{content:"\f225"}.fa-mercury:before{content:"\f223"}.fa-arrow-turn-down:before,.fa-level-down:before{content:"\f149"}.fa-person-falling-burst:before{content:"\e547"}.fa-award:before{content:"\f559"}.fa-ticket-alt:before,.fa-ticket-simple:before{content:"\f3ff"}.fa-building:before{content:"\f1ad"}.fa-angle-double-left:before,.fa-angles-left:before{content:"\f100"}.fa-qrcode:before{content:"\f029"}.fa-clock-rotate-left:before,.fa-history:before{content:"\f1da"}.fa-face-grin-beam-sweat:before,.fa-grin-beam-sweat:before{content:"\f583"}.fa-arrow-right-from-file:before,.fa-file-export:before{content:"\f56e"}.fa-shield-blank:before,.fa-shield:before{content:"\f132"}.fa-arrow-up-short-wide:before,.fa-sort-amount-up-alt:before{content:"\f885"}.fa-house-medical:before{content:"\e3b2"}.fa-golf-ball-tee:before,.fa-golf-ball:before{content:"\f450"}.fa-chevron-circle-left:before,.fa-circle-chevron-left:before{content:"\f137"}.fa-house-chimney-window:before{content:"\e00d"}.fa-pen-nib:before{content:"\f5ad"}.fa-tent-arrow-turn-left:before{content:"\e580"}.fa-tents:before{content:"\e582"}.fa-magic:before,.fa-wand-magic:before{content:"\f0d0"}.fa-dog:before{content:"\f6d3"}.fa-carrot:before{content:"\f787"}.fa-moon:before{content:"\f186"}.fa-wine-glass-alt:before,.fa-wine-glass-empty:before{content:"\f5ce"}.fa-cheese:before{content:"\f7ef"}.fa-yin-yang:before{content:"\f6ad"}.fa-music:before{content:"\f001"}.fa-code-commit:before{content:"\f386"}.fa-temperature-low:before{content:"\f76b"}.fa-biking:before,.fa-person-biking:before{content:"\f84a"}.fa-broom:before{content:"\f51a"}.fa-shield-heart:before{content:"\e574"}.fa-gopuram:before{content:"\f664"}.fa-earth-oceania:before,.fa-globe-oceania:before{content:"\e47b"}.fa-square-xmark:before,.fa-times-square:before,.fa-xmark-square:before{content:"\f2d3"}.fa-hashtag:before{content:"\23"}.fa-expand-alt:before,.fa-up-right-and-down-left-from-center:before{content:"\f424"}.fa-oil-can:before{content:"\f613"}.fa-t:before{content:"\54"}.fa-hippo:before{content:"\f6ed"}.fa-chart-column:before{content:"\e0e3"}.fa-infinity:before{content:"\f534"}.fa-vial-circle-check:before{content:"\e596"}.fa-person-arrow-down-to-line:before{content:"\e538"}.fa-voicemail:before{content:"\f897"}.fa-fan:before{content:"\f863"}.fa-person-walking-luggage:before{content:"\e554"}.fa-arrows-alt-v:before,.fa-up-down:before{content:"\f338"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-calendar:before{content:"\f133"}.fa-trailer:before{content:"\e041"}.fa-bahai:before,.fa-haykal:before{content:"\f666"}.fa-sd-card:before{content:"\f7c2"}.fa-dragon:before{content:"\f6d5"}.fa-shoe-prints:before{content:"\f54b"}.fa-circle-plus:before,.fa-plus-circle:before{content:"\f055"}.fa-face-grin-tongue-wink:before,.fa-grin-tongue-wink:before{content:"\f58b"}.fa-hand-holding:before{content:"\f4bd"}.fa-plug-circle-exclamation:before{content:"\e55d"}.fa-chain-broken:before,.fa-chain-slash:before,.fa-link-slash:before,.fa-unlink:before{content:"\f127"}.fa-clone:before{content:"\f24d"}.fa-person-walking-arrow-loop-left:before{content:"\e551"}.fa-arrow-up-z-a:before,.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-fire-alt:before,.fa-fire-flame-curved:before{content:"\f7e4"}.fa-tornado:before{content:"\f76f"}.fa-file-circle-plus:before{content:"\e494"}.fa-book-quran:before,.fa-quran:before{content:"\f687"}.fa-anchor:before{content:"\f13d"}.fa-border-all:before{content:"\f84c"}.fa-angry:before,.fa-face-angry:before{content:"\f556"}.fa-cookie-bite:before{content:"\f564"}.fa-arrow-trend-down:before{content:"\e097"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-draw-polygon:before{content:"\f5ee"}.fa-balance-scale:before,.fa-scale-balanced:before{content:"\f24e"}.fa-gauge-simple-high:before,.fa-tachometer-fast:before,.fa-tachometer:before{content:"\f62a"}.fa-shower:before{content:"\f2cc"}.fa-desktop-alt:before,.fa-desktop:before{content:"\f390"}.fa-m:before{content:"\4d"}.fa-table-list:before,.fa-th-list:before{content:"\f00b"}.fa-comment-sms:before,.fa-sms:before{content:"\f7cd"}.fa-book:before{content:"\f02d"}.fa-user-plus:before{content:"\f234"}.fa-check:before{content:"\f00c"}.fa-battery-4:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-house-circle-check:before{content:"\e509"}.fa-angle-left:before{content:"\f104"}.fa-diagram-successor:before{content:"\e47a"}.fa-truck-arrow-right:before{content:"\e58b"}.fa-arrows-split-up-and-left:before{content:"\e4bc"}.fa-fist-raised:before,.fa-hand-fist:before{content:"\f6de"}.fa-cloud-moon:before{content:"\f6c3"}.fa-briefcase:before{content:"\f0b1"}.fa-person-falling:before{content:"\e546"}.fa-image-portrait:before,.fa-portrait:before{content:"\f3e0"}.fa-user-tag:before{content:"\f507"}.fa-rug:before{content:"\e569"}.fa-earth-europe:before,.fa-globe-europe:before{content:"\f7a2"}.fa-cart-flatbed-suitcase:before,.fa-luggage-cart:before{content:"\f59d"}.fa-rectangle-times:before,.fa-rectangle-xmark:before,.fa-times-rectangle:before,.fa-window-close:before{content:"\f410"}.fa-baht-sign:before{content:"\e0ac"}.fa-book-open:before{content:"\f518"}.fa-book-journal-whills:before,.fa-journal-whills:before{content:"\f66a"}.fa-handcuffs:before{content:"\e4f8"}.fa-exclamation-triangle:before,.fa-triangle-exclamation:before,.fa-warning:before{content:"\f071"}.fa-database:before{content:"\f1c0"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-bottle-droplet:before{content:"\e4c4"}.fa-mask-face:before{content:"\e1d7"}.fa-hill-rockslide:before{content:"\e508"}.fa-exchange-alt:before,.fa-right-left:before{content:"\f362"}.fa-paper-plane:before{content:"\f1d8"}.fa-road-circle-exclamation:before{content:"\e565"}.fa-dungeon:before{content:"\f6d9"}.fa-align-right:before{content:"\f038"}.fa-money-bill-1-wave:before,.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-life-ring:before{content:"\f1cd"}.fa-hands:before,.fa-sign-language:before,.fa-signing:before{content:"\f2a7"}.fa-calendar-day:before{content:"\f783"}.fa-ladder-water:before,.fa-swimming-pool:before,.fa-water-ladder:before{content:"\f5c5"}.fa-arrows-up-down:before,.fa-arrows-v:before{content:"\f07d"}.fa-face-grimace:before,.fa-grimace:before{content:"\f57f"}.fa-wheelchair-alt:before,.fa-wheelchair-move:before{content:"\e2ce"}.fa-level-down-alt:before,.fa-turn-down:before{content:"\f3be"}.fa-person-walking-arrow-right:before{content:"\e552"}.fa-envelope-square:before,.fa-square-envelope:before{content:"\f199"}.fa-dice:before{content:"\f522"}.fa-bowling-ball:before{content:"\f436"}.fa-brain:before{content:"\f5dc"}.fa-band-aid:before,.fa-bandage:before{content:"\f462"}.fa-calendar-minus:before{content:"\f272"}.fa-circle-xmark:before,.fa-times-circle:before,.fa-xmark-circle:before{content:"\f057"}.fa-gifts:before{content:"\f79c"}.fa-hotel:before{content:"\f594"}.fa-earth-asia:before,.fa-globe-asia:before{content:"\f57e"}.fa-id-card-alt:before,.fa-id-card-clip:before{content:"\f47f"}.fa-magnifying-glass-plus:before,.fa-search-plus:before{content:"\f00e"}.fa-thumbs-up:before{content:"\f164"}.fa-user-clock:before{content:"\f4fd"}.fa-allergies:before,.fa-hand-dots:before{content:"\f461"}.fa-file-invoice:before{content:"\f570"}.fa-window-minimize:before{content:"\f2d1"}.fa-coffee:before,.fa-mug-saucer:before{content:"\f0f4"}.fa-brush:before{content:"\f55d"}.fa-mask:before{content:"\f6fa"}.fa-magnifying-glass-minus:before,.fa-search-minus:before{content:"\f010"}.fa-ruler-vertical:before{content:"\f548"}.fa-user-alt:before,.fa-user-large:before{content:"\f406"}.fa-train-tram:before{content:"\e5b4"}.fa-user-nurse:before{content:"\f82f"}.fa-syringe:before{content:"\f48e"}.fa-cloud-sun:before{content:"\f6c4"}.fa-stopwatch-20:before{content:"\e06f"}.fa-square-full:before{content:"\f45c"}.fa-magnet:before{content:"\f076"}.fa-jar:before{content:"\e516"}.fa-note-sticky:before,.fa-sticky-note:before{content:"\f249"}.fa-bug-slash:before{content:"\e490"}.fa-arrow-up-from-water-pump:before{content:"\e4b6"}.fa-bone:before{content:"\f5d7"}.fa-user-injured:before{content:"\f728"}.fa-face-sad-tear:before,.fa-sad-tear:before{content:"\f5b4"}.fa-plane:before{content:"\f072"}.fa-tent-arrows-down:before{content:"\e581"}.fa-exclamation:before{content:"\21"}.fa-arrows-spin:before{content:"\e4bb"}.fa-print:before{content:"\f02f"}.fa-try:before,.fa-turkish-lira-sign:before,.fa-turkish-lira:before{content:"\e2bb"}.fa-dollar-sign:before,.fa-dollar:before,.fa-usd:before{content:"\24"}.fa-x:before{content:"\58"}.fa-magnifying-glass-dollar:before,.fa-search-dollar:before{content:"\f688"}.fa-users-cog:before,.fa-users-gear:before{content:"\f509"}.fa-person-military-pointing:before{content:"\e54a"}.fa-bank:before,.fa-building-columns:before,.fa-institution:before,.fa-museum:before,.fa-university:before{content:"\f19c"}.fa-umbrella:before{content:"\f0e9"}.fa-trowel:before{content:"\e589"}.fa-d:before{content:"\44"}.fa-stapler:before{content:"\e5af"}.fa-masks-theater:before,.fa-theater-masks:before{content:"\f630"}.fa-kip-sign:before{content:"\e1c4"}.fa-hand-point-left:before{content:"\f0a5"}.fa-handshake-alt:before,.fa-handshake-simple:before{content:"\f4c6"}.fa-fighter-jet:before,.fa-jet-fighter:before{content:"\f0fb"}.fa-share-alt-square:before,.fa-square-share-nodes:before{content:"\f1e1"}.fa-barcode:before{content:"\f02a"}.fa-plus-minus:before{content:"\e43c"}.fa-video-camera:before,.fa-video:before{content:"\f03d"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-hand-holding-medical:before{content:"\e05c"}.fa-person-circle-check:before{content:"\e53e"}.fa-level-up-alt:before,.fa-turn-up:before{content:"\f3bf"} +.fa-sr-only,.fa-sr-only-focusable:not(:focus),.sr-only,.sr-only-focusable:not(:focus){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}:host,:root{--fa-style-family-brands:"Font Awesome 6 Brands";--fa-font-brands:normal 400 1em/1 "Font Awesome 6 Brands"}@font-face{font-family:"Font Awesome 6 Brands";font-style:normal;font-weight:400;font-display:block;src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); }.fa-brands,.fab{font-weight:400}.fa-monero:before{content:"\f3d0"}.fa-hooli:before{content:"\f427"}.fa-yelp:before{content:"\f1e9"}.fa-cc-visa:before{content:"\f1f0"}.fa-lastfm:before{content:"\f202"}.fa-shopware:before{content:"\f5b5"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-aws:before{content:"\f375"}.fa-redhat:before{content:"\f7bc"}.fa-yoast:before{content:"\f2b1"}.fa-cloudflare:before{content:"\e07d"}.fa-ups:before{content:"\f7e0"}.fa-pixiv:before{content:"\e640"}.fa-wpexplorer:before{content:"\f2de"}.fa-dyalog:before{content:"\f399"}.fa-bity:before{content:"\f37a"}.fa-stackpath:before{content:"\f842"}.fa-buysellads:before{content:"\f20d"}.fa-first-order:before{content:"\f2b0"}.fa-modx:before{content:"\f285"}.fa-guilded:before{content:"\e07e"}.fa-vnv:before{content:"\f40b"}.fa-js-square:before,.fa-square-js:before{content:"\f3b9"}.fa-microsoft:before{content:"\f3ca"}.fa-qq:before{content:"\f1d6"}.fa-orcid:before{content:"\f8d2"}.fa-java:before{content:"\f4e4"}.fa-invision:before{content:"\f7b0"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-centercode:before{content:"\f380"}.fa-glide-g:before{content:"\f2a6"}.fa-drupal:before{content:"\f1a9"}.fa-jxl:before{content:"\e67b"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-unity:before{content:"\e049"}.fa-whmcs:before{content:"\f40d"}.fa-rocketchat:before{content:"\f3e8"}.fa-vk:before{content:"\f189"}.fa-untappd:before{content:"\f405"}.fa-mailchimp:before{content:"\f59e"}.fa-css3-alt:before{content:"\f38b"}.fa-reddit-square:before,.fa-square-reddit:before{content:"\f1a2"}.fa-vimeo-v:before{content:"\f27d"}.fa-contao:before{content:"\f26d"}.fa-square-font-awesome:before{content:"\e5ad"}.fa-deskpro:before{content:"\f38f"}.fa-brave:before{content:"\e63c"}.fa-sistrix:before{content:"\f3ee"}.fa-instagram-square:before,.fa-square-instagram:before{content:"\e055"}.fa-battle-net:before{content:"\f835"}.fa-the-red-yeti:before{content:"\f69d"}.fa-hacker-news-square:before,.fa-square-hacker-news:before{content:"\f3af"}.fa-edge:before{content:"\f282"}.fa-threads:before{content:"\e618"}.fa-napster:before{content:"\f3d2"}.fa-snapchat-square:before,.fa-square-snapchat:before{content:"\f2ad"}.fa-google-plus-g:before{content:"\f0d5"}.fa-artstation:before{content:"\f77a"}.fa-markdown:before{content:"\f60f"}.fa-sourcetree:before{content:"\f7d3"}.fa-google-plus:before{content:"\f2b3"}.fa-diaspora:before{content:"\f791"}.fa-foursquare:before{content:"\f180"}.fa-stack-overflow:before{content:"\f16c"}.fa-github-alt:before{content:"\f113"}.fa-phoenix-squadron:before{content:"\f511"}.fa-pagelines:before{content:"\f18c"}.fa-algolia:before{content:"\f36c"}.fa-red-river:before{content:"\f3e3"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-safari:before{content:"\f267"}.fa-google:before{content:"\f1a0"}.fa-font-awesome-alt:before,.fa-square-font-awesome-stroke:before{content:"\f35c"}.fa-atlassian:before{content:"\f77b"}.fa-linkedin-in:before{content:"\f0e1"}.fa-digital-ocean:before{content:"\f391"}.fa-nimblr:before{content:"\f5a8"}.fa-chromecast:before{content:"\f838"}.fa-evernote:before{content:"\f839"}.fa-hacker-news:before{content:"\f1d4"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-adversal:before{content:"\f36a"}.fa-creative-commons:before{content:"\f25e"}.fa-watchman-monitoring:before{content:"\e087"}.fa-fonticons:before{content:"\f280"}.fa-weixin:before{content:"\f1d7"}.fa-shirtsinbulk:before{content:"\f214"}.fa-codepen:before{content:"\f1cb"}.fa-git-alt:before{content:"\f841"}.fa-lyft:before{content:"\f3c3"}.fa-rev:before{content:"\f5b2"}.fa-windows:before{content:"\f17a"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-square-viadeo:before,.fa-viadeo-square:before{content:"\f2aa"}.fa-meetup:before{content:"\f2e0"}.fa-centos:before{content:"\f789"}.fa-adn:before{content:"\f170"}.fa-cloudsmith:before{content:"\f384"}.fa-opensuse:before{content:"\e62b"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-dribbble-square:before,.fa-square-dribbble:before{content:"\f397"}.fa-codiepie:before{content:"\f284"}.fa-node:before{content:"\f419"}.fa-mix:before{content:"\f3cb"}.fa-steam:before{content:"\f1b6"}.fa-cc-apple-pay:before{content:"\f416"}.fa-scribd:before{content:"\f28a"}.fa-debian:before{content:"\e60b"}.fa-openid:before{content:"\f19b"}.fa-instalod:before{content:"\e081"}.fa-expeditedssl:before{content:"\f23e"}.fa-sellcast:before{content:"\f2da"}.fa-square-twitter:before,.fa-twitter-square:before{content:"\f081"}.fa-r-project:before{content:"\f4f7"}.fa-delicious:before{content:"\f1a5"}.fa-freebsd:before{content:"\f3a4"}.fa-vuejs:before{content:"\f41f"}.fa-accusoft:before{content:"\f369"}.fa-ioxhost:before{content:"\f208"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-app-store:before{content:"\f36f"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-itunes-note:before{content:"\f3b5"}.fa-golang:before{content:"\e40f"}.fa-kickstarter:before,.fa-square-kickstarter:before{content:"\f3bb"}.fa-grav:before{content:"\f2d6"}.fa-weibo:before{content:"\f18a"}.fa-uncharted:before{content:"\e084"}.fa-firstdraft:before{content:"\f3a1"}.fa-square-youtube:before,.fa-youtube-square:before{content:"\f431"}.fa-wikipedia-w:before{content:"\f266"}.fa-rendact:before,.fa-wpressr:before{content:"\f3e4"}.fa-angellist:before{content:"\f209"}.fa-galactic-republic:before{content:"\f50c"}.fa-nfc-directional:before{content:"\e530"}.fa-skype:before{content:"\f17e"}.fa-joget:before{content:"\f3b7"}.fa-fedora:before{content:"\f798"}.fa-stripe-s:before{content:"\f42a"}.fa-meta:before{content:"\e49b"}.fa-laravel:before{content:"\f3bd"}.fa-hotjar:before{content:"\f3b1"}.fa-bluetooth-b:before{content:"\f294"}.fa-square-letterboxd:before{content:"\e62e"}.fa-sticker-mule:before{content:"\f3f7"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-hips:before{content:"\f452"}.fa-behance:before{content:"\f1b4"}.fa-reddit:before{content:"\f1a1"}.fa-discord:before{content:"\f392"}.fa-chrome:before{content:"\f268"}.fa-app-store-ios:before{content:"\f370"}.fa-cc-discover:before{content:"\f1f2"}.fa-wpbeginner:before{content:"\f297"}.fa-confluence:before{content:"\f78d"}.fa-shoelace:before{content:"\e60c"}.fa-mdb:before{content:"\f8ca"}.fa-dochub:before{content:"\f394"}.fa-accessible-icon:before{content:"\f368"}.fa-ebay:before{content:"\f4f4"}.fa-amazon:before{content:"\f270"}.fa-unsplash:before{content:"\e07c"}.fa-yarn:before{content:"\f7e3"}.fa-square-steam:before,.fa-steam-square:before{content:"\f1b7"}.fa-500px:before{content:"\f26e"}.fa-square-vimeo:before,.fa-vimeo-square:before{content:"\f194"}.fa-asymmetrik:before{content:"\f372"}.fa-font-awesome-flag:before,.fa-font-awesome-logo-full:before,.fa-font-awesome:before{content:"\f2b4"}.fa-gratipay:before{content:"\f184"}.fa-apple:before{content:"\f179"}.fa-hive:before{content:"\e07f"}.fa-gitkraken:before{content:"\f3a6"}.fa-keybase:before{content:"\f4f5"}.fa-apple-pay:before{content:"\f415"}.fa-padlet:before{content:"\e4a0"}.fa-amazon-pay:before{content:"\f42c"}.fa-github-square:before,.fa-square-github:before{content:"\f092"}.fa-stumbleupon:before{content:"\f1a4"}.fa-fedex:before{content:"\f797"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-shopify:before{content:"\e057"}.fa-neos:before{content:"\f612"}.fa-square-threads:before{content:"\e619"}.fa-hackerrank:before{content:"\f5f7"}.fa-researchgate:before{content:"\f4f8"}.fa-swift:before{content:"\f8e1"}.fa-angular:before{content:"\f420"}.fa-speakap:before{content:"\f3f3"}.fa-angrycreative:before{content:"\f36e"}.fa-y-combinator:before{content:"\f23b"}.fa-empire:before{content:"\f1d1"}.fa-envira:before{content:"\f299"}.fa-google-scholar:before{content:"\e63b"}.fa-gitlab-square:before,.fa-square-gitlab:before{content:"\e5ae"}.fa-studiovinari:before{content:"\f3f8"}.fa-pied-piper:before{content:"\f2ae"}.fa-wordpress:before{content:"\f19a"}.fa-product-hunt:before{content:"\f288"}.fa-firefox:before{content:"\f269"}.fa-linode:before{content:"\f2b8"}.fa-goodreads:before{content:"\f3a8"}.fa-odnoklassniki-square:before,.fa-square-odnoklassniki:before{content:"\f264"}.fa-jsfiddle:before{content:"\f1cc"}.fa-sith:before{content:"\f512"}.fa-themeisle:before{content:"\f2b2"}.fa-page4:before{content:"\f3d7"}.fa-hashnode:before{content:"\e499"}.fa-react:before{content:"\f41b"}.fa-cc-paypal:before{content:"\f1f4"}.fa-squarespace:before{content:"\f5be"}.fa-cc-stripe:before{content:"\f1f5"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-bitcoin:before{content:"\f379"}.fa-keycdn:before{content:"\f3ba"}.fa-opera:before{content:"\f26a"}.fa-itch-io:before{content:"\f83a"}.fa-umbraco:before{content:"\f8e8"}.fa-galactic-senate:before{content:"\f50d"}.fa-ubuntu:before{content:"\f7df"}.fa-draft2digital:before{content:"\f396"}.fa-stripe:before{content:"\f429"}.fa-houzz:before{content:"\f27c"}.fa-gg:before{content:"\f260"}.fa-dhl:before{content:"\f790"}.fa-pinterest-square:before,.fa-square-pinterest:before{content:"\f0d3"}.fa-xing:before{content:"\f168"}.fa-blackberry:before{content:"\f37b"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-playstation:before{content:"\f3df"}.fa-quinscape:before{content:"\f459"}.fa-less:before{content:"\f41d"}.fa-blogger-b:before{content:"\f37d"}.fa-opencart:before{content:"\f23d"}.fa-vine:before{content:"\f1ca"}.fa-signal-messenger:before{content:"\e663"}.fa-paypal:before{content:"\f1ed"}.fa-gitlab:before{content:"\f296"}.fa-typo3:before{content:"\f42b"}.fa-reddit-alien:before{content:"\f281"}.fa-yahoo:before{content:"\f19e"}.fa-dailymotion:before{content:"\e052"}.fa-affiliatetheme:before{content:"\f36b"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-bootstrap:before{content:"\f836"}.fa-odnoklassniki:before{content:"\f263"}.fa-nfc-symbol:before{content:"\e531"}.fa-mintbit:before{content:"\e62f"}.fa-ethereum:before{content:"\f42e"}.fa-speaker-deck:before{content:"\f83c"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-patreon:before{content:"\f3d9"}.fa-avianex:before{content:"\f374"}.fa-ello:before{content:"\f5f1"}.fa-gofore:before{content:"\f3a7"}.fa-bimobject:before{content:"\f378"}.fa-brave-reverse:before{content:"\e63d"}.fa-facebook-f:before{content:"\f39e"}.fa-google-plus-square:before,.fa-square-google-plus:before{content:"\f0d4"}.fa-web-awesome:before{content:"\e682"}.fa-mandalorian:before{content:"\f50f"}.fa-first-order-alt:before{content:"\f50a"}.fa-osi:before{content:"\f41a"}.fa-google-wallet:before{content:"\f1ee"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-periscope:before{content:"\f3da"}.fa-fulcrum:before{content:"\f50b"}.fa-cloudscale:before{content:"\f383"}.fa-forumbee:before{content:"\f211"}.fa-mizuni:before{content:"\f3cc"}.fa-schlix:before{content:"\f3ea"}.fa-square-xing:before,.fa-xing-square:before{content:"\f169"}.fa-bandcamp:before{content:"\f2d5"}.fa-wpforms:before{content:"\f298"}.fa-cloudversify:before{content:"\f385"}.fa-usps:before{content:"\f7e1"}.fa-megaport:before{content:"\f5a3"}.fa-magento:before{content:"\f3c4"}.fa-spotify:before{content:"\f1bc"}.fa-optin-monster:before{content:"\f23c"}.fa-fly:before{content:"\f417"}.fa-aviato:before{content:"\f421"}.fa-itunes:before{content:"\f3b4"}.fa-cuttlefish:before{content:"\f38c"}.fa-blogger:before{content:"\f37c"}.fa-flickr:before{content:"\f16e"}.fa-viber:before{content:"\f409"}.fa-soundcloud:before{content:"\f1be"}.fa-digg:before{content:"\f1a6"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-letterboxd:before{content:"\e62d"}.fa-symfony:before{content:"\f83d"}.fa-maxcdn:before{content:"\f136"}.fa-etsy:before{content:"\f2d7"}.fa-facebook-messenger:before{content:"\f39f"}.fa-audible:before{content:"\f373"}.fa-think-peaks:before{content:"\f731"}.fa-bilibili:before{content:"\e3d9"}.fa-erlang:before{content:"\f39d"}.fa-x-twitter:before{content:"\e61b"}.fa-cotton-bureau:before{content:"\f89e"}.fa-dashcube:before{content:"\f210"}.fa-42-group:before,.fa-innosoft:before{content:"\e080"}.fa-stack-exchange:before{content:"\f18d"}.fa-elementor:before{content:"\f430"}.fa-pied-piper-square:before,.fa-square-pied-piper:before{content:"\e01e"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-palfed:before{content:"\f3d8"}.fa-superpowers:before{content:"\f2dd"}.fa-resolving:before{content:"\f3e7"}.fa-xbox:before{content:"\f412"}.fa-square-web-awesome-stroke:before{content:"\e684"}.fa-searchengin:before{content:"\f3eb"}.fa-tiktok:before{content:"\e07b"}.fa-facebook-square:before,.fa-square-facebook:before{content:"\f082"}.fa-renren:before{content:"\f18b"}.fa-linux:before{content:"\f17c"}.fa-glide:before{content:"\f2a5"}.fa-linkedin:before{content:"\f08c"}.fa-hubspot:before{content:"\f3b2"}.fa-deploydog:before{content:"\f38e"}.fa-twitch:before{content:"\f1e8"}.fa-ravelry:before{content:"\f2d9"}.fa-mixer:before{content:"\e056"}.fa-lastfm-square:before,.fa-square-lastfm:before{content:"\f203"}.fa-vimeo:before{content:"\f40a"}.fa-mendeley:before{content:"\f7b3"}.fa-uniregistry:before{content:"\f404"}.fa-figma:before{content:"\f799"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-dropbox:before{content:"\f16b"}.fa-instagram:before{content:"\f16d"}.fa-cmplid:before{content:"\e360"}.fa-upwork:before{content:"\e641"}.fa-facebook:before{content:"\f09a"}.fa-gripfire:before{content:"\f3ac"}.fa-jedi-order:before{content:"\f50e"}.fa-uikit:before{content:"\f403"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-phabricator:before{content:"\f3db"}.fa-ussunnah:before{content:"\f407"}.fa-earlybirds:before{content:"\f39a"}.fa-trade-federation:before{content:"\f513"}.fa-autoprefixer:before{content:"\f41c"}.fa-whatsapp:before{content:"\f232"}.fa-square-upwork:before{content:"\e67c"}.fa-slideshare:before{content:"\f1e7"}.fa-google-play:before{content:"\f3ab"}.fa-viadeo:before{content:"\f2a9"}.fa-line:before{content:"\f3c0"}.fa-google-drive:before{content:"\f3aa"}.fa-servicestack:before{content:"\f3ec"}.fa-simplybuilt:before{content:"\f215"}.fa-bitbucket:before{content:"\f171"}.fa-imdb:before{content:"\f2d8"}.fa-deezer:before{content:"\e077"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-jira:before{content:"\f7b1"}.fa-docker:before{content:"\f395"}.fa-screenpal:before{content:"\e570"}.fa-bluetooth:before{content:"\f293"}.fa-gitter:before{content:"\f426"}.fa-d-and-d:before{content:"\f38d"}.fa-microblog:before{content:"\e01a"}.fa-cc-diners-club:before{content:"\f24c"}.fa-gg-circle:before{content:"\f261"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-yandex:before{content:"\f413"}.fa-readme:before{content:"\f4d5"}.fa-html5:before{content:"\f13b"}.fa-sellsy:before{content:"\f213"}.fa-square-web-awesome:before{content:"\e683"}.fa-sass:before{content:"\f41e"}.fa-wirsindhandwerk:before,.fa-wsh:before{content:"\e2d0"}.fa-buromobelexperte:before{content:"\f37f"}.fa-salesforce:before{content:"\f83b"}.fa-octopus-deploy:before{content:"\e082"}.fa-medapps:before{content:"\f3c6"}.fa-ns8:before{content:"\f3d5"}.fa-pinterest-p:before{content:"\f231"}.fa-apper:before{content:"\f371"}.fa-fort-awesome:before{content:"\f286"}.fa-waze:before{content:"\f83f"}.fa-bluesky:before{content:"\e671"}.fa-cc-jcb:before{content:"\f24b"}.fa-snapchat-ghost:before,.fa-snapchat:before{content:"\f2ab"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-rust:before{content:"\e07a"}.fa-wix:before{content:"\f5cf"}.fa-behance-square:before,.fa-square-behance:before{content:"\f1b5"}.fa-supple:before{content:"\f3f9"}.fa-webflow:before{content:"\e65c"}.fa-rebel:before{content:"\f1d0"}.fa-css3:before{content:"\f13c"}.fa-staylinked:before{content:"\f3f5"}.fa-kaggle:before{content:"\f5fa"}.fa-space-awesome:before{content:"\e5ac"}.fa-deviantart:before{content:"\f1bd"}.fa-cpanel:before{content:"\f388"}.fa-goodreads-g:before{content:"\f3a9"}.fa-git-square:before,.fa-square-git:before{content:"\f1d2"}.fa-square-tumblr:before,.fa-tumblr-square:before{content:"\f174"}.fa-trello:before{content:"\f181"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-get-pocket:before{content:"\f265"}.fa-perbyte:before{content:"\e083"}.fa-grunt:before{content:"\f3ad"}.fa-weebly:before{content:"\f5cc"}.fa-connectdevelop:before{content:"\f20e"}.fa-leanpub:before{content:"\f212"}.fa-black-tie:before{content:"\f27e"}.fa-themeco:before{content:"\f5c6"}.fa-python:before{content:"\f3e2"}.fa-android:before{content:"\f17b"}.fa-bots:before{content:"\e340"}.fa-free-code-camp:before{content:"\f2c5"}.fa-hornbill:before{content:"\f592"}.fa-js:before{content:"\f3b8"}.fa-ideal:before{content:"\e013"}.fa-git:before{content:"\f1d3"}.fa-dev:before{content:"\f6cc"}.fa-sketch:before{content:"\f7c6"}.fa-yandex-international:before{content:"\f414"}.fa-cc-amex:before{content:"\f1f3"}.fa-uber:before{content:"\f402"}.fa-github:before{content:"\f09b"}.fa-php:before{content:"\f457"}.fa-alipay:before{content:"\f642"}.fa-youtube:before{content:"\f167"}.fa-skyatlas:before{content:"\f216"}.fa-firefox-browser:before{content:"\e007"}.fa-replyd:before{content:"\f3e6"}.fa-suse:before{content:"\f7d6"}.fa-jenkins:before{content:"\f3b6"}.fa-twitter:before{content:"\f099"}.fa-rockrms:before{content:"\f3e9"}.fa-pinterest:before{content:"\f0d2"}.fa-buffer:before{content:"\f837"}.fa-npm:before{content:"\f3d4"}.fa-yammer:before{content:"\f840"}.fa-btc:before{content:"\f15a"}.fa-dribbble:before{content:"\f17d"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-internet-explorer:before{content:"\f26b"}.fa-stubber:before{content:"\e5c7"}.fa-telegram-plane:before,.fa-telegram:before{content:"\f2c6"}.fa-old-republic:before{content:"\f510"}.fa-odysee:before{content:"\e5c6"}.fa-square-whatsapp:before,.fa-whatsapp-square:before{content:"\f40c"}.fa-node-js:before{content:"\f3d3"}.fa-edge-legacy:before{content:"\e078"}.fa-slack-hash:before,.fa-slack:before{content:"\f198"}.fa-medrt:before{content:"\f3c8"}.fa-usb:before{content:"\f287"}.fa-tumblr:before{content:"\f173"}.fa-vaadin:before{content:"\f408"}.fa-quora:before{content:"\f2c4"}.fa-square-x-twitter:before{content:"\e61a"}.fa-reacteurope:before{content:"\f75d"}.fa-medium-m:before,.fa-medium:before{content:"\f23a"}.fa-amilia:before{content:"\f36d"}.fa-mixcloud:before{content:"\f289"}.fa-flipboard:before{content:"\f44d"}.fa-viacoin:before{content:"\f237"}.fa-critical-role:before{content:"\f6c9"}.fa-sitrox:before{content:"\e44a"}.fa-discourse:before{content:"\f393"}.fa-joomla:before{content:"\f1aa"}.fa-mastodon:before{content:"\f4f6"}.fa-airbnb:before{content:"\f834"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-buy-n-large:before{content:"\f8a6"}.fa-gulp:before{content:"\f3ae"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-strava:before{content:"\f428"}.fa-ember:before{content:"\f423"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-teamspeak:before{content:"\f4f9"}.fa-pushed:before{content:"\f3e1"}.fa-wordpress-simple:before{content:"\f411"}.fa-nutritionix:before{content:"\f3d6"}.fa-wodu:before{content:"\e088"}.fa-google-pay:before{content:"\e079"}.fa-intercom:before{content:"\f7af"}.fa-zhihu:before{content:"\f63f"}.fa-korvue:before{content:"\f42f"}.fa-pix:before{content:"\e43a"}.fa-steam-symbol:before{content:"\f3f6"}:host,:root{--fa-font-regular:normal 400 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:400;font-display:block;src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); }.fa-regular,.far{font-weight:400}:host,:root{--fa-style-family-classic:"Font Awesome 6 Free";--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:900;font-display:block;src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); }.fa-solid,.fas{font-weight:900}@font-face{font-family:"Font Awesome 5 Brands";font-display:block;font-weight:400;src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); }@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:900;src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); }@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:400;src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); }@font-face{font-family:"FontAwesome";font-display:block;src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); }@font-face{font-family:"FontAwesome";font-display:block;src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); }@font-face{font-family:"FontAwesome";font-display:block;src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); }@font-face{font-family:"FontAwesome";font-display:block;src: url("../webfonts/fa-v4compatibility.woff2") format("woff2"), url("../webfonts/fa-v4compatibility.ttf") format("truetype"); } \ No newline at end of file diff --git a/docs/deps/font-awesome-6.5.2/css/v4-shims.css b/docs/deps/font-awesome-6.5.2/css/v4-shims.css new file mode 100644 index 00000000..ea60ea4d --- /dev/null +++ b/docs/deps/font-awesome-6.5.2/css/v4-shims.css @@ -0,0 +1,2194 @@ +/*! + * Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + * Copyright 2024 Fonticons, Inc. + */ +.fa.fa-glass:before { + content: "\f000"; } + +.fa.fa-envelope-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-envelope-o:before { + content: "\f0e0"; } + +.fa.fa-star-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-star-o:before { + content: "\f005"; } + +.fa.fa-remove:before { + content: "\f00d"; } + +.fa.fa-close:before { + content: "\f00d"; } + +.fa.fa-gear:before { + content: "\f013"; } + +.fa.fa-trash-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-trash-o:before { + content: "\f2ed"; } + +.fa.fa-home:before { + content: "\f015"; } + +.fa.fa-file-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-file-o:before { + content: "\f15b"; } + +.fa.fa-clock-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-clock-o:before { + content: "\f017"; } + +.fa.fa-arrow-circle-o-down { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-arrow-circle-o-down:before { + content: "\f358"; } + +.fa.fa-arrow-circle-o-up { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-arrow-circle-o-up:before { + content: "\f35b"; } + +.fa.fa-play-circle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-play-circle-o:before { + content: "\f144"; } + +.fa.fa-repeat:before { + content: "\f01e"; } + +.fa.fa-rotate-right:before { + content: "\f01e"; } + +.fa.fa-refresh:before { + content: "\f021"; } + +.fa.fa-list-alt { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-list-alt:before { + content: "\f022"; } + +.fa.fa-dedent:before { + content: "\f03b"; } + +.fa.fa-video-camera:before { + content: "\f03d"; } + +.fa.fa-picture-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-picture-o:before { + content: "\f03e"; } + +.fa.fa-photo { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-photo:before { + content: "\f03e"; } + +.fa.fa-image { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-image:before { + content: "\f03e"; } + +.fa.fa-map-marker:before { + content: "\f3c5"; } + +.fa.fa-pencil-square-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-pencil-square-o:before { + content: "\f044"; } + +.fa.fa-edit { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-edit:before { + content: "\f044"; } + +.fa.fa-share-square-o:before { + content: "\f14d"; } + +.fa.fa-check-square-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-check-square-o:before { + content: "\f14a"; } + +.fa.fa-arrows:before { + content: "\f0b2"; } + +.fa.fa-times-circle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-times-circle-o:before { + content: "\f057"; } + +.fa.fa-check-circle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-check-circle-o:before { + content: "\f058"; } + +.fa.fa-mail-forward:before { + content: "\f064"; } + +.fa.fa-expand:before { + content: "\f424"; } + +.fa.fa-compress:before { + content: "\f422"; } + +.fa.fa-eye { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-eye-slash { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-warning:before { + content: "\f071"; } + +.fa.fa-calendar:before { + content: "\f073"; } + +.fa.fa-arrows-v:before { + content: "\f338"; } + +.fa.fa-arrows-h:before { + content: "\f337"; } + +.fa.fa-bar-chart:before { + content: "\e0e3"; } + +.fa.fa-bar-chart-o:before { + content: "\e0e3"; } + +.fa.fa-twitter-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-twitter-square:before { + content: "\f081"; } + +.fa.fa-facebook-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-facebook-square:before { + content: "\f082"; } + +.fa.fa-gears:before { + content: "\f085"; } + +.fa.fa-thumbs-o-up { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-thumbs-o-up:before { + content: "\f164"; } + +.fa.fa-thumbs-o-down { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-thumbs-o-down:before { + content: "\f165"; } + +.fa.fa-heart-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-heart-o:before { + content: "\f004"; } + +.fa.fa-sign-out:before { + content: "\f2f5"; } + +.fa.fa-linkedin-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-linkedin-square:before { + content: "\f08c"; } + +.fa.fa-thumb-tack:before { + content: "\f08d"; } + +.fa.fa-external-link:before { + content: "\f35d"; } + +.fa.fa-sign-in:before { + content: "\f2f6"; } + +.fa.fa-github-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-github-square:before { + content: "\f092"; } + +.fa.fa-lemon-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-lemon-o:before { + content: "\f094"; } + +.fa.fa-square-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-square-o:before { + content: "\f0c8"; } + +.fa.fa-bookmark-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-bookmark-o:before { + content: "\f02e"; } + +.fa.fa-twitter { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-facebook { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-facebook:before { + content: "\f39e"; } + +.fa.fa-facebook-f { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-facebook-f:before { + content: "\f39e"; } + +.fa.fa-github { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-credit-card { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-feed:before { + content: "\f09e"; } + +.fa.fa-hdd-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-hdd-o:before { + content: "\f0a0"; } + +.fa.fa-hand-o-right { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-hand-o-right:before { + content: "\f0a4"; } + +.fa.fa-hand-o-left { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-hand-o-left:before { + content: "\f0a5"; } + +.fa.fa-hand-o-up { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-hand-o-up:before { + content: "\f0a6"; } + +.fa.fa-hand-o-down { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-hand-o-down:before { + content: "\f0a7"; } + +.fa.fa-globe:before { + content: "\f57d"; } + +.fa.fa-tasks:before { + content: "\f828"; } + +.fa.fa-arrows-alt:before { + content: "\f31e"; } + +.fa.fa-group:before { + content: "\f0c0"; } + +.fa.fa-chain:before { + content: "\f0c1"; } + +.fa.fa-cut:before { + content: "\f0c4"; } + +.fa.fa-files-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-files-o:before { + content: "\f0c5"; } + +.fa.fa-floppy-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-floppy-o:before { + content: "\f0c7"; } + +.fa.fa-save { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-save:before { + content: "\f0c7"; } + +.fa.fa-navicon:before { + content: "\f0c9"; } + +.fa.fa-reorder:before { + content: "\f0c9"; } + +.fa.fa-magic:before { + content: "\e2ca"; } + +.fa.fa-pinterest { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-pinterest-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-pinterest-square:before { + content: "\f0d3"; } + +.fa.fa-google-plus-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-google-plus-square:before { + content: "\f0d4"; } + +.fa.fa-google-plus { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-google-plus:before { + content: "\f0d5"; } + +.fa.fa-money:before { + content: "\f3d1"; } + +.fa.fa-unsorted:before { + content: "\f0dc"; } + +.fa.fa-sort-desc:before { + content: "\f0dd"; } + +.fa.fa-sort-asc:before { + content: "\f0de"; } + +.fa.fa-linkedin { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-linkedin:before { + content: "\f0e1"; } + +.fa.fa-rotate-left:before { + content: "\f0e2"; } + +.fa.fa-legal:before { + content: "\f0e3"; } + +.fa.fa-tachometer:before { + content: "\f625"; } + +.fa.fa-dashboard:before { + content: "\f625"; } + +.fa.fa-comment-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-comment-o:before { + content: "\f075"; } + +.fa.fa-comments-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-comments-o:before { + content: "\f086"; } + +.fa.fa-flash:before { + content: "\f0e7"; } + +.fa.fa-clipboard:before { + content: "\f0ea"; } + +.fa.fa-lightbulb-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-lightbulb-o:before { + content: "\f0eb"; } + +.fa.fa-exchange:before { + content: "\f362"; } + +.fa.fa-cloud-download:before { + content: "\f0ed"; } + +.fa.fa-cloud-upload:before { + content: "\f0ee"; } + +.fa.fa-bell-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-bell-o:before { + content: "\f0f3"; } + +.fa.fa-cutlery:before { + content: "\f2e7"; } + +.fa.fa-file-text-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-file-text-o:before { + content: "\f15c"; } + +.fa.fa-building-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-building-o:before { + content: "\f1ad"; } + +.fa.fa-hospital-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-hospital-o:before { + content: "\f0f8"; } + +.fa.fa-tablet:before { + content: "\f3fa"; } + +.fa.fa-mobile:before { + content: "\f3cd"; } + +.fa.fa-mobile-phone:before { + content: "\f3cd"; } + +.fa.fa-circle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-circle-o:before { + content: "\f111"; } + +.fa.fa-mail-reply:before { + content: "\f3e5"; } + +.fa.fa-github-alt { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-folder-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-folder-o:before { + content: "\f07b"; } + +.fa.fa-folder-open-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-folder-open-o:before { + content: "\f07c"; } + +.fa.fa-smile-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-smile-o:before { + content: "\f118"; } + +.fa.fa-frown-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-frown-o:before { + content: "\f119"; } + +.fa.fa-meh-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-meh-o:before { + content: "\f11a"; } + +.fa.fa-keyboard-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-keyboard-o:before { + content: "\f11c"; } + +.fa.fa-flag-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-flag-o:before { + content: "\f024"; } + +.fa.fa-mail-reply-all:before { + content: "\f122"; } + +.fa.fa-star-half-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-star-half-o:before { + content: "\f5c0"; } + +.fa.fa-star-half-empty { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-star-half-empty:before { + content: "\f5c0"; } + +.fa.fa-star-half-full { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-star-half-full:before { + content: "\f5c0"; } + +.fa.fa-code-fork:before { + content: "\f126"; } + +.fa.fa-chain-broken:before { + content: "\f127"; } + +.fa.fa-unlink:before { + content: "\f127"; } + +.fa.fa-calendar-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-calendar-o:before { + content: "\f133"; } + +.fa.fa-maxcdn { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-html5 { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-css3 { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-unlock-alt:before { + content: "\f09c"; } + +.fa.fa-minus-square-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-minus-square-o:before { + content: "\f146"; } + +.fa.fa-level-up:before { + content: "\f3bf"; } + +.fa.fa-level-down:before { + content: "\f3be"; } + +.fa.fa-pencil-square:before { + content: "\f14b"; } + +.fa.fa-external-link-square:before { + content: "\f360"; } + +.fa.fa-compass { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-caret-square-o-down { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-caret-square-o-down:before { + content: "\f150"; } + +.fa.fa-toggle-down { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-toggle-down:before { + content: "\f150"; } + +.fa.fa-caret-square-o-up { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-caret-square-o-up:before { + content: "\f151"; } + +.fa.fa-toggle-up { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-toggle-up:before { + content: "\f151"; } + +.fa.fa-caret-square-o-right { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-caret-square-o-right:before { + content: "\f152"; } + +.fa.fa-toggle-right { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-toggle-right:before { + content: "\f152"; } + +.fa.fa-eur:before { + content: "\f153"; } + +.fa.fa-euro:before { + content: "\f153"; } + +.fa.fa-gbp:before { + content: "\f154"; } + +.fa.fa-usd:before { + content: "\24"; } + +.fa.fa-dollar:before { + content: "\24"; } + +.fa.fa-inr:before { + content: "\e1bc"; } + +.fa.fa-rupee:before { + content: "\e1bc"; } + +.fa.fa-jpy:before { + content: "\f157"; } + +.fa.fa-cny:before { + content: "\f157"; } + +.fa.fa-rmb:before { + content: "\f157"; } + +.fa.fa-yen:before { + content: "\f157"; } + +.fa.fa-rub:before { + content: "\f158"; } + +.fa.fa-ruble:before { + content: "\f158"; } + +.fa.fa-rouble:before { + content: "\f158"; } + +.fa.fa-krw:before { + content: "\f159"; } + +.fa.fa-won:before { + content: "\f159"; } + +.fa.fa-btc { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-bitcoin { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-bitcoin:before { + content: "\f15a"; } + +.fa.fa-file-text:before { + content: "\f15c"; } + +.fa.fa-sort-alpha-asc:before { + content: "\f15d"; } + +.fa.fa-sort-alpha-desc:before { + content: "\f881"; } + +.fa.fa-sort-amount-asc:before { + content: "\f884"; } + +.fa.fa-sort-amount-desc:before { + content: "\f160"; } + +.fa.fa-sort-numeric-asc:before { + content: "\f162"; } + +.fa.fa-sort-numeric-desc:before { + content: "\f886"; } + +.fa.fa-youtube-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-youtube-square:before { + content: "\f431"; } + +.fa.fa-youtube { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-xing { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-xing-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-xing-square:before { + content: "\f169"; } + +.fa.fa-youtube-play { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-youtube-play:before { + content: "\f167"; } + +.fa.fa-dropbox { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-stack-overflow { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-instagram { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-flickr { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-adn { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-bitbucket { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-bitbucket-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-bitbucket-square:before { + content: "\f171"; } + +.fa.fa-tumblr { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-tumblr-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-tumblr-square:before { + content: "\f174"; } + +.fa.fa-long-arrow-down:before { + content: "\f309"; } + +.fa.fa-long-arrow-up:before { + content: "\f30c"; } + +.fa.fa-long-arrow-left:before { + content: "\f30a"; } + +.fa.fa-long-arrow-right:before { + content: "\f30b"; } + +.fa.fa-apple { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-windows { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-android { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-linux { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-dribbble { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-skype { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-foursquare { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-trello { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-gratipay { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-gittip { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-gittip:before { + content: "\f184"; } + +.fa.fa-sun-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-sun-o:before { + content: "\f185"; } + +.fa.fa-moon-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-moon-o:before { + content: "\f186"; } + +.fa.fa-vk { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-weibo { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-renren { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-pagelines { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-stack-exchange { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-arrow-circle-o-right { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-arrow-circle-o-right:before { + content: "\f35a"; } + +.fa.fa-arrow-circle-o-left { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-arrow-circle-o-left:before { + content: "\f359"; } + +.fa.fa-caret-square-o-left { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-caret-square-o-left:before { + content: "\f191"; } + +.fa.fa-toggle-left { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-toggle-left:before { + content: "\f191"; } + +.fa.fa-dot-circle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-dot-circle-o:before { + content: "\f192"; } + +.fa.fa-vimeo-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-vimeo-square:before { + content: "\f194"; } + +.fa.fa-try:before { + content: "\e2bb"; } + +.fa.fa-turkish-lira:before { + content: "\e2bb"; } + +.fa.fa-plus-square-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-plus-square-o:before { + content: "\f0fe"; } + +.fa.fa-slack { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-wordpress { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-openid { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-institution:before { + content: "\f19c"; } + +.fa.fa-bank:before { + content: "\f19c"; } + +.fa.fa-mortar-board:before { + content: "\f19d"; } + +.fa.fa-yahoo { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-google { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-reddit { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-reddit-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-reddit-square:before { + content: "\f1a2"; } + +.fa.fa-stumbleupon-circle { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-stumbleupon { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-delicious { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-digg { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-pied-piper-pp { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-pied-piper-alt { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-drupal { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-joomla { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-behance { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-behance-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-behance-square:before { + content: "\f1b5"; } + +.fa.fa-steam { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-steam-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-steam-square:before { + content: "\f1b7"; } + +.fa.fa-automobile:before { + content: "\f1b9"; } + +.fa.fa-cab:before { + content: "\f1ba"; } + +.fa.fa-spotify { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-deviantart { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-soundcloud { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-file-pdf-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-file-pdf-o:before { + content: "\f1c1"; } + +.fa.fa-file-word-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-file-word-o:before { + content: "\f1c2"; } + +.fa.fa-file-excel-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-file-excel-o:before { + content: "\f1c3"; } + +.fa.fa-file-powerpoint-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-file-powerpoint-o:before { + content: "\f1c4"; } + +.fa.fa-file-image-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-file-image-o:before { + content: "\f1c5"; } + +.fa.fa-file-photo-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-file-photo-o:before { + content: "\f1c5"; } + +.fa.fa-file-picture-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-file-picture-o:before { + content: "\f1c5"; } + +.fa.fa-file-archive-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-file-archive-o:before { + content: "\f1c6"; } + +.fa.fa-file-zip-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-file-zip-o:before { + content: "\f1c6"; } + +.fa.fa-file-audio-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-file-audio-o:before { + content: "\f1c7"; } + +.fa.fa-file-sound-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-file-sound-o:before { + content: "\f1c7"; } + +.fa.fa-file-video-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-file-video-o:before { + content: "\f1c8"; } + +.fa.fa-file-movie-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-file-movie-o:before { + content: "\f1c8"; } + +.fa.fa-file-code-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-file-code-o:before { + content: "\f1c9"; } + +.fa.fa-vine { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-codepen { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-jsfiddle { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-life-bouy:before { + content: "\f1cd"; } + +.fa.fa-life-buoy:before { + content: "\f1cd"; } + +.fa.fa-life-saver:before { + content: "\f1cd"; } + +.fa.fa-support:before { + content: "\f1cd"; } + +.fa.fa-circle-o-notch:before { + content: "\f1ce"; } + +.fa.fa-rebel { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-ra { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-ra:before { + content: "\f1d0"; } + +.fa.fa-resistance { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-resistance:before { + content: "\f1d0"; } + +.fa.fa-empire { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-ge { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-ge:before { + content: "\f1d1"; } + +.fa.fa-git-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-git-square:before { + content: "\f1d2"; } + +.fa.fa-git { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-hacker-news { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-y-combinator-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-y-combinator-square:before { + content: "\f1d4"; } + +.fa.fa-yc-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-yc-square:before { + content: "\f1d4"; } + +.fa.fa-tencent-weibo { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-qq { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-weixin { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-wechat { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-wechat:before { + content: "\f1d7"; } + +.fa.fa-send:before { + content: "\f1d8"; } + +.fa.fa-paper-plane-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-paper-plane-o:before { + content: "\f1d8"; } + +.fa.fa-send-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-send-o:before { + content: "\f1d8"; } + +.fa.fa-circle-thin { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-circle-thin:before { + content: "\f111"; } + +.fa.fa-header:before { + content: "\f1dc"; } + +.fa.fa-futbol-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-futbol-o:before { + content: "\f1e3"; } + +.fa.fa-soccer-ball-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-soccer-ball-o:before { + content: "\f1e3"; } + +.fa.fa-slideshare { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-twitch { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-yelp { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-newspaper-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-newspaper-o:before { + content: "\f1ea"; } + +.fa.fa-paypal { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-google-wallet { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-cc-visa { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-cc-mastercard { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-cc-discover { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-cc-amex { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-cc-paypal { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-cc-stripe { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-bell-slash-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-bell-slash-o:before { + content: "\f1f6"; } + +.fa.fa-trash:before { + content: "\f2ed"; } + +.fa.fa-copyright { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-eyedropper:before { + content: "\f1fb"; } + +.fa.fa-area-chart:before { + content: "\f1fe"; } + +.fa.fa-pie-chart:before { + content: "\f200"; } + +.fa.fa-line-chart:before { + content: "\f201"; } + +.fa.fa-lastfm { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-lastfm-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-lastfm-square:before { + content: "\f203"; } + +.fa.fa-ioxhost { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-angellist { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-cc { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-cc:before { + content: "\f20a"; } + +.fa.fa-ils:before { + content: "\f20b"; } + +.fa.fa-shekel:before { + content: "\f20b"; } + +.fa.fa-sheqel:before { + content: "\f20b"; } + +.fa.fa-buysellads { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-connectdevelop { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-dashcube { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-forumbee { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-leanpub { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-sellsy { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-shirtsinbulk { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-simplybuilt { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-skyatlas { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-diamond { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-diamond:before { + content: "\f3a5"; } + +.fa.fa-transgender:before { + content: "\f224"; } + +.fa.fa-intersex:before { + content: "\f224"; } + +.fa.fa-transgender-alt:before { + content: "\f225"; } + +.fa.fa-facebook-official { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-facebook-official:before { + content: "\f09a"; } + +.fa.fa-pinterest-p { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-whatsapp { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-hotel:before { + content: "\f236"; } + +.fa.fa-viacoin { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-medium { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-y-combinator { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-yc { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-yc:before { + content: "\f23b"; } + +.fa.fa-optin-monster { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-opencart { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-expeditedssl { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-battery-4:before { + content: "\f240"; } + +.fa.fa-battery:before { + content: "\f240"; } + +.fa.fa-battery-3:before { + content: "\f241"; } + +.fa.fa-battery-2:before { + content: "\f242"; } + +.fa.fa-battery-1:before { + content: "\f243"; } + +.fa.fa-battery-0:before { + content: "\f244"; } + +.fa.fa-object-group { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-object-ungroup { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-sticky-note-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-sticky-note-o:before { + content: "\f249"; } + +.fa.fa-cc-jcb { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-cc-diners-club { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-clone { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-hourglass-o:before { + content: "\f254"; } + +.fa.fa-hourglass-1:before { + content: "\f251"; } + +.fa.fa-hourglass-2:before { + content: "\f252"; } + +.fa.fa-hourglass-3:before { + content: "\f253"; } + +.fa.fa-hand-rock-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-hand-rock-o:before { + content: "\f255"; } + +.fa.fa-hand-grab-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-hand-grab-o:before { + content: "\f255"; } + +.fa.fa-hand-paper-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-hand-paper-o:before { + content: "\f256"; } + +.fa.fa-hand-stop-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-hand-stop-o:before { + content: "\f256"; } + +.fa.fa-hand-scissors-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-hand-scissors-o:before { + content: "\f257"; } + +.fa.fa-hand-lizard-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-hand-lizard-o:before { + content: "\f258"; } + +.fa.fa-hand-spock-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-hand-spock-o:before { + content: "\f259"; } + +.fa.fa-hand-pointer-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-hand-pointer-o:before { + content: "\f25a"; } + +.fa.fa-hand-peace-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-hand-peace-o:before { + content: "\f25b"; } + +.fa.fa-registered { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-creative-commons { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-gg { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-gg-circle { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-odnoklassniki { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-odnoklassniki-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-odnoklassniki-square:before { + content: "\f264"; } + +.fa.fa-get-pocket { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-wikipedia-w { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-safari { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-chrome { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-firefox { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-opera { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-internet-explorer { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-television:before { + content: "\f26c"; } + +.fa.fa-contao { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-500px { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-amazon { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-calendar-plus-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-calendar-plus-o:before { + content: "\f271"; } + +.fa.fa-calendar-minus-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-calendar-minus-o:before { + content: "\f272"; } + +.fa.fa-calendar-times-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-calendar-times-o:before { + content: "\f273"; } + +.fa.fa-calendar-check-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-calendar-check-o:before { + content: "\f274"; } + +.fa.fa-map-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-map-o:before { + content: "\f279"; } + +.fa.fa-commenting:before { + content: "\f4ad"; } + +.fa.fa-commenting-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-commenting-o:before { + content: "\f4ad"; } + +.fa.fa-houzz { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-vimeo { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-vimeo:before { + content: "\f27d"; } + +.fa.fa-black-tie { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-fonticons { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-reddit-alien { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-edge { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-credit-card-alt:before { + content: "\f09d"; } + +.fa.fa-codiepie { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-modx { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-fort-awesome { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-usb { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-product-hunt { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-mixcloud { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-scribd { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-pause-circle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-pause-circle-o:before { + content: "\f28b"; } + +.fa.fa-stop-circle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-stop-circle-o:before { + content: "\f28d"; } + +.fa.fa-bluetooth { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-bluetooth-b { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-gitlab { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-wpbeginner { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-wpforms { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-envira { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-wheelchair-alt { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-wheelchair-alt:before { + content: "\f368"; } + +.fa.fa-question-circle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-question-circle-o:before { + content: "\f059"; } + +.fa.fa-volume-control-phone:before { + content: "\f2a0"; } + +.fa.fa-asl-interpreting:before { + content: "\f2a3"; } + +.fa.fa-deafness:before { + content: "\f2a4"; } + +.fa.fa-hard-of-hearing:before { + content: "\f2a4"; } + +.fa.fa-glide { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-glide-g { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-signing:before { + content: "\f2a7"; } + +.fa.fa-viadeo { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-viadeo-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-viadeo-square:before { + content: "\f2aa"; } + +.fa.fa-snapchat { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-snapchat-ghost { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-snapchat-ghost:before { + content: "\f2ab"; } + +.fa.fa-snapchat-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-snapchat-square:before { + content: "\f2ad"; } + +.fa.fa-pied-piper { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-first-order { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-yoast { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-themeisle { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-google-plus-official { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-google-plus-official:before { + content: "\f2b3"; } + +.fa.fa-google-plus-circle { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-google-plus-circle:before { + content: "\f2b3"; } + +.fa.fa-font-awesome { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-fa { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-fa:before { + content: "\f2b4"; } + +.fa.fa-handshake-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-handshake-o:before { + content: "\f2b5"; } + +.fa.fa-envelope-open-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-envelope-open-o:before { + content: "\f2b6"; } + +.fa.fa-linode { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-address-book-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-address-book-o:before { + content: "\f2b9"; } + +.fa.fa-vcard:before { + content: "\f2bb"; } + +.fa.fa-address-card-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-address-card-o:before { + content: "\f2bb"; } + +.fa.fa-vcard-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-vcard-o:before { + content: "\f2bb"; } + +.fa.fa-user-circle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-user-circle-o:before { + content: "\f2bd"; } + +.fa.fa-user-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-user-o:before { + content: "\f007"; } + +.fa.fa-id-badge { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-drivers-license:before { + content: "\f2c2"; } + +.fa.fa-id-card-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-id-card-o:before { + content: "\f2c2"; } + +.fa.fa-drivers-license-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-drivers-license-o:before { + content: "\f2c2"; } + +.fa.fa-quora { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-free-code-camp { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-telegram { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-thermometer-4:before { + content: "\f2c7"; } + +.fa.fa-thermometer:before { + content: "\f2c7"; } + +.fa.fa-thermometer-3:before { + content: "\f2c8"; } + +.fa.fa-thermometer-2:before { + content: "\f2c9"; } + +.fa.fa-thermometer-1:before { + content: "\f2ca"; } + +.fa.fa-thermometer-0:before { + content: "\f2cb"; } + +.fa.fa-bathtub:before { + content: "\f2cd"; } + +.fa.fa-s15:before { + content: "\f2cd"; } + +.fa.fa-window-maximize { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-window-restore { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-times-rectangle:before { + content: "\f410"; } + +.fa.fa-window-close-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-window-close-o:before { + content: "\f410"; } + +.fa.fa-times-rectangle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-times-rectangle-o:before { + content: "\f410"; } + +.fa.fa-bandcamp { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-grav { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-etsy { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-imdb { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-ravelry { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-eercast { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-eercast:before { + content: "\f2da"; } + +.fa.fa-snowflake-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; } + +.fa.fa-snowflake-o:before { + content: "\f2dc"; } + +.fa.fa-superpowers { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-wpexplorer { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa.fa-meetup { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; } diff --git a/docs/deps/font-awesome-6.5.2/css/v4-shims.min.css b/docs/deps/font-awesome-6.5.2/css/v4-shims.min.css new file mode 100644 index 00000000..09baf5fc --- /dev/null +++ b/docs/deps/font-awesome-6.5.2/css/v4-shims.min.css @@ -0,0 +1,6 @@ +/*! + * Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + * Copyright 2024 Fonticons, Inc. + */ +.fa.fa-glass:before{content:"\f000"}.fa.fa-envelope-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-envelope-o:before{content:"\f0e0"}.fa.fa-star-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-star-o:before{content:"\f005"}.fa.fa-close:before,.fa.fa-remove:before{content:"\f00d"}.fa.fa-gear:before{content:"\f013"}.fa.fa-trash-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-trash-o:before{content:"\f2ed"}.fa.fa-home:before{content:"\f015"}.fa.fa-file-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-o:before{content:"\f15b"}.fa.fa-clock-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-clock-o:before{content:"\f017"}.fa.fa-arrow-circle-o-down{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-arrow-circle-o-down:before{content:"\f358"}.fa.fa-arrow-circle-o-up{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-arrow-circle-o-up:before{content:"\f35b"}.fa.fa-play-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-play-circle-o:before{content:"\f144"}.fa.fa-repeat:before,.fa.fa-rotate-right:before{content:"\f01e"}.fa.fa-refresh:before{content:"\f021"}.fa.fa-list-alt{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-list-alt:before{content:"\f022"}.fa.fa-dedent:before{content:"\f03b"}.fa.fa-video-camera:before{content:"\f03d"}.fa.fa-picture-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-picture-o:before{content:"\f03e"}.fa.fa-photo{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-photo:before{content:"\f03e"}.fa.fa-image{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-image:before{content:"\f03e"}.fa.fa-map-marker:before{content:"\f3c5"}.fa.fa-pencil-square-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-pencil-square-o:before{content:"\f044"}.fa.fa-edit{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-edit:before{content:"\f044"}.fa.fa-share-square-o:before{content:"\f14d"}.fa.fa-check-square-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-check-square-o:before{content:"\f14a"}.fa.fa-arrows:before{content:"\f0b2"}.fa.fa-times-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-times-circle-o:before{content:"\f057"}.fa.fa-check-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-check-circle-o:before{content:"\f058"}.fa.fa-mail-forward:before{content:"\f064"}.fa.fa-expand:before{content:"\f424"}.fa.fa-compress:before{content:"\f422"}.fa.fa-eye,.fa.fa-eye-slash{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-warning:before{content:"\f071"}.fa.fa-calendar:before{content:"\f073"}.fa.fa-arrows-v:before{content:"\f338"}.fa.fa-arrows-h:before{content:"\f337"}.fa.fa-bar-chart-o:before,.fa.fa-bar-chart:before{content:"\e0e3"}.fa.fa-twitter-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-twitter-square:before{content:"\f081"}.fa.fa-facebook-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-facebook-square:before{content:"\f082"}.fa.fa-gears:before{content:"\f085"}.fa.fa-thumbs-o-up{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-thumbs-o-up:before{content:"\f164"}.fa.fa-thumbs-o-down{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-thumbs-o-down:before{content:"\f165"}.fa.fa-heart-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-heart-o:before{content:"\f004"}.fa.fa-sign-out:before{content:"\f2f5"}.fa.fa-linkedin-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-linkedin-square:before{content:"\f08c"}.fa.fa-thumb-tack:before{content:"\f08d"}.fa.fa-external-link:before{content:"\f35d"}.fa.fa-sign-in:before{content:"\f2f6"}.fa.fa-github-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-github-square:before{content:"\f092"}.fa.fa-lemon-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-lemon-o:before{content:"\f094"}.fa.fa-square-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-square-o:before{content:"\f0c8"}.fa.fa-bookmark-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-bookmark-o:before{content:"\f02e"}.fa.fa-facebook,.fa.fa-twitter{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-facebook:before{content:"\f39e"}.fa.fa-facebook-f{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-facebook-f:before{content:"\f39e"}.fa.fa-github{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-credit-card{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-feed:before{content:"\f09e"}.fa.fa-hdd-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hdd-o:before{content:"\f0a0"}.fa.fa-hand-o-right{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-o-right:before{content:"\f0a4"}.fa.fa-hand-o-left{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-o-left:before{content:"\f0a5"}.fa.fa-hand-o-up{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-o-up:before{content:"\f0a6"}.fa.fa-hand-o-down{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-o-down:before{content:"\f0a7"}.fa.fa-globe:before{content:"\f57d"}.fa.fa-tasks:before{content:"\f828"}.fa.fa-arrows-alt:before{content:"\f31e"}.fa.fa-group:before{content:"\f0c0"}.fa.fa-chain:before{content:"\f0c1"}.fa.fa-cut:before{content:"\f0c4"}.fa.fa-files-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-files-o:before{content:"\f0c5"}.fa.fa-floppy-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-floppy-o:before{content:"\f0c7"}.fa.fa-save{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-save:before{content:"\f0c7"}.fa.fa-navicon:before,.fa.fa-reorder:before{content:"\f0c9"}.fa.fa-magic:before{content:"\e2ca"}.fa.fa-pinterest,.fa.fa-pinterest-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-pinterest-square:before{content:"\f0d3"}.fa.fa-google-plus-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-google-plus-square:before{content:"\f0d4"}.fa.fa-google-plus{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-google-plus:before{content:"\f0d5"}.fa.fa-money:before{content:"\f3d1"}.fa.fa-unsorted:before{content:"\f0dc"}.fa.fa-sort-desc:before{content:"\f0dd"}.fa.fa-sort-asc:before{content:"\f0de"}.fa.fa-linkedin{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-linkedin:before{content:"\f0e1"}.fa.fa-rotate-left:before{content:"\f0e2"}.fa.fa-legal:before{content:"\f0e3"}.fa.fa-dashboard:before,.fa.fa-tachometer:before{content:"\f625"}.fa.fa-comment-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-comment-o:before{content:"\f075"}.fa.fa-comments-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-comments-o:before{content:"\f086"}.fa.fa-flash:before{content:"\f0e7"}.fa.fa-clipboard:before{content:"\f0ea"}.fa.fa-lightbulb-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-lightbulb-o:before{content:"\f0eb"}.fa.fa-exchange:before{content:"\f362"}.fa.fa-cloud-download:before{content:"\f0ed"}.fa.fa-cloud-upload:before{content:"\f0ee"}.fa.fa-bell-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-bell-o:before{content:"\f0f3"}.fa.fa-cutlery:before{content:"\f2e7"}.fa.fa-file-text-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-text-o:before{content:"\f15c"}.fa.fa-building-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-building-o:before{content:"\f1ad"}.fa.fa-hospital-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hospital-o:before{content:"\f0f8"}.fa.fa-tablet:before{content:"\f3fa"}.fa.fa-mobile-phone:before,.fa.fa-mobile:before{content:"\f3cd"}.fa.fa-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-circle-o:before{content:"\f111"}.fa.fa-mail-reply:before{content:"\f3e5"}.fa.fa-github-alt{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-folder-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-folder-o:before{content:"\f07b"}.fa.fa-folder-open-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-folder-open-o:before{content:"\f07c"}.fa.fa-smile-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-smile-o:before{content:"\f118"}.fa.fa-frown-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-frown-o:before{content:"\f119"}.fa.fa-meh-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-meh-o:before{content:"\f11a"}.fa.fa-keyboard-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-keyboard-o:before{content:"\f11c"}.fa.fa-flag-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-flag-o:before{content:"\f024"}.fa.fa-mail-reply-all:before{content:"\f122"}.fa.fa-star-half-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-star-half-o:before{content:"\f5c0"}.fa.fa-star-half-empty{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-star-half-empty:before{content:"\f5c0"}.fa.fa-star-half-full{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-star-half-full:before{content:"\f5c0"}.fa.fa-code-fork:before{content:"\f126"}.fa.fa-chain-broken:before,.fa.fa-unlink:before{content:"\f127"}.fa.fa-calendar-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-calendar-o:before{content:"\f133"}.fa.fa-css3,.fa.fa-html5,.fa.fa-maxcdn{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-unlock-alt:before{content:"\f09c"}.fa.fa-minus-square-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-minus-square-o:before{content:"\f146"}.fa.fa-level-up:before{content:"\f3bf"}.fa.fa-level-down:before{content:"\f3be"}.fa.fa-pencil-square:before{content:"\f14b"}.fa.fa-external-link-square:before{content:"\f360"}.fa.fa-compass{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-caret-square-o-down{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-caret-square-o-down:before{content:"\f150"}.fa.fa-toggle-down{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-toggle-down:before{content:"\f150"}.fa.fa-caret-square-o-up{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-caret-square-o-up:before{content:"\f151"}.fa.fa-toggle-up{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-toggle-up:before{content:"\f151"}.fa.fa-caret-square-o-right{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-caret-square-o-right:before{content:"\f152"}.fa.fa-toggle-right{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-toggle-right:before{content:"\f152"}.fa.fa-eur:before,.fa.fa-euro:before{content:"\f153"}.fa.fa-gbp:before{content:"\f154"}.fa.fa-dollar:before,.fa.fa-usd:before{content:"\24"}.fa.fa-inr:before,.fa.fa-rupee:before{content:"\e1bc"}.fa.fa-cny:before,.fa.fa-jpy:before,.fa.fa-rmb:before,.fa.fa-yen:before{content:"\f157"}.fa.fa-rouble:before,.fa.fa-rub:before,.fa.fa-ruble:before{content:"\f158"}.fa.fa-krw:before,.fa.fa-won:before{content:"\f159"}.fa.fa-bitcoin,.fa.fa-btc{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-bitcoin:before{content:"\f15a"}.fa.fa-file-text:before{content:"\f15c"}.fa.fa-sort-alpha-asc:before{content:"\f15d"}.fa.fa-sort-alpha-desc:before{content:"\f881"}.fa.fa-sort-amount-asc:before{content:"\f884"}.fa.fa-sort-amount-desc:before{content:"\f160"}.fa.fa-sort-numeric-asc:before{content:"\f162"}.fa.fa-sort-numeric-desc:before{content:"\f886"}.fa.fa-youtube-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-youtube-square:before{content:"\f431"}.fa.fa-xing,.fa.fa-xing-square,.fa.fa-youtube{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-xing-square:before{content:"\f169"}.fa.fa-youtube-play{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-youtube-play:before{content:"\f167"}.fa.fa-adn,.fa.fa-bitbucket,.fa.fa-bitbucket-square,.fa.fa-dropbox,.fa.fa-flickr,.fa.fa-instagram,.fa.fa-stack-overflow{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-bitbucket-square:before{content:"\f171"}.fa.fa-tumblr,.fa.fa-tumblr-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-tumblr-square:before{content:"\f174"}.fa.fa-long-arrow-down:before{content:"\f309"}.fa.fa-long-arrow-up:before{content:"\f30c"}.fa.fa-long-arrow-left:before{content:"\f30a"}.fa.fa-long-arrow-right:before{content:"\f30b"}.fa.fa-android,.fa.fa-apple,.fa.fa-dribbble,.fa.fa-foursquare,.fa.fa-gittip,.fa.fa-gratipay,.fa.fa-linux,.fa.fa-skype,.fa.fa-trello,.fa.fa-windows{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-gittip:before{content:"\f184"}.fa.fa-sun-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-sun-o:before{content:"\f185"}.fa.fa-moon-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-moon-o:before{content:"\f186"}.fa.fa-pagelines,.fa.fa-renren,.fa.fa-stack-exchange,.fa.fa-vk,.fa.fa-weibo{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-arrow-circle-o-right{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-arrow-circle-o-right:before{content:"\f35a"}.fa.fa-arrow-circle-o-left{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-arrow-circle-o-left:before{content:"\f359"}.fa.fa-caret-square-o-left{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-caret-square-o-left:before{content:"\f191"}.fa.fa-toggle-left{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-toggle-left:before{content:"\f191"}.fa.fa-dot-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-dot-circle-o:before{content:"\f192"}.fa.fa-vimeo-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-vimeo-square:before{content:"\f194"}.fa.fa-try:before,.fa.fa-turkish-lira:before{content:"\e2bb"}.fa.fa-plus-square-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-plus-square-o:before{content:"\f0fe"}.fa.fa-openid,.fa.fa-slack,.fa.fa-wordpress{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-bank:before,.fa.fa-institution:before{content:"\f19c"}.fa.fa-mortar-board:before{content:"\f19d"}.fa.fa-google,.fa.fa-reddit,.fa.fa-reddit-square,.fa.fa-yahoo{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-reddit-square:before{content:"\f1a2"}.fa.fa-behance,.fa.fa-behance-square,.fa.fa-delicious,.fa.fa-digg,.fa.fa-drupal,.fa.fa-joomla,.fa.fa-pied-piper-alt,.fa.fa-pied-piper-pp,.fa.fa-stumbleupon,.fa.fa-stumbleupon-circle{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-behance-square:before{content:"\f1b5"}.fa.fa-steam,.fa.fa-steam-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-steam-square:before{content:"\f1b7"}.fa.fa-automobile:before{content:"\f1b9"}.fa.fa-cab:before{content:"\f1ba"}.fa.fa-deviantart,.fa.fa-soundcloud,.fa.fa-spotify{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-file-pdf-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-pdf-o:before{content:"\f1c1"}.fa.fa-file-word-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-word-o:before{content:"\f1c2"}.fa.fa-file-excel-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-excel-o:before{content:"\f1c3"}.fa.fa-file-powerpoint-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-powerpoint-o:before{content:"\f1c4"}.fa.fa-file-image-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-image-o:before{content:"\f1c5"}.fa.fa-file-photo-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-photo-o:before{content:"\f1c5"}.fa.fa-file-picture-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-picture-o:before{content:"\f1c5"}.fa.fa-file-archive-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-archive-o:before{content:"\f1c6"}.fa.fa-file-zip-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-zip-o:before{content:"\f1c6"}.fa.fa-file-audio-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-audio-o:before{content:"\f1c7"}.fa.fa-file-sound-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-sound-o:before{content:"\f1c7"}.fa.fa-file-video-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-video-o:before{content:"\f1c8"}.fa.fa-file-movie-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-movie-o:before{content:"\f1c8"}.fa.fa-file-code-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-code-o:before{content:"\f1c9"}.fa.fa-codepen,.fa.fa-jsfiddle,.fa.fa-vine{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-life-bouy:before,.fa.fa-life-buoy:before,.fa.fa-life-saver:before,.fa.fa-support:before{content:"\f1cd"}.fa.fa-circle-o-notch:before{content:"\f1ce"}.fa.fa-ra,.fa.fa-rebel{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-ra:before{content:"\f1d0"}.fa.fa-resistance{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-resistance:before{content:"\f1d0"}.fa.fa-empire,.fa.fa-ge{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-ge:before{content:"\f1d1"}.fa.fa-git-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-git-square:before{content:"\f1d2"}.fa.fa-git,.fa.fa-hacker-news,.fa.fa-y-combinator-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-y-combinator-square:before{content:"\f1d4"}.fa.fa-yc-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-yc-square:before{content:"\f1d4"}.fa.fa-qq,.fa.fa-tencent-weibo,.fa.fa-wechat,.fa.fa-weixin{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-wechat:before{content:"\f1d7"}.fa.fa-send:before{content:"\f1d8"}.fa.fa-paper-plane-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-paper-plane-o:before{content:"\f1d8"}.fa.fa-send-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-send-o:before{content:"\f1d8"}.fa.fa-circle-thin{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-circle-thin:before{content:"\f111"}.fa.fa-header:before{content:"\f1dc"}.fa.fa-futbol-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-futbol-o:before{content:"\f1e3"}.fa.fa-soccer-ball-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-soccer-ball-o:before{content:"\f1e3"}.fa.fa-slideshare,.fa.fa-twitch,.fa.fa-yelp{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-newspaper-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-newspaper-o:before{content:"\f1ea"}.fa.fa-cc-amex,.fa.fa-cc-discover,.fa.fa-cc-mastercard,.fa.fa-cc-paypal,.fa.fa-cc-stripe,.fa.fa-cc-visa,.fa.fa-google-wallet,.fa.fa-paypal{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-bell-slash-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-bell-slash-o:before{content:"\f1f6"}.fa.fa-trash:before{content:"\f2ed"}.fa.fa-copyright{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-eyedropper:before{content:"\f1fb"}.fa.fa-area-chart:before{content:"\f1fe"}.fa.fa-pie-chart:before{content:"\f200"}.fa.fa-line-chart:before{content:"\f201"}.fa.fa-lastfm,.fa.fa-lastfm-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-lastfm-square:before{content:"\f203"}.fa.fa-angellist,.fa.fa-ioxhost{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-cc{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-cc:before{content:"\f20a"}.fa.fa-ils:before,.fa.fa-shekel:before,.fa.fa-sheqel:before{content:"\f20b"}.fa.fa-buysellads,.fa.fa-connectdevelop,.fa.fa-dashcube,.fa.fa-forumbee,.fa.fa-leanpub,.fa.fa-sellsy,.fa.fa-shirtsinbulk,.fa.fa-simplybuilt,.fa.fa-skyatlas{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-diamond{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-diamond:before{content:"\f3a5"}.fa.fa-intersex:before,.fa.fa-transgender:before{content:"\f224"}.fa.fa-transgender-alt:before{content:"\f225"}.fa.fa-facebook-official{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-facebook-official:before{content:"\f09a"}.fa.fa-pinterest-p,.fa.fa-whatsapp{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-hotel:before{content:"\f236"}.fa.fa-medium,.fa.fa-viacoin,.fa.fa-y-combinator,.fa.fa-yc{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-yc:before{content:"\f23b"}.fa.fa-expeditedssl,.fa.fa-opencart,.fa.fa-optin-monster{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-battery-4:before,.fa.fa-battery:before{content:"\f240"}.fa.fa-battery-3:before{content:"\f241"}.fa.fa-battery-2:before{content:"\f242"}.fa.fa-battery-1:before{content:"\f243"}.fa.fa-battery-0:before{content:"\f244"}.fa.fa-object-group,.fa.fa-object-ungroup,.fa.fa-sticky-note-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-sticky-note-o:before{content:"\f249"}.fa.fa-cc-diners-club,.fa.fa-cc-jcb{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-clone{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hourglass-o:before{content:"\f254"}.fa.fa-hourglass-1:before{content:"\f251"}.fa.fa-hourglass-2:before{content:"\f252"}.fa.fa-hourglass-3:before{content:"\f253"}.fa.fa-hand-rock-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-rock-o:before{content:"\f255"}.fa.fa-hand-grab-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-grab-o:before{content:"\f255"}.fa.fa-hand-paper-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-paper-o:before{content:"\f256"}.fa.fa-hand-stop-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-stop-o:before{content:"\f256"}.fa.fa-hand-scissors-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-scissors-o:before{content:"\f257"}.fa.fa-hand-lizard-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-lizard-o:before{content:"\f258"}.fa.fa-hand-spock-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-spock-o:before{content:"\f259"}.fa.fa-hand-pointer-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-pointer-o:before{content:"\f25a"}.fa.fa-hand-peace-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-peace-o:before{content:"\f25b"}.fa.fa-registered{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-creative-commons,.fa.fa-gg,.fa.fa-gg-circle,.fa.fa-odnoklassniki,.fa.fa-odnoklassniki-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-odnoklassniki-square:before{content:"\f264"}.fa.fa-chrome,.fa.fa-firefox,.fa.fa-get-pocket,.fa.fa-internet-explorer,.fa.fa-opera,.fa.fa-safari,.fa.fa-wikipedia-w{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-television:before{content:"\f26c"}.fa.fa-500px,.fa.fa-amazon,.fa.fa-contao{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-calendar-plus-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-calendar-plus-o:before{content:"\f271"}.fa.fa-calendar-minus-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-calendar-minus-o:before{content:"\f272"}.fa.fa-calendar-times-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-calendar-times-o:before{content:"\f273"}.fa.fa-calendar-check-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-calendar-check-o:before{content:"\f274"}.fa.fa-map-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-map-o:before{content:"\f279"}.fa.fa-commenting:before{content:"\f4ad"}.fa.fa-commenting-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-commenting-o:before{content:"\f4ad"}.fa.fa-houzz,.fa.fa-vimeo{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-vimeo:before{content:"\f27d"}.fa.fa-black-tie,.fa.fa-edge,.fa.fa-fonticons,.fa.fa-reddit-alien{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-credit-card-alt:before{content:"\f09d"}.fa.fa-codiepie,.fa.fa-fort-awesome,.fa.fa-mixcloud,.fa.fa-modx,.fa.fa-product-hunt,.fa.fa-scribd,.fa.fa-usb{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-pause-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-pause-circle-o:before{content:"\f28b"}.fa.fa-stop-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-stop-circle-o:before{content:"\f28d"}.fa.fa-bluetooth,.fa.fa-bluetooth-b,.fa.fa-envira,.fa.fa-gitlab,.fa.fa-wheelchair-alt,.fa.fa-wpbeginner,.fa.fa-wpforms{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-wheelchair-alt:before{content:"\f368"}.fa.fa-question-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-question-circle-o:before{content:"\f059"}.fa.fa-volume-control-phone:before{content:"\f2a0"}.fa.fa-asl-interpreting:before{content:"\f2a3"}.fa.fa-deafness:before,.fa.fa-hard-of-hearing:before{content:"\f2a4"}.fa.fa-glide,.fa.fa-glide-g{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-signing:before{content:"\f2a7"}.fa.fa-viadeo,.fa.fa-viadeo-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-viadeo-square:before{content:"\f2aa"}.fa.fa-snapchat,.fa.fa-snapchat-ghost{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-snapchat-ghost:before{content:"\f2ab"}.fa.fa-snapchat-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-snapchat-square:before{content:"\f2ad"}.fa.fa-first-order,.fa.fa-google-plus-official,.fa.fa-pied-piper,.fa.fa-themeisle,.fa.fa-yoast{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-google-plus-official:before{content:"\f2b3"}.fa.fa-google-plus-circle{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-google-plus-circle:before{content:"\f2b3"}.fa.fa-fa,.fa.fa-font-awesome{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-fa:before{content:"\f2b4"}.fa.fa-handshake-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-handshake-o:before{content:"\f2b5"}.fa.fa-envelope-open-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-envelope-open-o:before{content:"\f2b6"}.fa.fa-linode{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-address-book-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-address-book-o:before{content:"\f2b9"}.fa.fa-vcard:before{content:"\f2bb"}.fa.fa-address-card-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-address-card-o:before{content:"\f2bb"}.fa.fa-vcard-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-vcard-o:before{content:"\f2bb"}.fa.fa-user-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-user-circle-o:before{content:"\f2bd"}.fa.fa-user-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-user-o:before{content:"\f007"}.fa.fa-id-badge{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-drivers-license:before{content:"\f2c2"}.fa.fa-id-card-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-id-card-o:before{content:"\f2c2"}.fa.fa-drivers-license-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-drivers-license-o:before{content:"\f2c2"}.fa.fa-free-code-camp,.fa.fa-quora,.fa.fa-telegram{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-thermometer-4:before,.fa.fa-thermometer:before{content:"\f2c7"}.fa.fa-thermometer-3:before{content:"\f2c8"}.fa.fa-thermometer-2:before{content:"\f2c9"}.fa.fa-thermometer-1:before{content:"\f2ca"}.fa.fa-thermometer-0:before{content:"\f2cb"}.fa.fa-bathtub:before,.fa.fa-s15:before{content:"\f2cd"}.fa.fa-window-maximize,.fa.fa-window-restore{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-times-rectangle:before{content:"\f410"}.fa.fa-window-close-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-window-close-o:before{content:"\f410"}.fa.fa-times-rectangle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-times-rectangle-o:before{content:"\f410"}.fa.fa-bandcamp,.fa.fa-eercast,.fa.fa-etsy,.fa.fa-grav,.fa.fa-imdb,.fa.fa-ravelry{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-eercast:before{content:"\f2da"}.fa.fa-snowflake-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-snowflake-o:before{content:"\f2dc"}.fa.fa-meetup,.fa.fa-superpowers,.fa.fa-wpexplorer{font-family:"Font Awesome 6 Brands";font-weight:400} \ No newline at end of file diff --git a/docs/deps/font-awesome-6.5.2/webfonts/fa-brands-400.ttf b/docs/deps/font-awesome-6.5.2/webfonts/fa-brands-400.ttf new file mode 100644 index 00000000..1fbb1f7c Binary files /dev/null and b/docs/deps/font-awesome-6.5.2/webfonts/fa-brands-400.ttf differ diff --git a/docs/deps/font-awesome-6.5.2/webfonts/fa-brands-400.woff2 b/docs/deps/font-awesome-6.5.2/webfonts/fa-brands-400.woff2 new file mode 100644 index 00000000..5d280216 Binary files /dev/null and b/docs/deps/font-awesome-6.5.2/webfonts/fa-brands-400.woff2 differ diff --git a/docs/deps/font-awesome-6.5.2/webfonts/fa-regular-400.ttf b/docs/deps/font-awesome-6.5.2/webfonts/fa-regular-400.ttf new file mode 100644 index 00000000..549d68dc Binary files /dev/null and b/docs/deps/font-awesome-6.5.2/webfonts/fa-regular-400.ttf differ diff --git a/docs/deps/font-awesome-6.5.2/webfonts/fa-regular-400.woff2 b/docs/deps/font-awesome-6.5.2/webfonts/fa-regular-400.woff2 new file mode 100644 index 00000000..18400d7f Binary files /dev/null and b/docs/deps/font-awesome-6.5.2/webfonts/fa-regular-400.woff2 differ diff --git a/docs/deps/font-awesome-6.5.2/webfonts/fa-solid-900.ttf b/docs/deps/font-awesome-6.5.2/webfonts/fa-solid-900.ttf new file mode 100644 index 00000000..bb2a8695 Binary files /dev/null and b/docs/deps/font-awesome-6.5.2/webfonts/fa-solid-900.ttf differ diff --git a/docs/deps/font-awesome-6.5.2/webfonts/fa-solid-900.woff2 b/docs/deps/font-awesome-6.5.2/webfonts/fa-solid-900.woff2 new file mode 100644 index 00000000..758dd4f6 Binary files /dev/null and b/docs/deps/font-awesome-6.5.2/webfonts/fa-solid-900.woff2 differ diff --git a/docs/deps/font-awesome-6.5.2/webfonts/fa-v4compatibility.ttf b/docs/deps/font-awesome-6.5.2/webfonts/fa-v4compatibility.ttf new file mode 100644 index 00000000..8c5864c4 Binary files /dev/null and b/docs/deps/font-awesome-6.5.2/webfonts/fa-v4compatibility.ttf differ diff --git a/docs/deps/font-awesome-6.5.2/webfonts/fa-v4compatibility.woff2 b/docs/deps/font-awesome-6.5.2/webfonts/fa-v4compatibility.woff2 new file mode 100644 index 00000000..f94bec22 Binary files /dev/null and b/docs/deps/font-awesome-6.5.2/webfonts/fa-v4compatibility.woff2 differ diff --git a/docs/deps/headroom-0.11.0/headroom.min.js b/docs/deps/headroom-0.11.0/headroom.min.js new file mode 100644 index 00000000..433069fd --- /dev/null +++ b/docs/deps/headroom-0.11.0/headroom.min.js @@ -0,0 +1,7 @@ +/*! + * headroom.js v0.11.0 - Give your page some headroom. Hide your header until you need it + * Copyright (c) 2020 Nick Williams - http://wicky.nillia.ms/headroom.js + * License: MIT + */ + +!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).Headroom=n()}(this,function(){"use strict";function t(){return"undefined"!=typeof window}function d(t){return function(t){return t&&t.document&&function(t){return 9===t.nodeType}(t.document)}(t)?function(t){var n=t.document,o=n.body,s=n.documentElement;return{scrollHeight:function(){return Math.max(o.scrollHeight,s.scrollHeight,o.offsetHeight,s.offsetHeight,o.clientHeight,s.clientHeight)},height:function(){return t.innerHeight||s.clientHeight||o.clientHeight},scrollY:function(){return void 0!==t.pageYOffset?t.pageYOffset:(s||o.parentNode||o).scrollTop}}}(t):function(t){return{scrollHeight:function(){return Math.max(t.scrollHeight,t.offsetHeight,t.clientHeight)},height:function(){return Math.max(t.offsetHeight,t.clientHeight)},scrollY:function(){return t.scrollTop}}}(t)}function n(t,s,e){var n,o=function(){var n=!1;try{var t={get passive(){n=!0}};window.addEventListener("test",t,t),window.removeEventListener("test",t,t)}catch(t){n=!1}return n}(),i=!1,r=d(t),l=r.scrollY(),a={};function c(){var t=Math.round(r.scrollY()),n=r.height(),o=r.scrollHeight();a.scrollY=t,a.lastScrollY=l,a.direction=ls.tolerance[a.direction],e(a),l=t,i=!1}function h(){i||(i=!0,n=requestAnimationFrame(c))}var u=!!o&&{passive:!0,capture:!1};return t.addEventListener("scroll",h,u),c(),{destroy:function(){cancelAnimationFrame(n),t.removeEventListener("scroll",h,u)}}}function o(t,n){n=n||{},Object.assign(this,o.options,n),this.classes=Object.assign({},o.options.classes,n.classes),this.elem=t,this.tolerance=function(t){return t===Object(t)?t:{down:t,up:t}}(this.tolerance),this.initialised=!1,this.frozen=!1}return o.prototype={constructor:o,init:function(){return o.cutsTheMustard&&!this.initialised&&(this.addClass("initial"),this.initialised=!0,setTimeout(function(t){t.scrollTracker=n(t.scroller,{offset:t.offset,tolerance:t.tolerance},t.update.bind(t))},100,this)),this},destroy:function(){this.initialised=!1,Object.keys(this.classes).forEach(this.removeClass,this),this.scrollTracker.destroy()},unpin:function(){!this.hasClass("pinned")&&this.hasClass("unpinned")||(this.addClass("unpinned"),this.removeClass("pinned"),this.onUnpin&&this.onUnpin.call(this))},pin:function(){this.hasClass("unpinned")&&(this.addClass("pinned"),this.removeClass("unpinned"),this.onPin&&this.onPin.call(this))},freeze:function(){this.frozen=!0,this.addClass("frozen")},unfreeze:function(){this.frozen=!1,this.removeClass("frozen")},top:function(){this.hasClass("top")||(this.addClass("top"),this.removeClass("notTop"),this.onTop&&this.onTop.call(this))},notTop:function(){this.hasClass("notTop")||(this.addClass("notTop"),this.removeClass("top"),this.onNotTop&&this.onNotTop.call(this))},bottom:function(){this.hasClass("bottom")||(this.addClass("bottom"),this.removeClass("notBottom"),this.onBottom&&this.onBottom.call(this))},notBottom:function(){this.hasClass("notBottom")||(this.addClass("notBottom"),this.removeClass("bottom"),this.onNotBottom&&this.onNotBottom.call(this))},shouldUnpin:function(t){return"down"===t.direction&&!t.top&&t.toleranceExceeded},shouldPin:function(t){return"up"===t.direction&&t.toleranceExceeded||t.top},addClass:function(t){this.elem.classList.add.apply(this.elem.classList,this.classes[t].split(" "))},removeClass:function(t){this.elem.classList.remove.apply(this.elem.classList,this.classes[t].split(" "))},hasClass:function(t){return this.classes[t].split(" ").every(function(t){return this.classList.contains(t)},this.elem)},update:function(t){t.isOutOfBounds||!0!==this.frozen&&(t.top?this.top():this.notTop(),t.bottom?this.bottom():this.notBottom(),this.shouldUnpin(t)?this.unpin():this.shouldPin(t)&&this.pin())}},o.options={tolerance:{up:0,down:0},offset:0,scroller:t()?window:null,classes:{frozen:"headroom--frozen",pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",bottom:"headroom--bottom",notBottom:"headroom--not-bottom",initial:"headroom"}},o.cutsTheMustard=!!(t()&&function(){}.bind&&"classList"in document.documentElement&&Object.assign&&Object.keys&&requestAnimationFrame),o}); \ No newline at end of file diff --git a/docs/deps/headroom-0.11.0/jQuery.headroom.min.js b/docs/deps/headroom-0.11.0/jQuery.headroom.min.js new file mode 100644 index 00000000..17f70c9e --- /dev/null +++ b/docs/deps/headroom-0.11.0/jQuery.headroom.min.js @@ -0,0 +1,7 @@ +/*! + * headroom.js v0.9.4 - Give your page some headroom. Hide your header until you need it + * Copyright (c) 2017 Nick Williams - http://wicky.nillia.ms/headroom.js + * License: MIT + */ + +!function(a){a&&(a.fn.headroom=function(b){return this.each(function(){var c=a(this),d=c.data("headroom"),e="object"==typeof b&&b;e=a.extend(!0,{},Headroom.options,e),d||(d=new Headroom(this,e),d.init(),c.data("headroom",d)),"string"==typeof b&&(d[b](),"destroy"===b&&c.removeData("headroom"))})},a("[data-headroom]").each(function(){var b=a(this);b.headroom(b.data())}))}(window.Zepto||window.jQuery); \ No newline at end of file diff --git a/docs/deps/jquery-3.6.0/jquery-3.6.0.js b/docs/deps/jquery-3.6.0/jquery-3.6.0.js new file mode 100644 index 00000000..fc6c299b --- /dev/null +++ b/docs/deps/jquery-3.6.0/jquery-3.6.0.js @@ -0,0 +1,10881 @@ +/*! + * jQuery JavaScript Library v3.6.0 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright OpenJS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2021-03-02T17:08Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // 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 #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 ); + }; + } else { + factory( global ); + } + +// 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"; + +var arr = []; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +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; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +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"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + +var document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + 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 ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* 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.6.0", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + 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() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return flat( ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), + function( _i, name ) { + 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; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.6 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2021-02-16 + */ +( function( window ) { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // 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: http://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) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + 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" ), + + // 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" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// 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: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( 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; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // 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 ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // 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 ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // 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( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * 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 = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * 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" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split( "|" ), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // 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 ) { + + // 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 ) { + + // 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; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // 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; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * 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; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); +} + +/** + * Checks a node for validity as a Sizzle 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; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem && elem.namespaceURI, + docElem = elem && ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, 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; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // 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 ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // 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 ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // 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" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // 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 + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // 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( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); + } : + function( a, b ) { + if ( b ) { + while ( ( b = b.parentNode ) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // 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 && + contains( preferredDoc, a ) ) { + return -1; + } + + // 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 && + contains( preferredDoc, b ) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( ( cur = cur.parentNode ) ) { + ap.unshift( cur ); + } + cur = b; + while ( ( cur = cur.parentNode ) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[ i ] === bp[ i ] ) { + i++; + } + + return i ? + + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[ i ], bp[ i ] ) : + + // Otherwise nodes in our document sort first + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + + // 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 ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + + // 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 ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + + // 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 ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); + + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } + + return match.slice( 0, 4 ); + }, + + "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 ] ) { + Sizzle.error( match[ 0 ] ); + } + + // 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" ); + + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + 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 nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "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 = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + /* eslint-disable max-len */ + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + /* eslint-enable max-len */ + + }; + }, + + "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, uniqueCache, 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 ? + node.nodeName.toLowerCase() === 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 + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ 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 ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + + // Use previously-cached element index if available + if ( useCache ) { + + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ 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 ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + uniqueCache[ 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 + // http://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() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle 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( 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( rtrim, "$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 (issue #299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), + + "has": markFunction( function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + } ), + + "contains": markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( 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." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + Sizzle.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 === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && + ( !document.hasFocus || 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 + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); + }, + + "selected": function( elem ) { + + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + + // http://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 ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // 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 = argument < 0 ? + argument + length : + argument > length ? + length : + 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(); + +tokenize = Sizzle.tokenize = function( 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 = rcombinators.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrim, " " ) + } ); + 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 + return parseOnly ? + soFar.length : + soFar ? + Sizzle.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, uniqueCache, 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 ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = uniqueCache[ 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 + uniqueCache[ 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++ ) { + Sizzle( 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, + 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, + + matcherOut = matcher ? + + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // 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( 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( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + + // Avoid hanging onto element (issue #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( rtrim, "$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: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + 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 ) ) { + results.push( 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 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( 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 Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( 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 + +// Sort stability +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// 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; +} ); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert( function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + } ); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert( function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + } ); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; + } + } ); +} + +return Sizzle; + +} )( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +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; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +} +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 (#9521) + // Strict HTML recognition (#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 Sizzle + 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 ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +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 ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // 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 ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // 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.stackTrace ); + } + + // 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 { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + 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(); + }, + + // 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; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // 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; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the primary Deferred + primary = jQuery.Deferred(), + + // 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 ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( primary.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return primary.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); + } + + return primary.promise(); + } +} ); + + +// 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$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // 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, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // 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 ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// 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 ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// 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; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, _key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} + +// 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 (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +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 = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #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 + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + 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 ) { + + // 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 ) ) { + + return this.get( owner, key ); + } + + // 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 ); + + // 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 ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // 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 ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // 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 ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// 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 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // 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 ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // 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 ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // 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 ) { + + // 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; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // 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 ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // 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; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + 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", [] ); + }, + + // 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 ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + 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 ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // 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 ) && + + jQuery.css( elem, "display" ) === "none"; + }; + + + +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" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // 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; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // 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; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // 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"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // 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 ]; + } + } + + return elements; +} + +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 rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // 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, "", "
    " ], + + _default: [ 0, "", "" ] +}; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // 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; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// 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 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; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; + } + + // 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; + } + + // 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 ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + 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; + }; + } + + // 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(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // 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(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + 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 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + 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 ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // 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 ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // 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 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + 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 ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + 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 ) { + + // 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; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( 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; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // 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" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // 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; + } + } + } + } +}; + +// 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, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + 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 notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // 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 ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + + // Support: Chrome 86+ + // In Chrome, if an element having a focusout handler is blurred by + // clicking outside of it, it invokes the handler synchronously. If + // that handler calls `.remove()` on the element, the data is cleared, + // leaving `result` undefined. We need to guard against this. + return result && result.value; + } + + // 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 this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// 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, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// 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 ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + // Suppress native focus or blur as it's already being fired + // in leverageNative. + _default: function() { + return true; + }, + + delegateType: delegateType + }; +} ); + +// 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, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // 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; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + 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 ) { + + // ( 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; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + // 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 = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + // + // Support: Firefox 70+ + // Only Firefox includes border widths + // in computed dimensions. (gh-4529) + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; + tr.style.cssText = "border:1px solid"; + + // Support: Chrome 86+ + // Height set through cssText does not get applied. + // Computed height then comes back as 0. + tr.style.height = "1px"; + trChild.style.height = "9px"; + + // Support: Android 8 Chrome 86+ + // In our bodyBackground.html iframe, + // display for all div elements is set to "inline", + // which causes a problem only in Android 8 Chrome 86. + // Ensuring the div is display: block + // gets around this issue. + trChild.style.display = "block"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + + parseInt( trStyle.borderTopWidth, 10 ) + + parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +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 ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // 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() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// 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 ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // 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( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + 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; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // 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 + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + 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; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // 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 ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// 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 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// 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 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = { guid: Date.now() }; + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml, parserErrorElem; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) {} + + parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; + if ( !xml || parserErrorElem ) { + jQuery.error( "Invalid XML: " + ( + parserErrorElem ? + jQuery.map( parserErrorElem.childNodes, function( el ) { + return el.textContent; + } ).join( "\n" ) : + data + ) ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ).filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ).map( function( _i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + +originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Use a noop converter for missing script but not if jsonp + if ( !isSuccess && + jQuery.inArray( "script", s.dataTypes ) > -1 && + jQuery.inArray( "json", s.dataTypes ) < 0 ) { + s.converters[ "text script" ] = function() {}; + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( _i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); + + +jQuery._evalUrl = function( url, options, doc ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + + + + + + + + + + + Skip to contents + + +
    +
    +
    + + + +

    A package for performing Mendelian randomization using GWAS summary data. It uses the IEU OpenGWAS database to obtain data automatically, and a wide range of methods to run the analysis.

    +
    +

    January 2020 major update +

    +

    We have made substantial changes to the package, database and reference panels. For full details of the changes, please visit https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html

    +
    +
    +

    Installation +

    +

    Users running Windows and macOS, to install the latest version of TwoSampleMR please install from our MRC IEU r-universe

    +
    +install.packages("TwoSampleMR", repos = c("https://mrcieu.r-universe.dev", "https://cloud.r-project.org"))
    +

    Users running Linux or WebR please see the following instructions.

    +

    To update the package run the same command again.

    +
    +

    Installing from source +

    +
    +install.packages("remotes")
    +remotes::install_github("MRCIEU/TwoSampleMR")
    +

    To update the package just run the remotes::install_github("MRCIEU/TwoSampleMR") command again.

    +
    +
    +
    +

    Docker +

    +

    A multi-platform docker image containing R with the TwoSampleMR package pre-installed (for both x86_64 and ARM computers) is available here: https://hub.docker.com/r/mrcieu/twosamplemr

    +
    +
    +
    +
    + + +
    + + + +
    +
    + + + + + + + diff --git a/docs/katex-auto.js b/docs/katex-auto.js new file mode 100644 index 00000000..20651d9f --- /dev/null +++ b/docs/katex-auto.js @@ -0,0 +1,14 @@ +// https://github.com/jgm/pandoc/blob/29fa97ab96b8e2d62d48326e1b949a71dc41f47a/src/Text/Pandoc/Writers/HTML.hs#L332-L345 +document.addEventListener("DOMContentLoaded", function () { + var mathElements = document.getElementsByClassName("math"); + var macros = []; + for (var i = 0; i < mathElements.length; i++) { + var texText = mathElements[i].firstChild; + if (mathElements[i].tagName == "SPAN") { + katex.render(texText.data, mathElements[i], { + displayMode: mathElements[i].classList.contains("display"), + throwOnError: false, + macros: macros, + fleqn: false + }); + }}}); diff --git a/docs/lightswitch.js b/docs/lightswitch.js new file mode 100644 index 00000000..9467125a --- /dev/null +++ b/docs/lightswitch.js @@ -0,0 +1,85 @@ + +/*! + * Color mode toggler for Bootstrap's docs (https://getbootstrap.com/) + * Copyright 2011-2023 The Bootstrap Authors + * Licensed under the Creative Commons Attribution 3.0 Unported License. + * Updates for {pkgdown} by the {bslib} authors, also licensed under CC-BY-3.0. + */ + +const getStoredTheme = () => localStorage.getItem('theme') +const setStoredTheme = theme => localStorage.setItem('theme', theme) + +const getPreferredTheme = () => { + const storedTheme = getStoredTheme() + if (storedTheme) { + return storedTheme + } + + return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' +} + +const setTheme = theme => { + if (theme === 'auto') { + document.documentElement.setAttribute('data-bs-theme', (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')) + } else { + document.documentElement.setAttribute('data-bs-theme', theme) + } +} + +function bsSetupThemeToggle () { + 'use strict' + + const showActiveTheme = (theme, focus = false) => { + var activeLabel, activeIcon; + + document.querySelectorAll('[data-bs-theme-value]').forEach(element => { + const buttonTheme = element.getAttribute('data-bs-theme-value') + const isActive = buttonTheme == theme + + element.classList.toggle('active', isActive) + element.setAttribute('aria-pressed', isActive) + + if (isActive) { + activeLabel = element.textContent; + activeIcon = element.querySelector('span').classList.value; + } + }) + + const themeSwitcher = document.querySelector('#dropdown-lightswitch') + if (!themeSwitcher) { + return + } + + themeSwitcher.setAttribute('aria-label', activeLabel) + themeSwitcher.querySelector('span').classList.value = activeIcon; + + if (focus) { + themeSwitcher.focus() + } + } + + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { + const storedTheme = getStoredTheme() + if (storedTheme !== 'light' && storedTheme !== 'dark') { + setTheme(getPreferredTheme()) + } + }) + + window.addEventListener('DOMContentLoaded', () => { + showActiveTheme(getPreferredTheme()) + + document + .querySelectorAll('[data-bs-theme-value]') + .forEach(toggle => { + toggle.addEventListener('click', () => { + const theme = toggle.getAttribute('data-bs-theme-value') + setTheme(theme) + setStoredTheme(theme) + showActiveTheme(theme, true) + }) + }) + }) +} + +setTheme(getPreferredTheme()); +bsSetupThemeToggle(); diff --git a/docs/link.svg b/docs/link.svg new file mode 100644 index 00000000..88ad8276 --- /dev/null +++ b/docs/link.svg @@ -0,0 +1,12 @@ + + + + + + diff --git a/docs/logo.svg b/docs/logo.svg new file mode 100644 index 00000000..7eaa8b84 --- /dev/null +++ b/docs/logo.svg @@ -0,0 +1,36 @@ + + + + + G + + + + X + + + + Y + + + + + + + + + + + + + + + + + + + + β₁ + β₂ + β₃ + diff --git a/docs/news/index.html b/docs/news/index.html new file mode 100644 index 00000000..a95b9211 --- /dev/null +++ b/docs/news/index.html @@ -0,0 +1,359 @@ + +Changelog • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    TwoSampleMR v0.6.9

    +

    (Release date 2025-02-05)

    +
    • Fixed a bug in format_data() when the log_pval argument was set to TRUE. The specified p-value column is now used (thanks to @luddeluddis)
    • +
    • Amend references to MR-Base to OpenGWAS
    • +
    +
    +

    TwoSampleMR v0.6.8

    +

    (Release date 2024-09-06)

    +
    +
    +

    TwoSampleMR v0.6.7

    +

    (Release date 2024-08-21)

    +
    • Update OpenGWAS API URLs
    • +
    • Minor tweak to R CMD check GitHub Actions due to the rjson hard dependency of the MendelianRandomization package now requiring R >= 4.4.0
    • +
    • Add dark mode to pkgdown site
    • +
    +
    +

    TwoSampleMR v0.6.6

    +

    (Release date 2024-07-06)

    +
    • Improve a test
    • +
    • Improve permissions in GitHub Actions workflows
    • +
    • Bump minimum required version of ieugwasr to 1.0.1
    • +
    • Made some amends to the code to bring it more in line with lintr recommendations
    • +
    • Added omitted tidyr soft dependency
    • +
    +
    +

    TwoSampleMR v0.6.5

    +

    (Release date: 2024-06-30)

    +
    • Bumped version of roxygen2 for creating package documentation
    • +
    • Update the earliest version of R in the R CMD check GitHub Actions workflow to be 4.3.2. This is because the meta dependency depends on lme4, and the recent 1.1-35.4 release of lme4 requires Matrix 1.6-2 which was released a few days after R 4.3.2.
    • +
    • Made package tests more robust to non-response from the OpenGWAS API
    • +
    +
    +

    TwoSampleMR v0.6.4

    +

    (Release date: 2024-06-05)

    +
    • Update installation instructions in README.md
    • +
    • Fixed a bug in which the wrong indels recoding function was called (thanks @ruochiz)
    • +
    +
    +

    TwoSampleMR v0.6.3

    +

    (Release date: 2024-05-23)

    +
    • Update package startup message
    • +
    +
    +

    TwoSampleMR v0.6.2

    +

    (Release date: 2024-05-09)

    +
    • +format_data() now errors if it detects its dat object is of class 'data.table' and issues a message informing the user to make their dat object simply a 'data.frame' (thanks to Si Fang @sifang1678)
    • +
    +
    +

    TwoSampleMR v0.6.1

    +

    (Release date: 2024-04-30)

    +
    • The MendelianRandomization package has been moved from a hard dependency to a soft dependency. This is because its dependency package Matrix now requires R >= 4.4.0. Making MendelianRandomization a soft dependency means we don’t need to make TwoSampleMR have the same requirement.
    • +
    +
    +

    TwoSampleMR v0.6.0

    +

    (Release date: 2024-04-22)

    +
    +
    +

    TwoSampleMR v0.5.11

    +

    (Release date: 2024-03-21)

    +
    • In mr_leaveoneout_plot() and mr_forest_plot() amended size argument to linewidth as per ggplot2 version 3.4.0.
    • +
    • Add some datasets such that tests, continuous integration services, and creation of the vignettes don’t rely on the availability of the OpenGWAS server.
    • +
    • Various improvements to helpfiles.
    • +
    +
    +

    TwoSampleMR v0.5.10

    +

    (Release date: 2024-02-20)

    +
    +
    +

    TwoSampleMR v0.5.9

    +

    (Release date: 2024-02-01)

    +
    • Fixed a minor issue in dat_to_RadialMR() +
    • +
    • Minor improvements to make_dat() default arguments and helpfile
    • +
    • Minor improvements to package tests
    • +
    • Amendments to GitHub Actions workflows
    • +
    • Updated several URLs which had changed
    • +
    +
    +

    TwoSampleMR v0.5.8

    +

    (Release date: 2023-11-16)

    +
    • Improved speed of harmonisation using data.table functions (thanks @nicksunderland)
    • +
    • Updated URL to R-CMD-check README badge
    • +
    • Updates to GitHub Actions workflows
    • +
    +
    +

    TwoSampleMR v0.5.7

    +

    (Release date: 2023-05-29)

    +
    • Move car package to Suggests to allow TwoSampleMR to install on R between versions 4.0.0 and 4.1.0
    • +
    • In DESCRIPTION use pkgdepends syntax for MRPRESSO package due its repository name being different to the package name so that installing TwoSampleMR under pak continues to work
    • +
    • Various minor code tweaks to fix 2 R CMD check notes
    • +
    • Add Cairo package to Suggests list (thanks @hdraisma)
    • +
    • Fix error in outcome data vignette (thanks @hdraisma)
    • +
    • Some p-values that should have been ~0 were being stored as 1 in the elasticsearch database. This has now been fixed and those datasets have been clumped again to re-define the tophits. A full list of affected GWAS is available here: https://github.com/MRCIEU/opengwas-infpval-fix +
    • +
    • Updated steiger filtering to use effective sample size for case control studies (thanks to @niekverw)
    • +
    • Fixed issue with tri-allelic SNPs in harmonisation. Credit to Clare Horscroft (@chorscroft) for spotting the error and fixing
    • +
    • Fixed an issue with experimental version of local multivariable MR method. Credit to Mischa Lundberg (@MischaLundberg).
    • +
    • Catching edge cases for retrieving sample size meta data
    • +
    • Updating default rsq estimation function to use beta and standard error instead of p-value, should improve numerical stability
    • +
    • Allow chr and pos to be read in from local summary data files
    • +
    • When reading in local data without p-values, editing the inferred p-value method to be two-sided
    • +
    • All images in the vignettes (and hence also in the rendered pkgdown website) now have accompanying alt text descriptions
    • +
    • The accompanying website for the package now uses Bootstrap 5, which means a search facility is enabled
    • +
    • The NAMESPACE has been simplified, hence the package load time is very slightly improved
    • +
    +
    +

    TwoSampleMR v0.5.6

    +

    (Release date: 2021-03-25)

    +
    • Fix to scatter plot (thanks to Yossi Farjoun @yfarjoun)
    • +
    • Update to mr.raps parameters (thanks to Qingyuan Zhao @qingyuanzhao)
    • +
    • Bug fix to MVMR (thanks to Conor Judge @conorjudge)
    • +
    • Fix to harmonise_data (thanks to Leland Taylor @letaylor)
    • +
    • Documentation (thanks to @jinghuazhao)
    • +
    +
    +

    TwoSampleMR v0.5.5

    +

    (Release date: 2020-08-09)

    +
    • Updating clump_data function to operate on outcome datasets in the same way as it operates on exposure datasets. Credit goes to Marina Vabistsevits for spotting this and suggesting a solution.
    • +
    • Removing ios function, this has now moved to mr.ios package here: https://github.com/universe77/mr.ios +
    • +
    • Temporarily removing some studies because the reported effect allele may have been incorrect, will reinstate after this has been further investigated. A list of studies quarantined below: +
      • ieu-a-756
      • +
      • ieu-a-757
      • +
      • ieu-a-758
      • +
      • ieu-a-759
      • +
      • ieu-a-760
      • +
      • ieu-a-761
      • +
      • ieu-a-762
      • +
      • ieu-a-763
      • +
      • ieu-a-764
      • +
      • ieu-a-765
      • +
      • ieu-a-766
      • +
      • ieu-a-767
      • +
      • ieu-a-768
      • +
      • ieu-a-769
      • +
      • ieu-a-770
      • +
      • ieu-a-771
      • +
      • ieu-a-772
      • +
      • ieu-a-773
      • +
      • ieu-a-774
      • +
      • ieu-a-775
      • +
      • ieu-a-776
      • +
      • ieu-a-777
      • +
      • ieu-a-778
      • +
      • ieu-a-779
      • +
      • bbj-a-64
      • +
      • bbj-a-65
      • +
      • bbj-a-66
      • +
      • bbj-a-67
      • +
      • bbj-a-68
      • +
      • bbj-a-69
      • +
      • ebi-a-GCST004364
      • +
      • ebi-a-GCST005215
      • +
      • ebi-a-GCST005216
      • +
      • ebi-a-GCST005221
      • +
      • ebi-a-GCST005222
      • +
      • ieu-a-1086
      • +
      • ieu-a-761
      • +
      • ieu-a-762
      • +
      • ieu-a-763
      • +
      • ieu-a-767
      • +
      • ieu-a-777
      • +
      • ieu-a-779
      • +
    • +
    +
    +

    TwoSampleMR v0.5.4

    +

    (Release date: 2020-05-10)

    +
    • All datasets now re-instated
    • +
    • Added options for different populations in LD operations
    • +
    • When converting to MRInput format and supplying an LD matrix, it is possible that multi-allelic variants will be represented differently on in the GWAS and the LD reference panel. Ambiguous alignments were not being removed, now fixed. Credit goes to Mona Almramhi for spotting and fixing this issue.
    • +
    +
    +

    TwoSampleMR v0.5.3

    +

    (Release date: 2020-04-02)

    +
    • When converting to MRInput format and supplying an LD matrix, the LD matrix SNP order was not matching the summary data order. Credit goes to Mona Almramhi for spotting and fixing this issue.
    • +
    • Reinstating all datasets that were previously disabled (ukb-a, ukb-d, ubm-a)
    • +
    • Fixed bug with mr_wrapper. Thanks to Gunn-Helen Moen for this.
    • +
    +
    +

    TwoSampleMR v0.5.2

    +

    (Release date: 2020-03-11)

    +
    • No longer marking LD functions as deprecated for now. Thanks to Jonas Bovijn for discussions on this.
    • +
    • Various fixes for R CMD check warnings and notes.
    • +
    +
    +

    TwoSampleMR v0.5.1

    +

    (Release date: 2020-02-14)

    +
    • A number of datasets have been found to have issues since 0.5.0. These include:
    • +
    • A minority of non-effect alleles being incorrect in the ieu-a batch. The consequence of this is harmonisation may have thrown out some SNPs due to harmonisation mismatches. Error arose in 0.5.0 and now fixed
    • +
    • p-value issues with the ubm-a batch. This would have led to fewer top-hits being identified than they should have. Error arose in 0.5.0 and currently disabled
    • +
    • Effect allele frequency issues with the ukb-a batch, potentially due to misreported effect alleles. Error arose in 0.5.0 and currently disabled
    • +
    +
    +

    TwoSampleMR v0.5.0

    +

    (Release date: 2020-01-01)

    +
    +
    +

    TwoSampleMR v0.4.26

    +

    (Release date: 2019-12-01)

    +
    • Improved precision of low p-values in steiger tests. Thanks to Hannah V Meyer and Tom Palmer for this.
    • +
    • Improved instrument extraction for new datasets
    • +
    +
    +

    TwoSampleMR v0.4.25

    +

    (Release date: 2019-09-12)

    +
    • Changes in googleAuthR package break authentication. Added interception to install older version while this is being fixed. Please use devtools::install_github("MarkEdmondson1234/googleAuthR@v0.8.1") +
    • +
    +
    +

    TwoSampleMR v0.4.24

    +

    (Release date: 2019-09-10)

    +
    • Bug found in extract_instruments when requesting non-default parameters. Thanks to Shantanu Bafna for pointing this out.
    • +
    +
    +

    TwoSampleMR v0.4.23

    +

    (Release date: 2019-08-12)

    +
    • Forcing server to extract_instruments when pre-computed outcomes are not present by default. The old behaviour is still possible by setting extract_instruments(force_server_if_empty=FALSE) +
    • +
    +
    +

    TwoSampleMR v0.4.22

    +

    (Release date: 2019-02-22)

    +
    • Changing default API address in preparation for moving to version 0.5.0 which will use the new API
    • +
    +
    +

    TwoSampleMR v0.4.21

    +

    (Release date: 2019-02-19)

    +
    • Updated mixture of experts
    • +
    +
    +

    TwoSampleMR v0.4.20

    +

    (Release date: 2019-01-31)

    +
    • The harmonise function now returns a summary of the harmonisation procedure e.g. number of SNPs removed etc. Access via attr(obj, “log”)
    • +
    • Note that this has been tested and shown to give the same results as previously but there is a chance that it might lead to slightly different behaviour. Please install the previous version if you would prefer to avoid possibilities of changed behaviour - devtools::install_github(“”)
    • +
    +
    +

    TwoSampleMR v0.4.19

    +

    (Release date: 2019-01-31)

    +
    • Fixed a bug in mr_heterogeneity that would have impacted a minority of cases. If the method list was being specified then the order of the results didn’t always match the method (MR Egger and IVW were mixed up). This did not affect default usage. Thanks to Anna Guyatt for pointing this out.
    • +
    • Added index of suspicion functionality, and penalised mode estimator
    • +
    • Added transformation function to scale effect estimate units to SD scale
    • +
    • Starting to write change log again!
    • +
    +
    +

    TwoSampleMR v0.4.18

    +

    (Release date: 2018-12-03)

    +
    • Improved performance of harmonisation
    • +
    +
    +

    TwoSampleMR v0.4.17

    +

    (Release date: 2018-12-03)

    +
    • Added facility to harmonise indels
    • +
    • Documentation and options added to multivariable MR
    • +
    +
    +

    TwoSampleMR v0.3.4

    +

    (Release date: 2017-11-30)

    +
    • Moving over to elastic search database so the request batching is changing from 50 SNPs per chunk to 10000. This can be modified through extract_outcome_data(splitsize=50)
    • +
    • Changing harmonise_data behaviour - now does not discard the bad SNPs but retains them with the mr_keep column indicating whether or not they will be used by the mr analysis functions
    • +
    • Fixed issue with oauth token
    • +
    • Updated scatter plot to register the mr_keep column.
    • +
    +
    +

    TwoSampleMR v0.3.3

    +

    (Release date: 2017-11-23)

    +
    • Fixed bug in singlesnp and leaveoneout analyses
    • +
    +
    +

    TwoSampleMR v0.3.2

    +

    (Release date: 2017-11-22)

    +
    • Added function to check for latest version on package load
    • +
    +
    +

    TwoSampleMR v0.3.1

    +

    (Release date: 2017-11-22)

    +
    • One of the external packages that TwoSampleMR depends upon had changed, making the authorisation behaviour change. The authorisation was timing out after an hour and it was not refreshing after its timeout. This has now been fixed - the authorisation token will refresh after an hour.
    • +
    • The authorisation token used to be stored in a hidden file called .httr-oauth. This has now been changed - it will be stored in a visible file called ‘mrbase.oauth’.
    • +
    +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/pkgdown.js b/docs/pkgdown.js new file mode 100644 index 00000000..9757bf9e --- /dev/null +++ b/docs/pkgdown.js @@ -0,0 +1,154 @@ +/* http://gregfranko.com/blog/jquery-best-practices/ */ +(function($) { + $(function() { + + $('nav.navbar').headroom(); + + Toc.init({ + $nav: $("#toc"), + $scope: $("main h2, main h3, main h4, main h5, main h6") + }); + + if ($('#toc').length) { + $('body').scrollspy({ + target: '#toc', + offset: $("nav.navbar").outerHeight() + 1 + }); + } + + // Activate popovers + $('[data-bs-toggle="popover"]').popover({ + container: 'body', + html: true, + trigger: 'focus', + placement: "top", + sanitize: false, + }); + + $('[data-bs-toggle="tooltip"]').tooltip(); + + /* Clipboard --------------------------*/ + + function changeTooltipMessage(element, msg) { + var tooltipOriginalTitle=element.getAttribute('data-bs-original-title'); + element.setAttribute('data-bs-original-title', msg); + $(element).tooltip('show'); + element.setAttribute('data-bs-original-title', tooltipOriginalTitle); + } + + if(ClipboardJS.isSupported()) { + $(document).ready(function() { + var copyButton = ""; + + $("div.sourceCode").addClass("hasCopyButton"); + + // Insert copy buttons: + $(copyButton).prependTo(".hasCopyButton"); + + // Initialize tooltips: + $('.btn-copy-ex').tooltip({container: 'body'}); + + // Initialize clipboard: + var clipboard = new ClipboardJS('[data-clipboard-copy]', { + text: function(trigger) { + return trigger.parentNode.textContent.replace(/\n#>[^\n]*/g, ""); + } + }); + + clipboard.on('success', function(e) { + changeTooltipMessage(e.trigger, 'Copied!'); + e.clearSelection(); + }); + + clipboard.on('error', function(e) { + changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); + }); + + }); + } + + /* Search marking --------------------------*/ + var url = new URL(window.location.href); + var toMark = url.searchParams.get("q"); + var mark = new Mark("main#main"); + if (toMark) { + mark.mark(toMark, { + accuracy: { + value: "complementary", + limiters: [",", ".", ":", "/"], + } + }); + } + + /* Search --------------------------*/ + /* Adapted from https://github.com/rstudio/bookdown/blob/2d692ba4b61f1e466c92e78fd712b0ab08c11d31/inst/resources/bs4_book/bs4_book.js#L25 */ + // Initialise search index on focus + var fuse; + $("#search-input").focus(async function(e) { + if (fuse) { + return; + } + + $(e.target).addClass("loading"); + var response = await fetch($("#search-input").data("search-index")); + var data = await response.json(); + + var options = { + keys: ["what", "text", "code"], + ignoreLocation: true, + threshold: 0.1, + includeMatches: true, + includeScore: true, + }; + fuse = new Fuse(data, options); + + $(e.target).removeClass("loading"); + }); + + // Use algolia autocomplete + var options = { + autoselect: true, + debug: true, + hint: false, + minLength: 2, + }; + var q; +async function searchFuse(query, callback) { + await fuse; + + var items; + if (!fuse) { + items = []; + } else { + q = query; + var results = fuse.search(query, { limit: 20 }); + items = results + .filter((x) => x.score <= 0.75) + .map((x) => x.item); + if (items.length === 0) { + items = [{dir:"Sorry 😿",previous_headings:"",title:"No results found.",what:"No results found.",path:window.location.href}]; + } + } + callback(items); +} + $("#search-input").autocomplete(options, [ + { + name: "content", + source: searchFuse, + templates: { + suggestion: (s) => { + if (s.title == s.what) { + return `${s.dir} >
    ${s.title}
    `; + } else if (s.previous_headings == "") { + return `${s.dir} >
    ${s.title}
    > ${s.what}`; + } else { + return `${s.dir} >
    ${s.title}
    > ${s.previous_headings} > ${s.what}`; + } + }, + }, + }, + ]).on('autocomplete:selected', function(event, s) { + window.location.href = s.path + "?q=" + q + "#" + s.id; + }); + }); +})(window.jQuery || window.$) diff --git a/docs/pkgdown.yml b/docs/pkgdown.yml new file mode 100644 index 00000000..0aa4343e --- /dev/null +++ b/docs/pkgdown.yml @@ -0,0 +1,14 @@ +pandoc: '2.18' +pkgdown: 2.1.0 +pkgdown_sha: ~ +articles: + exposure: exposure.html + gwas2020: gwas2020.html + harmonise: harmonise.html + introduction: introduction.html + outcome: outcome.html + perform_mr: perform_mr.html +last_built: 2025-02-21T20:22Z +urls: + reference: https://mrcieu.github.io/TwoSampleMR/reference + article: https://mrcieu.github.io/TwoSampleMR/articles diff --git a/docs/reference/Isq.html b/docs/reference/Isq.html new file mode 100644 index 00000000..6c73091e --- /dev/null +++ b/docs/reference/Isq.html @@ -0,0 +1,99 @@ + +I-squared calculation — Isq • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    This function calculates the \(I^2\) statistic. +To use it for the \(I^2_{GX}\) metric ensure that the effects are all the same sign (e.g. abs(y)).

    +
    + +
    +

    Usage

    +
    Isq(y, s)
    +
    + +
    +

    Arguments

    + + +
    y
    +

    Vector of effects.

    + + +
    s
    +

    Vector of standard errors.

    + +
    +
    +

    Value

    +

    Isq value

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/TwoSampleMR-package.html b/docs/reference/TwoSampleMR-package.html new file mode 100644 index 00000000..0e28440b --- /dev/null +++ b/docs/reference/TwoSampleMR-package.html @@ -0,0 +1,92 @@ + +TwoSampleMR: Two Sample MR Functions and Interface to MRC Integrative Epidemiology Unit OpenGWAS Database — TwoSampleMR-package • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    A package for performing Mendelian randomization using GWAS summary data. It uses the IEU OpenGWAS database https://gwas.mrcieu.ac.uk/ to automatically obtain data, and a wide range of methods to run the analysis.

    +
    + + + +
    +

    Author

    +

    Maintainer: Gibran Hemani g.hemani@bristol.ac.uk (ORCID)

    +

    Authors:

    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/TwoSampleMR.html b/docs/reference/TwoSampleMR.html new file mode 100644 index 00000000..25f4f58a --- /dev/null +++ b/docs/reference/TwoSampleMR.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/docs/reference/add_metadata.html b/docs/reference/add_metadata.html new file mode 100644 index 00000000..e894268b --- /dev/null +++ b/docs/reference/add_metadata.html @@ -0,0 +1,99 @@ + +Add meta data to extracted data — add_metadata • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Previously the meta data was returned alongside association information. This is mostly unnecessary as it is needlessly repeating information. This is a convenience function that reinstates that information. +Can be applied to either exposure data, outcome data, or harmonised data

    +
    + +
    +

    Usage

    +
    add_metadata(dat, cols = c("sample_size", "ncase", "ncontrol", "unit", "sd"))
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Either exposure data, outcome data or harmonised data

    + + +
    cols
    +

    Which metadata fields to add. Default = c("sample_size", "ncase", "ncontrol", "unit", "sd")

    + +
    +
    +

    Value

    +

    Data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/add_rsq.html b/docs/reference/add_rsq.html new file mode 100644 index 00000000..3eb19b1d --- /dev/null +++ b/docs/reference/add_rsq.html @@ -0,0 +1,101 @@ + +Estimate r-square of each association — add_rsq • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Can be applied to exposure_dat, outcome_dat or harmonised_data. +Note that it will be beneficial in some circumstances to add the meta data to +the data object using add_metadata() before running this function. +Also adds effective sample size for case control data.

    +
    + +
    +

    Usage

    +
    add_rsq(dat)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    exposure_dat, outcome_dat or harmonised_data

    + +
    +
    +

    Value

    +

    data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/allele_frequency.html b/docs/reference/allele_frequency.html new file mode 100644 index 00000000..53e906d4 --- /dev/null +++ b/docs/reference/allele_frequency.html @@ -0,0 +1,92 @@ + +Estimate allele frequency from SNP — allele_frequency • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Estimate allele frequency from SNP

    +
    + +
    +

    Usage

    +
    allele_frequency(g)
    +
    + +
    +

    Arguments

    + + +
    g
    +

    Vector of 0/1/2

    + +
    +
    +

    Value

    +

    Allele frequency

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/available_outcomes.html b/docs/reference/available_outcomes.html new file mode 100644 index 00000000..a3be809b --- /dev/null +++ b/docs/reference/available_outcomes.html @@ -0,0 +1,92 @@ + +Get list of studies with available GWAS summary statistics through API — available_outcomes • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Get list of studies with available GWAS summary statistics through API

    +
    + +
    +

    Usage

    +
    available_outcomes(opengwas_jwt = ieugwasr::get_opengwas_jwt())
    +
    + +
    +

    Arguments

    + + +
    opengwas_jwt
    +

    Used to authenticate protected endpoints. Login to https://api.opengwas.io to obtain a jwt. Provide the jwt string here, or store in .Renviron under the keyname OPENGWAS_JWT.

    + +
    +
    +

    Value

    +

    Dataframe of details for all available studies

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/cleanup_outcome_data.html b/docs/reference/cleanup_outcome_data.html new file mode 100644 index 00000000..bf49d669 --- /dev/null +++ b/docs/reference/cleanup_outcome_data.html @@ -0,0 +1,92 @@ + +Avoid issues in MR by finding impossible vals and setting to NA — cleanup_outcome_data • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Avoid issues in MR by finding impossible vals and setting to NA

    +
    + +
    +

    Usage

    +
    cleanup_outcome_data(d)
    +
    + +
    +

    Arguments

    + + +
    d
    +

    Data frame

    + +
    +
    +

    Value

    +

    Cleaned data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/clump_data.html b/docs/reference/clump_data.html new file mode 100644 index 00000000..a3c8c0c7 --- /dev/null +++ b/docs/reference/clump_data.html @@ -0,0 +1,138 @@ + +Perform LD clumping on SNP data — clump_data • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Uses PLINK clumping method, where SNPs in LD within a particular window will be pruned. The SNP with the lowest p-value is retained.

    +
    + +
    +

    Usage

    +
    clump_data(
    +  dat,
    +  clump_kb = 10000,
    +  clump_r2 = 0.001,
    +  clump_p1 = 1,
    +  clump_p2 = 1,
    +  pop = "EUR",
    +  bfile = NULL,
    +  plink_bin = NULL
    +)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from format_data(). Must have a SNP name column (SNP), SNP chromosome column (chr_name), SNP position column (chrom_start). If id.exposure or pval.exposure not present they will be generated.

    + + +
    clump_kb
    +

    Clumping window, default is 10000.

    + + +
    clump_r2
    +

    Clumping r2 cutoff. Note that this default value has recently changed from 0.01 to 0.001.

    + + +
    clump_p1
    +

    Clumping sig level for index SNPs, default is 1.

    + + +
    clump_p2
    +

    Clumping sig level for secondary SNPs, default is 1.

    + + +
    pop
    +

    Super-population to use as reference panel. Default = "EUR". Options are "EUR", "SAS", "EAS", "AFR", "AMR". 'legacy' also available - which is a previously used version of the EUR panel with a slightly different set of markers

    + + +
    bfile
    +

    If this is provided then will use the API. Default = NULL

    + + + +

    If NULL and bfile is not NULL then will detect packaged plink binary for specific OS. Otherwise specify path to plink binary. Default = NULL

    + +
    +
    +

    Value

    +

    Data frame

    +
    +
    +

    Details

    +

    This function interacts with the OpenGWAS API, which houses LD reference panels for the 5 super-populations in the 1000 genomes reference panel. +It includes only bi-allelic SNPs with MAF > 0.01, so it's quite possible that a variant you want to include in the clumping process will be absent. +If it is absent, it will be automatically excluded from the results.

    +

    You can check if your variants are present in the LD reference panel using ieugwasr::ld_reflookup().

    +

    This function does put load on the OpenGWAS servers, which makes life more difficult for other users. +We have implemented a method and made available the LD reference panels to perform clumping locally, see ieugwasr::ld_clump() and related vignettes for details.

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/combine_all_mrresults.html b/docs/reference/combine_all_mrresults.html new file mode 100644 index 00000000..cf3d2538 --- /dev/null +++ b/docs/reference/combine_all_mrresults.html @@ -0,0 +1,141 @@ + +Combine all mr results — combine_all_mrresults • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    This function combines results of mr(), mr_heterogeneity(), mr_pleiotropy_test() and mr_singlesnp() into a single data frame. +It also merges the results with outcome study level characteristics in available_outcomes(). +If desired it also exponentiates results (e.g. if the user wants log odds ratio converted into odds ratios with 95 percent confidence intervals). +The exposure and outcome columns from the output from mr() contain both the trait names and trait ids. +The combine_all_mrresults() function splits these into separate columns by default.

    +
    + +
    +

    Usage

    +
    combine_all_mrresults(
    +  res,
    +  het,
    +  plt,
    +  sin,
    +  ao_slc = TRUE,
    +  Exp = FALSE,
    +  split.exposure = FALSE,
    +  split.outcome = FALSE
    +)
    +
    + +
    +

    Arguments

    + + +
    res
    +

    Results from mr().

    + + +
    het
    +

    Results from mr_heterogeneity().

    + + +
    plt
    +

    Results from mr_pleiotropy_test().

    + + +
    sin
    +

    Results from mr_singlesnp().

    + + +
    ao_slc
    +

    Logical; if set to TRUE then outcome study level characteristics are retrieved from available_outcomes(). Default is TRUE.

    + + +
    Exp
    +

    Logical; if set to TRUE results are exponentiated. Useful if user wants log odds ratios expressed as odds ratios. Default is FALSE.

    + + +
    split.exposure
    +

    Logical; if set to TRUE the exposure column is split into separate columns for the exposure name and exposure ID. Default is FALSE.

    + + +
    split.outcome
    +

    Logical; if set to TRUE the outcome column is split into separate columns for the outcome name and outcome ID. Default is FALSE.

    + +
    +
    +

    Value

    +

    data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/combine_data.html b/docs/reference/combine_data.html new file mode 100644 index 00000000..85ec0ee9 --- /dev/null +++ b/docs/reference/combine_data.html @@ -0,0 +1,101 @@ + +Combine data — combine_data • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Taking exposure or outcome data (returned from format_data()) +combine multiple datasets together so they can be analysed in one +batch. Removes duplicate SNPs, preferentially keeping those usable +in MR analysis.

    +
    + +
    +

    Usage

    +
    combine_data(x)
    +
    + +
    +

    Arguments

    + + +
    x
    +

    List of data frames returned from format_data().

    + +
    +
    +

    Value

    +

    data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/contingency.html b/docs/reference/contingency.html new file mode 100644 index 00000000..e8b49774 --- /dev/null +++ b/docs/reference/contingency.html @@ -0,0 +1,107 @@ + +Obtain 2x2 contingency table from marginal parameters and odds ratio — contingency • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Columns are the case and control frequencies. +Rows are the frequencies for allele 1 and allele 2.

    +
    + +
    +

    Usage

    +
    contingency(af, prop, odds_ratio, eps = 1e-15)
    +
    + +
    +

    Arguments

    + + +
    af
    +

    Allele frequency of effect allele.

    + + +
    prop
    +

    Proportion of cases.

    + + +
    odds_ratio
    +

    Odds ratio.

    + + +
    eps
    +

    tolerance, default is 1e-15.

    + +
    +
    +

    Value

    +

    2x2 contingency table as matrix

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/convert_outcome_to_exposure.html b/docs/reference/convert_outcome_to_exposure.html new file mode 100644 index 00000000..0b3e4275 --- /dev/null +++ b/docs/reference/convert_outcome_to_exposure.html @@ -0,0 +1,92 @@ + +Convert outcome data to exposure data — convert_outcome_to_exposure • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Helper function to convert results from extract_outcome_data() to exposure_dat format.

    +
    + +
    +

    Usage

    +
    convert_outcome_to_exposure(outcome_dat)
    +
    + +
    +

    Arguments

    + + +
    outcome_dat
    +

    Output from extract_outcome_data().

    + +
    +
    +

    Value

    +

    data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/create_label.html b/docs/reference/create_label.html new file mode 100644 index 00000000..599a0391 --- /dev/null +++ b/docs/reference/create_label.html @@ -0,0 +1,96 @@ + +Create fixed width label — create_label • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Create fixed width label

    +
    + +
    +

    Usage

    +
    create_label(n1, nom)
    +
    + +
    +

    Arguments

    + + +
    n1
    +

    number

    + + +
    nom
    +

    name

    + +
    +
    +

    Value

    +

    text

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/dat_to_MRInput.html b/docs/reference/dat_to_MRInput.html new file mode 100644 index 00000000..5f8b5989 --- /dev/null +++ b/docs/reference/dat_to_MRInput.html @@ -0,0 +1,106 @@ + +Convert TwoSampleMR format to MendelianRandomization format — dat_to_MRInput • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    The MendelianRandomization package offers MR methods that can +be used with the same data used in the TwoSampleMR package. This +function converts from the TwoSampleMR format to the MRInput class.

    +
    + +
    +

    Usage

    +
    dat_to_MRInput(dat, get_correlations = FALSE, pop = "EUR")
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from the harmonise_data() function.

    + + +
    get_correlations
    +

    Default FALSE. If TRUE then extract the LD matrix for the SNPs from the European 1000 genomes data on OpenGWAS.

    + + +
    pop
    +

    If get_correlations is TRUE then use the following

    + +
    +
    +

    Value

    +

    List of MRInput objects for each exposure/outcome combination

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/dat_to_RadialMR.html b/docs/reference/dat_to_RadialMR.html new file mode 100644 index 00000000..7e440db4 --- /dev/null +++ b/docs/reference/dat_to_RadialMR.html @@ -0,0 +1,92 @@ + +Convert dat to RadialMR format — dat_to_RadialMR • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Creates a list of RadialMR format datasets for each exposure-outcome pair.

    +
    + +
    +

    Usage

    +
    dat_to_RadialMR(dat)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from harmonise_data().

    + +
    +
    +

    Value

    +

    List of RadialMR format datasets

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/default_parameters.html b/docs/reference/default_parameters.html new file mode 100644 index 00000000..86c5cbe9 --- /dev/null +++ b/docs/reference/default_parameters.html @@ -0,0 +1,79 @@ + +List of parameters for use with MR functions — default_parameters • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    The default is list(test_dist = "z", nboot = 1000, Cov = 0, penk = 20, phi = 1, alpha = 0.05, Qthresh = 0.05, over.dispersion = TRUE, loss.function = "huber").

    +
    + +
    +

    Usage

    +
    default_parameters()
    +
    + + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/directionality_test.html b/docs/reference/directionality_test.html new file mode 100644 index 00000000..2d5e9d81 --- /dev/null +++ b/docs/reference/directionality_test.html @@ -0,0 +1,92 @@ + +Perform MR Steiger test of directionality — directionality_test • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    A statistical test for whether the assumption that exposure causes outcome is valid.

    +
    + +
    +

    Usage

    +
    directionality_test(dat)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Harmonised exposure and outcome data. Output from harmonise_data().

    + +
    +
    +

    Value

    +

    List

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/effective_n.html b/docs/reference/effective_n.html new file mode 100644 index 00000000..010e99a2 --- /dev/null +++ b/docs/reference/effective_n.html @@ -0,0 +1,96 @@ + +Estimate the effective sample size in a case control study — effective_n • TwoSampleMR + Skip to contents + + +
    +
    +
    + + + +
    +

    Usage

    +
    effective_n(ncase, ncontrol)
    +
    + +
    +

    Arguments

    + + +
    ncase
    +

    Vector of number of cases

    + + +
    ncontrol
    +

    Vector of number of controls

    + +
    +
    +

    Value

    +

    Vector of effective sample size

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/enrichment.html b/docs/reference/enrichment.html new file mode 100644 index 00000000..ac5bf9d8 --- /dev/null +++ b/docs/reference/enrichment.html @@ -0,0 +1,96 @@ + +Perform enrichment analysis — enrichment • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Perform enrichment analysis

    +
    + +
    +

    Usage

    +
    enrichment(dat, method_list = enrichment_method_list()$obj)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Harmonised exposure and outcome data. Output from harmonise_data().

    + + +
    method_list
    +

    List of methods to use in analysis. Default is enrichment_method_list()$obj. See enrichment_method_list() for details.

    + +
    +
    +

    Value

    +

    data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/enrichment_method_list.html b/docs/reference/enrichment_method_list.html new file mode 100644 index 00000000..1e4d8635 --- /dev/null +++ b/docs/reference/enrichment_method_list.html @@ -0,0 +1,84 @@ + +Get list of available p-value enrichment methods — enrichment_method_list • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Get list of available p-value enrichment methods

    +
    + +
    +

    Usage

    +
    enrichment_method_list()
    +
    + +
    +

    Value

    +

    Data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/estimate_trait_sd.html b/docs/reference/estimate_trait_sd.html new file mode 100644 index 00000000..2659e13a --- /dev/null +++ b/docs/reference/estimate_trait_sd.html @@ -0,0 +1,104 @@ + +Estimate trait SD by obtaining beta estimates from z-scores and finding the ratio with original beta values — estimate_trait_sd • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Assumes that sample size and allele frequency is correct for each SNP, and that allele frequency gives a reasonable estimate of the variance of the SNP.

    +
    + +
    +

    Usage

    +
    estimate_trait_sd(b, se, n, p)
    +
    + +
    +

    Arguments

    + + +
    b
    +

    vector of effect sizes.

    + + +
    se
    +

    vector of standard errors.

    + + +
    n
    +

    vector of sample sizes.

    + + +
    p
    +

    vector of allele frequencies.

    + +
    +
    +

    Value

    +

    Vector of sd estimates for each association.

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/extract_instruments.html b/docs/reference/extract_instruments.html new file mode 100644 index 00000000..f884a9c0 --- /dev/null +++ b/docs/reference/extract_instruments.html @@ -0,0 +1,132 @@ + +Find instruments for use in MR from the OpenGWAS database — extract_instruments • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    This function searches for GWAS significant SNPs (for a given p-value) for a specified set of outcomes. +It then performs LD based clumping to return only independent significant associations.

    +
    + +
    +

    Usage

    +
    extract_instruments(
    +  outcomes,
    +  p1 = 5e-08,
    +  clump = TRUE,
    +  p2 = 5e-08,
    +  r2 = 0.001,
    +  kb = 10000,
    +  opengwas_jwt = ieugwasr::get_opengwas_jwt(),
    +  force_server = FALSE
    +)
    +
    + +
    +

    Arguments

    + + +
    outcomes
    +

    Array of outcome IDs (see available_outcomes()).

    + + +
    p1
    +

    Significance threshold. The default is 5e-8.

    + + +
    clump
    +

    Logical; whether to clump results. The default is TRUE.

    + + +
    p2
    +

    Secondary clumping threshold. The default is 5e-8.

    + + +
    r2
    +

    Clumping r2 cut off. The default is 0.001.

    + + +
    kb
    +

    Clumping distance cutoff. The default is 10000.

    + + +
    opengwas_jwt
    +

    Used to authenticate protected endpoints. Login to https://api.opengwas.io to obtain a jwt. Provide the jwt string here, or store in .Renviron under the keyname OPENGWAS_JWT.

    + + +
    force_server
    +

    Force the analysis to extract results from the server rather than the MRInstruments package.

    + +
    +
    +

    Value

    +

    data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/extract_outcome_data.html b/docs/reference/extract_outcome_data.html new file mode 100644 index 00000000..a19a6324 --- /dev/null +++ b/docs/reference/extract_outcome_data.html @@ -0,0 +1,139 @@ + +Supply the output from read_exposure_data() and all the SNPs therein will be queried against the requested outcomes in remote database using API. — extract_outcome_data • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Supply the output from read_exposure_data() and all the SNPs therein will be queried against the requested outcomes in remote database using API.

    +
    + +
    +

    Usage

    +
    extract_outcome_data(
    +  snps,
    +  outcomes,
    +  proxies = TRUE,
    +  rsq = 0.8,
    +  align_alleles = 1,
    +  palindromes = 1,
    +  maf_threshold = 0.3,
    +  opengwas_jwt = ieugwasr::get_opengwas_jwt(),
    +  splitsize = 10000,
    +  proxy_splitsize = 500
    +)
    +
    + +
    +

    Arguments

    + + +
    snps
    +

    Array of SNP rs IDs.

    + + +
    outcomes
    +

    Array of IDs (see id column in output from available_outcomes()).

    + + +
    proxies
    +

    Look for LD tags? Default is TRUE.

    + + +
    rsq
    +

    Minimum LD rsq value (if proxies = 1). Default = 0.8.

    + + +
    align_alleles
    +

    Try to align tag alleles to target alleles (if proxies = 1). 1 = yes, 0 = no. The default is 1.

    + + +
    palindromes
    +

    Allow palindromic SNPs (if proxies = 1). 1 = yes, 0 = no. The default is 1.

    + + +
    maf_threshold
    +

    MAF threshold to try to infer palindromic SNPs. The default is 0.3.

    + + +
    opengwas_jwt
    +

    Used to authenticate protected endpoints. Login to https://api.opengwas.io to obtain a jwt. Provide the jwt string here, or store in .Renviron under the keyname OPENGWAS_JWT.

    + + +
    splitsize
    +

    The default is 10000.

    + + +
    proxy_splitsize
    +

    The default is 500.

    + +
    +
    +

    Value

    +

    Dataframe of summary statistics for all available outcomes

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/figures/logo.svg b/docs/reference/figures/logo.svg new file mode 100644 index 00000000..7eaa8b84 --- /dev/null +++ b/docs/reference/figures/logo.svg @@ -0,0 +1,36 @@ + + + + + G + + + + X + + + + Y + + + + + + + + + + + + + + + + + + + + β₁ + β₂ + β₃ + diff --git a/docs/reference/fishers_combined_test.html b/docs/reference/fishers_combined_test.html new file mode 100644 index 00000000..7bdffec6 --- /dev/null +++ b/docs/reference/fishers_combined_test.html @@ -0,0 +1,101 @@ + +Fisher's combined test — fishers_combined_test • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Fisher's combined test

    +
    + +
    +

    Usage

    +
    fishers_combined_test(pval)
    +
    + +
    +

    Arguments

    + + +
    pval
    +

    Vector of outcome p-values

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    MR estimate

    + +
    se
    +

    Standard error

    + +
    pval
    +

    p-value

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/forest_plot.html b/docs/reference/forest_plot.html new file mode 100644 index 00000000..d4bb0255 --- /dev/null +++ b/docs/reference/forest_plot.html @@ -0,0 +1,154 @@ + +Forest plot for multiple exposures and multiple outcomes — forest_plot • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Perform MR of multiple exposures and multiple outcomes. This plots the results.

    +
    + +
    +

    Usage

    +
    forest_plot(
    +  mr_res,
    +  exponentiate = FALSE,
    +  single_snp_method = "Wald ratio",
    +  multi_snp_method = "Inverse variance weighted",
    +  group_single_categories = TRUE,
    +  by_category = TRUE,
    +  in_columns = FALSE,
    +  threshold = NULL,
    +  xlab = "",
    +  xlim = NULL,
    +  trans = "identity",
    +  ao_slc = TRUE,
    +  priority = "Cardiometabolic"
    +)
    +
    + +
    +

    Arguments

    + + +
    mr_res
    +

    Results from mr().

    + + +
    exponentiate
    +

    Convert effects to OR? Default is FALSE.

    + + +
    single_snp_method
    +

    Which of the single SNP methosd to use when only 1 SNP was used to estimate the causal effect? The default is "Wald ratio".

    + + +
    multi_snp_method
    +

    Which of the multi-SNP methods to use when there was more than 1 SNPs used to estimate the causal effect? The default is "Inverse variance weighted".

    + + +
    group_single_categories
    +

    If there are categories with only one outcome, group them together into an "Other" group. The default is TRUE.

    + + +
    by_category
    +

    Separate the results into sections by category? The default is TRUE.

    + + +
    in_columns
    +

    Separate the exposures into different columns. The default is FALSE.

    + + +
    threshold
    +

    p-value threshold to use for colouring points by significance level. If NULL (default) then colour layer won't be applied.

    + + +
    xlab
    +

    x-axis label. If in_columns=TRUE then the exposure values are appended to the end of xlab. e.g. if xlab="Effect of" then x-labels will read "Effect of exposure1", "Effect of exposure2" etc. Otherwise will be printed as is.

    + + +
    xlim
    +

    limit x-axis range. Provide vector of length 2, with lower and upper bounds. The default is NULL.

    + + +
    trans
    +

    Transformation to apply to x-axis. e.g. "identity", "log2", etc. The default is "identity".

    + + +
    ao_slc
    +

    retrieve sample size and subcategory from available_outcomes(). If set to FALSE then mr_res must contain the following additional columns: sample_size and subcategory. The default behaviour is to use available_outcomes() to retrieve sample size and subcategory.

    + + +
    priority
    +

    Name of category to prioritise at the top of the forest plot. The default is "Cardiometabolic".

    + +
    +
    +

    Value

    +

    grid plot object

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/forest_plot_1_to_many.html b/docs/reference/forest_plot_1_to_many.html new file mode 100644 index 00000000..e8342cac --- /dev/null +++ b/docs/reference/forest_plot_1_to_many.html @@ -0,0 +1,203 @@ + +1-to-many forest plot — forest_plot_1_to_many • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Plot results from an analysis of multiple exposures against a single outcome or a single exposure against multiple outcomes. +Plots effect estimates and 95 percent confidence intervals. +The ordering of results in the plot is determined by the order supplied by the user. +Users may find sort_1_to_many() helpful for sorting their results prior to using the 1-to-many forest plot. The plot function works best for 50 results and is not designed to handle more than 100 results.

    +
    + +
    +

    Usage

    +
    forest_plot_1_to_many(
    +  mr_res = "mr_res",
    +  b = "b",
    +  se = "se",
    +  TraitM = "outcome",
    +  col1_width = 1,
    +  col1_title = "",
    +  exponentiate = FALSE,
    +  trans = "identity",
    +  ao_slc = TRUE,
    +  lo = NULL,
    +  up = NULL,
    +  by = NULL,
    +  xlab = "Effect (95% confidence interval)",
    +  addcols = NULL,
    +  addcol_widths = NULL,
    +  addcol_titles = "",
    +  subheading_size = 6,
    +  shape_points = 15,
    +  colour_scheme = "black",
    +  col_text_size = 5,
    +  weight = NULL
    +)
    +
    + +
    +

    Arguments

    + + +
    mr_res
    +

    Data frame of results supplied by the user. The default is "mr_res".

    + + +
    b
    +

    Name of the column specifying the effect of the exposure on the outcome. The default is "b".

    + + +
    se
    +

    Name of the column specifying the standard error for b. The default is "se".

    + + +
    TraitM
    +

    The column specifying the names of the traits. Corresponds to 'many' in the 1-to-many forest plot. The default is "outcome".

    + + +
    col1_width
    +

    Width of Y axis label for the column specified by the TraitM argument. The default is 1.

    + + +
    col1_title
    +

    Title for the column specified by the TraitM argument. The default is "".

    + + +
    exponentiate
    +

    Convert log odds ratios to odds ratios? Default is FALSE.

    + + +
    trans
    +

    Specify x-axis scale. e.g. "identity", "log2", etc. If set to "identity" an additive scale is used. If set to log2 the x-axis is plotted on a multiplicative / doubling scale (preferable when plotting odds ratios). Default is "identity".

    + + +
    ao_slc
    +

    Logical; retrieve trait subcategory information using available_outcomes(). Default is FALSE.

    + + +
    lo
    +

    Lower limit of X axis to plot.

    + + +
    up
    +

    upper limit of X axis to plot.

    + + +
    by
    +

    Name of the grouping variable to stratify results on. Default is NULL.

    + + +
    xlab
    +

    X-axis label, default is "Effect (95% confidence interval)".

    + + +
    addcols
    +

    Name of additional columns to plot. Character vector. The default is NULL.

    + + +
    addcol_widths
    +

    Widths of Y axis labels for additional columns specified by the addcols argument. Numeric vector. The default is NULL.

    + + +
    addcol_titles
    +

    Titles of additional columns specified by the addcols argument. Character vector. The default is NULL.

    + + +
    subheading_size
    +

    text size for the subheadings specified in by argument. The default is 6.

    + + +
    shape_points
    +

    the shape of the data points to pass to ggplot2::geom_point(). Default is set to 15 (filled square).

    + + +
    colour_scheme
    +

    the general colour scheme for the plot. Default is to make all text and data points "black".

    + + +
    col_text_size
    +

    The default is 5.

    + + +
    weight
    +

    The default is NULL.

    + +
    +
    +

    Value

    +

    grid plot object

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/forest_plot_basic.html b/docs/reference/forest_plot_basic.html new file mode 100644 index 00000000..ff10f67b --- /dev/null +++ b/docs/reference/forest_plot_basic.html @@ -0,0 +1,137 @@ + +A basic forest plot — forest_plot_basic • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    This function is used to create a basic forest plot. +It requires the output from format_mr_results().

    +
    + +
    +

    Usage

    +
    forest_plot_basic(
    +  dat,
    +  section = NULL,
    +  colour_group = NULL,
    +  colour_group_first = TRUE,
    +  xlab = NULL,
    +  bottom = TRUE,
    +  trans = "identity",
    +  xlim = NULL,
    +  threshold = NULL
    +)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from format_mr_results().

    + + +
    section
    +

    Which category in dat to plot. If NULL then prints everything.

    + + +
    colour_group
    +

    Which exposure to plot. If NULL then prints everything grouping by colour.

    + + +
    colour_group_first
    +

    The default is TRUE.

    + + +
    xlab
    +

    x-axis label. Default=NULL.

    + + +
    bottom
    +

    Show x-axis? Default=FALSE.

    + + +
    trans
    +

    Transformation of x axis.

    + + +
    xlim
    +

    x-axis limits.

    + + +
    threshold
    +

    p-value threshold to use for colouring points by significance level. If NULL (default) then colour layer won't be applied.

    + +
    +
    +

    Value

    +

    ggplot object

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/forest_plot_basic2.html b/docs/reference/forest_plot_basic2.html new file mode 100644 index 00000000..bf7dcc39 --- /dev/null +++ b/docs/reference/forest_plot_basic2.html @@ -0,0 +1,157 @@ + +A basic forest plot — forest_plot_basic2 • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    This function is used to create a basic forest plot. +It requires the output from format_1_to_many().

    +
    + +
    +

    Usage

    +
    forest_plot_basic2(
    +  dat,
    +  section = NULL,
    +  colour_group = NULL,
    +  colour_group_first = TRUE,
    +  xlab = NULL,
    +  bottom = TRUE,
    +  trans = "identity",
    +  xlim = NULL,
    +  lo = lo,
    +  up = up,
    +  subheading_size = subheading_size,
    +  colour_scheme = "black",
    +  shape_points = 15
    +)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from format_1_to_many()

    + + +
    section
    +

    Which category in dat to plot. If NULL then prints everything.

    + + +
    colour_group
    +

    Which exposure to plot. If NULL then prints everything grouping by colour.

    + + +
    colour_group_first
    +

    The default is TRUE.

    + + +
    xlab
    +

    x-axis label. Default=NULL.

    + + +
    bottom
    +

    Show x-axis? Default=FALSE.

    + + +
    trans
    +

    x-axis scale.

    + + +
    xlim
    +

    x-axis limits.

    + + +
    lo
    +

    Lower limit of x axis.

    + + +
    up
    +

    Upper limit of x axis.

    + + +
    subheading_size
    +

    text size for the subheadings. The subheadings correspond to the values of the section argument.

    + + +
    colour_scheme
    +

    the general colour scheme for the plot. Default is to make all text and data points "black".

    + + +
    shape_points
    +

    the shape of the data points to pass to ggplot2::geom_point(). Default is set to 15 (filled square).

    + +
    +
    +

    Value

    +

    ggplot object

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/format_1_to_many.html b/docs/reference/format_1_to_many.html new file mode 100644 index 00000000..db93fbc2 --- /dev/null +++ b/docs/reference/format_1_to_many.html @@ -0,0 +1,152 @@ + +Format MR results for a 1-to-many forest plot — format_1_to_many • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    This function formats user-supplied results for the forest_plot_1_to_many() function. +The user supplies their results in the form of a data frame. +The data frame is assumed to contain at least three columns of data:

    1. effect estimates, from an analysis of the effect of an exposure on an outcome;

    2. +
    3. standard errors for the effect estimates; and

    4. +
    5. a column of trait names, corresponding to the 'many' in a 1-to-many forest plot.

    6. +
    + +
    +

    Usage

    +
    format_1_to_many(
    +  mr_res,
    +  b = "b",
    +  se = "se",
    +  exponentiate = FALSE,
    +  ao_slc = FALSE,
    +  by = NULL,
    +  TraitM = "outcome",
    +  addcols = NULL,
    +  weight = NULL
    +)
    +
    + +
    +

    Arguments

    + + +
    mr_res
    +

    Data frame of results supplied by the user.

    + + +
    b
    +

    Name of the column specifying the effect of the exposure on the outcome. Default = "b".

    + + +
    se
    +

    Name of the column specifying the standard error for b. Default = "se".

    + + +
    exponentiate
    +

    Convert log odds ratios to odds ratios? Default=FALSE.

    + + +
    ao_slc
    +

    Logical; retrieve trait subcategory information using available_outcomes(). Default=FALSE.

    + + +
    by
    +

    Name of the column indicating a grouping variable to stratify results on. Default=NULL.

    + + +
    TraitM
    +

    The column specifying the names of the traits. Corresponds to 'many' in the 1-to-many forest plot. Default="outcome".

    + + +
    addcols
    +

    Name of any additional columns to add to the plot. Character vector. The default is NULL.

    + + +
    weight
    +

    The default is NULL.

    + +
    +
    +

    Value

    +

    data frame.

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/format_aries_mqtl.html b/docs/reference/format_aries_mqtl.html new file mode 100644 index 00000000..9bd0d7b2 --- /dev/null +++ b/docs/reference/format_aries_mqtl.html @@ -0,0 +1,96 @@ + +Get data from methylation QTL results — format_aries_mqtl • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    See format_data().

    +
    + +
    +

    Usage

    +
    format_aries_mqtl(aries_mqtl_subset, type = "exposure")
    +
    + +
    +

    Arguments

    + + +
    aries_mqtl_subset
    +

    Selected rows from aries_mqtl data loaded from MRInstruments package.

    + + +
    type
    +

    Are these data used as "exposure" or "outcome"? Default is "exposure".

    + +
    +
    +

    Value

    +

    Data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/format_d.html b/docs/reference/format_d.html new file mode 100644 index 00000000..580feb5e --- /dev/null +++ b/docs/reference/format_d.html @@ -0,0 +1,92 @@ + +Format the returned table from the MySQL database — format_d • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Format the returned table from the MySQL database

    +
    + +
    +

    Usage

    +
    format_d(d)
    +
    + +
    +

    Arguments

    + + +
    d
    +

    Data frame

    + +
    +
    +

    Value

    +

    Data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/format_data.html b/docs/reference/format_data.html new file mode 100644 index 00000000..6c8a722c --- /dev/null +++ b/docs/reference/format_data.html @@ -0,0 +1,212 @@ + +Read exposure or outcome data — format_data • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Reads in exposure data. Checks and organises columns for use with MR or enrichment tests. +Infers p-values when possible from beta and se.

    +
    + +
    +

    Usage

    +
    format_data(
    +  dat,
    +  type = "exposure",
    +  snps = NULL,
    +  header = TRUE,
    +  phenotype_col = "Phenotype",
    +  snp_col = "SNP",
    +  beta_col = "beta",
    +  se_col = "se",
    +  eaf_col = "eaf",
    +  effect_allele_col = "effect_allele",
    +  other_allele_col = "other_allele",
    +  pval_col = "pval",
    +  units_col = "units",
    +  ncase_col = "ncase",
    +  ncontrol_col = "ncontrol",
    +  samplesize_col = "samplesize",
    +  gene_col = "gene",
    +  id_col = "id",
    +  min_pval = 1e-200,
    +  z_col = "z",
    +  info_col = "info",
    +  chr_col = "chr",
    +  pos_col = "pos",
    +  log_pval = FALSE
    +)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Data frame. Must have header with at least SNP column present.

    + + +
    type
    +

    Is this the exposure or the outcome data that is being read in? The default is "exposure".

    + + +
    snps
    +

    SNPs to extract. If NULL then doesn't extract any and keeps all. The default is NULL.

    + + +
    header
    +

    The default is TRUE.

    + + +
    phenotype_col
    +

    Optional column name for the column with phenotype name corresponding the the SNP. If not present then will be created with the value "Outcome". The default is "Phenotype".

    + + +
    snp_col
    +

    Required name of column with SNP rs IDs. The default is "SNP".

    + + +
    beta_col
    +

    Required for MR. Name of column with effect sizes. The default is "beta".

    + + +
    se_col
    +

    Required for MR. Name of column with standard errors. The default is "se".

    + + +
    eaf_col
    +

    Required for MR. Name of column with effect allele frequency. The default is "eaf".

    + + +
    effect_allele_col
    +

    Required for MR. Name of column with effect allele. Must contain only the characters "A", "C", "T" or "G". The default is "effect_allele".

    + + +
    other_allele_col
    +

    Required for MR. Name of column with non effect allele. Must contain only the characters "A", "C", "T" or "G". The default is "other_allele".

    + + +
    pval_col
    +

    Required for enrichment tests. Name of column with p-value. The default is "pval".

    + + +
    units_col
    +

    Optional column name for units. The default is "units".

    + + +
    ncase_col
    +

    Optional column name for number of cases. The default is "ncase".

    + + +
    ncontrol_col
    +

    Optional column name for number of controls. The default is "ncontrol".

    + + +
    samplesize_col
    +

    Optional column name for sample size. The default is "samplesize".

    + + +
    gene_col
    +

    Optional column name for gene name. The default is "gene".

    + + +
    id_col
    +

    The default is "id".

    + + +
    min_pval
    +

    Minimum allowed p-value. The default is 1e-200.

    + + +
    z_col
    +

    The default is "z".

    + + +
    info_col
    +

    The default is "info_col".

    + + +
    chr_col
    +

    The default is "chr_col".

    + + +
    pos_col
    +

    The default is "pos".

    + + +
    log_pval
    +

    The pval is -log10(P). The default is FALSE.

    + +
    +
    +

    Value

    +

    data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/format_gtex_eqtl.html b/docs/reference/format_gtex_eqtl.html new file mode 100644 index 00000000..84bd358d --- /dev/null +++ b/docs/reference/format_gtex_eqtl.html @@ -0,0 +1,96 @@ + +Get data from eQTL catalog into correct format — format_gtex_eqtl • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    See format_data().

    +
    + +
    +

    Usage

    +
    format_gtex_eqtl(gtex_eqtl_subset, type = "exposure")
    +
    + +
    +

    Arguments

    + + +
    gtex_eqtl_subset
    +

    Selected rows from gtex_eqtl data loaded from MRInstruments package.

    + + +
    type
    +

    Are these data used as "exposure" or "outcome"? Default is "exposure".

    + +
    +
    +

    Value

    +

    Data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/format_gwas_catalog.html b/docs/reference/format_gwas_catalog.html new file mode 100644 index 00000000..fdaff75b --- /dev/null +++ b/docs/reference/format_gwas_catalog.html @@ -0,0 +1,106 @@ + +Get data selected from GWAS catalog into correct format — format_gwas_catalog • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    DEPRECATED. Please use format_data() instead.

    +
    + +
    +

    Usage

    +
    format_gwas_catalog(gwas_catalog_subset, type = "exposure")
    +
    + +
    +

    Arguments

    + + +
    gwas_catalog_subset
    +

    The GWAS catalog subset.

    + + +
    type
    +

    The default is "exposure".

    + +
    +
    +

    Value

    +

    Data frame

    +
    + +
    +

    Examples

    +
    if (FALSE) { # \dontrun{
    +require(MRInstruments)
    +data(gwas_catalog)
    +bmi <- subset(gwas_catalog, Phenotype=="Body mass index" & Year==2010 & grepl("kg", Units))
    +bmi <- format_data(bmi)
    +} # }
    +
    +
    +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/format_metab_qtls.html b/docs/reference/format_metab_qtls.html new file mode 100644 index 00000000..7cd01235 --- /dev/null +++ b/docs/reference/format_metab_qtls.html @@ -0,0 +1,96 @@ + +Get data from metabolomic QTL results — format_metab_qtls • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    See format_data().

    +
    + +
    +

    Usage

    +
    format_metab_qtls(metab_qtls_subset, type = "exposure")
    +
    + +
    +

    Arguments

    + + +
    metab_qtls_subset
    +

    Selected rows from metab_qtls data loaded from MRInstruments package.

    + + +
    type
    +

    Are these data used as "exposure" or "outcome"? Default is "exposure".

    + +
    +
    +

    Value

    +

    Data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/format_mr_results.html b/docs/reference/format_mr_results.html new file mode 100644 index 00000000..bf6c3bf8 --- /dev/null +++ b/docs/reference/format_mr_results.html @@ -0,0 +1,145 @@ + +Format MR results for forest plot — format_mr_results • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    This function takes the results from mr() and is particularly useful +if the MR has been applied using multiple exposures and multiple outcomes. +It creates a new data frame with the following:

    • Variables: exposure, outcome, category, outcome sample size, effect, upper ci, lower ci, pval, nsnp

    • +
    • only one estimate for each exposure-outcome

    • +
    • exponentiated effects if required

    • +
    + +
    +

    Usage

    +
    format_mr_results(
    +  mr_res,
    +  exponentiate = FALSE,
    +  single_snp_method = "Wald ratio",
    +  multi_snp_method = "Inverse variance weighted",
    +  ao_slc = TRUE,
    +  priority = "Cardiometabolic"
    +)
    +
    + +
    +

    Arguments

    + + +
    mr_res
    +

    Results from mr().

    + + +
    exponentiate
    +

    Convert effects to OR? The default is FALSE.

    + + +
    single_snp_method
    +

    Which of the single SNP methods to use when only 1 SNP was used to estimate the causal effect? The default is "Wald ratio".

    + + +
    multi_snp_method
    +

    Which of the multi-SNP methods to use when there was more than 1 SNPs used to estimate the causal effect? The default is "Inverse variance weighted".

    + + +
    ao_slc
    +

    Logical; retrieve sample size and subcategory using available_outcomes(). If set to FALSE mr_res must contain the following additional columns: subcategory and sample_size.

    + + +
    priority
    +

    Name of category to prioritise at the top of the forest plot. The default is "Cardiometabolic".

    + +
    +
    +

    Value

    +

    data frame.

    +
    +
    +

    Details

    +

    By default it uses the available_outcomes() function to retrieve the study level characteristics for the outcome trait, +including sample size and outcome category. +This assumes the MR analysis was performed using outcome GWAS(s) contained in OpenGWAS.

    +

    If ao_slc is set to TRUE then the user must supply their own study level characteristics. +This is useful when the user has supplied their own outcome GWAS results (i.e. they are not in OpenGWAS).

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/format_proteomic_qtls.html b/docs/reference/format_proteomic_qtls.html new file mode 100644 index 00000000..d16e191b --- /dev/null +++ b/docs/reference/format_proteomic_qtls.html @@ -0,0 +1,96 @@ + +Get data from proteomic QTL results — format_proteomic_qtls • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    See format_data().

    +
    + +
    +

    Usage

    +
    format_proteomic_qtls(proteomic_qtls_subset, type = "exposure")
    +
    + +
    +

    Arguments

    + + +
    proteomic_qtls_subset
    +

    Selected rows from proteomic_qtls data loaded from MRInstruments package.

    + + +
    type
    +

    Are these data used as "exposure" or "outcome"? Default is "exposure".

    + +
    +
    +

    Value

    +

    Data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/generate_odds_ratios.html b/docs/reference/generate_odds_ratios.html new file mode 100644 index 00000000..0378ee6a --- /dev/null +++ b/docs/reference/generate_odds_ratios.html @@ -0,0 +1,92 @@ + +Generate odds ratios — generate_odds_ratios • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    This function takes b and se from mr() and generates odds ratios and 95 percent confidence intervals.

    +
    + +
    +

    Usage

    +
    generate_odds_ratios(mr_res)
    +
    + +
    +

    Arguments

    + + +
    mr_res
    +

    Results from mr().

    + +
    +
    +

    Value

    +

    data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/get_p_from_r2n.html b/docs/reference/get_p_from_r2n.html new file mode 100644 index 00000000..86d0e83e --- /dev/null +++ b/docs/reference/get_p_from_r2n.html @@ -0,0 +1,96 @@ + +Calculate p-value from R-squared and sample size — get_p_from_r2n • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Calculate p-value from R-squared and sample size

    +
    + +
    +

    Usage

    +
    get_p_from_r2n(r2, n)
    +
    + +
    +

    Arguments

    + + +
    r2
    +

    Rsq

    + + +
    n
    +

    Sample size

    + +
    +
    +

    Value

    +

    P-value

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/get_population_allele_frequency.html b/docs/reference/get_population_allele_frequency.html new file mode 100644 index 00000000..1f61512e --- /dev/null +++ b/docs/reference/get_population_allele_frequency.html @@ -0,0 +1,104 @@ + +Estimate the allele frequency in population from case/control summary data — get_population_allele_frequency • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Estimate the allele frequency in population from case/control summary data

    +
    + +
    +

    Usage

    +
    get_population_allele_frequency(af, prop, odds_ratio, prevalence)
    +
    + +
    +

    Arguments

    + + +
    af
    +

    Effect allele frequency (or MAF)

    + + +
    prop
    +

    Proportion of samples that are cases

    + + +
    odds_ratio
    +

    Odds ratio

    + + +
    prevalence
    +

    Population disease prevalence

    + +
    +
    +

    Value

    +

    Population allele frequency

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/get_r_from_bsen.html b/docs/reference/get_r_from_bsen.html new file mode 100644 index 00000000..5f5b09e7 --- /dev/null +++ b/docs/reference/get_r_from_bsen.html @@ -0,0 +1,100 @@ + +Estimate R-squared from beta, standard error and sample size — get_r_from_bsen • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Estimate R-squared from beta, standard error and sample size

    +
    + +
    +

    Usage

    +
    get_r_from_bsen(b, se, n)
    +
    + +
    +

    Arguments

    + + +
    b
    +

    Array of effect sizes

    + + +
    se
    +

    Array of standard errors

    + + +
    n
    +

    Array of (effective) sample sizes

    + +
    +
    +

    Value

    +

    Vector of signed r values

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/get_r_from_lor.html b/docs/reference/get_r_from_lor.html new file mode 100644 index 00000000..91de64c6 --- /dev/null +++ b/docs/reference/get_r_from_lor.html @@ -0,0 +1,130 @@ + +Estimate proportion of variance of liability explained by SNP in general population — get_r_from_lor • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    This uses equation 10 in Lee et al. A Better Coefficient of Determination for Genetic Profile Analysis. +Genetic Epidemiology 36: 214–224 (2012) doi:10.1002/gepi.21614 +.

    +
    + +
    +

    Usage

    +
    get_r_from_lor(
    +  lor,
    +  af,
    +  ncase,
    +  ncontrol,
    +  prevalence,
    +  model = "logit",
    +  correction = FALSE
    +)
    +
    + +
    +

    Arguments

    + + +
    lor
    +

    Vector of Log odds ratio.

    + + +
    af
    +

    Vector of allele frequencies.

    + + +
    ncase
    +

    Vector of Number of cases.

    + + +
    ncontrol
    +

    Vector of Number of controls.

    + + +
    prevalence
    +

    Vector of Disease prevalence in the population.

    + + +
    model
    +

    Is the effect size estimated from the "logit" (default) or "probit" model.

    + + +
    correction
    +

    Scale the estimated r by correction value. The default is FALSE.

    + +
    +
    +

    Value

    +

    Vector of signed r values

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/get_r_from_pn.html b/docs/reference/get_r_from_pn.html new file mode 100644 index 00000000..b225ef19 --- /dev/null +++ b/docs/reference/get_r_from_pn.html @@ -0,0 +1,102 @@ + +Calculate variance explained from p-values and sample size — get_r_from_pn • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    This method is an approximation, and may be numerically unstable. +Ideally you should estimate r directly from independent replication samples. +Use get_r_from_lor() for binary traits.

    +
    + +
    +

    Usage

    +
    get_r_from_pn(p, n)
    +
    + +
    +

    Arguments

    + + +
    p
    +

    Array of pvals

    + + +
    n
    +

    Array of sample sizes

    + +
    +
    +

    Value

    +

    Vector of r values (all arbitrarily positive)

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/get_se.html b/docs/reference/get_se.html new file mode 100644 index 00000000..8b7e940a --- /dev/null +++ b/docs/reference/get_se.html @@ -0,0 +1,96 @@ + +Get SE from effect size and p-value — get_se • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Get SE from effect size and p-value

    +
    + +
    +

    Usage

    +
    get_se(eff, pval)
    +
    + +
    +

    Arguments

    + + +
    eff
    +

    effect size

    + + +
    pval
    +

    p-values

    + +
    +
    +

    Value

    +

    array

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/harmonise_data.html b/docs/reference/harmonise_data.html new file mode 100644 index 00000000..92633d93 --- /dev/null +++ b/docs/reference/harmonise_data.html @@ -0,0 +1,130 @@ + +Harmonise the alleles and effects between the exposure and outcome — harmonise_data • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    In order to perform MR the effect of a SNP on an outcome and exposure must be harmonised to be +relative to the same allele.

    +
    + +
    +

    Usage

    +
    harmonise_data(exposure_dat, outcome_dat, action = 2)
    +
    + +
    +

    Arguments

    + + +
    exposure_dat
    +

    Output from read_exposure_data().

    + + +
    outcome_dat
    +

    Output from extract_outcome_data().

    + + +
    action
    +

    Level of strictness in dealing with SNPs.

    • action = 1: Assume all alleles are coded on the forward strand, i.e. do not attempt to flip alleles

    • +
    • action = 2: Try to infer positive strand alleles, using allele frequencies for palindromes (default, conservative);

    • +
    • action = 3: Correct strand for non-palindromic SNPs, and drop all palindromic SNPs from the analysis (more conservative). +If a single value is passed then this action is applied to all outcomes. +But multiple values can be supplied as a vector, each element relating to a different outcome.

    • +
    + +
    +
    +

    Value

    +

    Data frame with harmonised effects and alleles

    +
    +
    +

    Details

    +

    Expects data in the format generated by read_exposure_data() and extract_outcome_data(). +This means the inputs must be dataframes with the following columns:

    +

    outcome_dat:

    • SNP

    • +
    • beta.outcome

    • +
    • se.outcome

    • +
    • effect_allele.outcome

    • +
    • other_allele.outcome

    • +
    • eaf.outcome

    • +
    • outcome

    • +

    exposure_dat:

    • SNP

    • +
    • beta.exposure

    • +
    • se.exposure

    • +
    • effect_allele.exposure

    • +
    • other_allele.exposure

    • +
    • eaf.exposure

    • +

    The function tries to harmonise INDELs. If they are coded as sequence strings things work more smoothly. +If they are coded as D/I in one dataset it will try to convert them to sequences if the other dataset has adequate information. +If coded as D/I in one dataset and as a variant with equal length INDEL alleles in the other, the variant is dropped. +If one or both the datasets only has one allele (i.e. the effect allele) then harmonisation is naturally going to be more ambiguous and more variants will be dropped.

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/harmonise_ld_dat.html b/docs/reference/harmonise_ld_dat.html new file mode 100644 index 00000000..7d6917ea --- /dev/null +++ b/docs/reference/harmonise_ld_dat.html @@ -0,0 +1,96 @@ + +Harmonise LD matrix against summary data — harmonise_ld_dat • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    LD matrix returns with rsid_ea_oa identifiers. Make sure that they are oriented to the same effect allele as the summary dataset. Summary dataset can be exposure dataset or harmonised dartaset.

    +
    + +
    +

    Usage

    +
    harmonise_ld_dat(x, ld)
    +
    + +
    +

    Arguments

    + + +
    x
    +

    Exposure dataset or harmonised dataset

    + + +
    ld
    +

    Output from ld_matrix()

    + +
    +
    +

    Value

    +

    List of exposure dataset and harmonised LD matrix

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/index.html b/docs/reference/index.html new file mode 100644 index 00000000..e0863929 --- /dev/null +++ b/docs/reference/index.html @@ -0,0 +1,757 @@ + +Package index • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    All functions

    + + + + +
    + + + + +
    + + Isq() + +
    +
    I-squared calculation
    +
    + + add_metadata() + +
    +
    Add meta data to extracted data
    +
    + + add_rsq() + +
    +
    Estimate r-square of each association
    +
    + + allele_frequency() + +
    +
    Estimate allele frequency from SNP
    +
    + + available_outcomes() + +
    +
    Get list of studies with available GWAS summary statistics through API
    +
    + + clump_data() + +
    +
    Perform LD clumping on SNP data
    +
    + + combine_all_mrresults() + +
    +
    Combine all mr results
    +
    + + combine_data() + +
    +
    Combine data
    +
    + + contingency() + +
    +
    Obtain 2x2 contingency table from marginal parameters and odds ratio
    +
    + + convert_outcome_to_exposure() + +
    +
    Convert outcome data to exposure data
    +
    + + dat_to_MRInput() + +
    +
    Convert TwoSampleMR format to MendelianRandomization format
    +
    + + dat_to_RadialMR() + +
    +
    Convert dat to RadialMR format
    +
    + + default_parameters() + +
    +
    List of parameters for use with MR functions
    +
    + + directionality_test() + +
    +
    Perform MR Steiger test of directionality
    +
    + + effective_n() + +
    +
    Estimate the effective sample size in a case control study
    +
    + + enrichment() + +
    +
    Perform enrichment analysis
    +
    + + enrichment_method_list() + +
    +
    Get list of available p-value enrichment methods
    +
    + + estimate_trait_sd() + +
    +
    Estimate trait SD by obtaining beta estimates from z-scores and finding the ratio with original beta values
    +
    + + extract_instruments() + +
    +
    Find instruments for use in MR from the OpenGWAS database
    +
    + + extract_outcome_data() + +
    +
    Supply the output from read_exposure_data() and all the SNPs therein will be queried against the requested outcomes in remote database using API.
    +
    + + fishers_combined_test() + +
    +
    Fisher's combined test
    +
    + + forest_plot() + +
    +
    Forest plot for multiple exposures and multiple outcomes
    +
    + + forest_plot_1_to_many() + +
    +
    1-to-many forest plot
    +
    + + forest_plot_basic2() + +
    +
    A basic forest plot
    +
    + + format_1_to_many() + +
    +
    Format MR results for a 1-to-many forest plot
    +
    + + format_aries_mqtl() + +
    +
    Get data from methylation QTL results
    +
    + + format_data() + +
    +
    Read exposure or outcome data
    +
    + + format_gtex_eqtl() + +
    +
    Get data from eQTL catalog into correct format
    +
    + + format_gwas_catalog() + +
    +
    Get data selected from GWAS catalog into correct format
    +
    + + format_metab_qtls() + +
    +
    Get data from metabolomic QTL results
    +
    + + format_mr_results() + +
    +
    Format MR results for forest plot
    +
    + + format_proteomic_qtls() + +
    +
    Get data from proteomic QTL results
    +
    + + generate_odds_ratios() + +
    +
    Generate odds ratios
    +
    + + get_p_from_r2n() + +
    +
    Calculate p-value from R-squared and sample size
    +
    + + get_population_allele_frequency() + +
    +
    Estimate the allele frequency in population from case/control summary data
    +
    + + get_r_from_bsen() + +
    +
    Estimate R-squared from beta, standard error and sample size
    +
    + + get_r_from_lor() + +
    +
    Estimate proportion of variance of liability explained by SNP in general population
    +
    + + get_r_from_pn() + +
    +
    Calculate variance explained from p-values and sample size
    +
    + + get_se() + +
    +
    Get SE from effect size and p-value
    +
    + + harmonise_data() + +
    +
    Harmonise the alleles and effects between the exposure and outcome
    +
    + + harmonise_ld_dat() + +
    +
    Harmonise LD matrix against summary data
    +
    + + ld_matrix() + +
    +
    Get LD matrix for list of SNPs
    +
    + + ldsc_h2() + +
    +
    Univariate LDSC
    +
    + + ldsc_rg() + +
    +
    Bivariate LDSC
    +
    + + make_dat() + +
    +
    Convenient function to create a harmonised dataset
    +
    + + mr() + +
    +
    Perform all Mendelian randomization tests
    +
    + + mr_density_plot() + +
    +
    Density plot
    +
    + + mr_egger_regression() + +
    +
    Egger's regression for Mendelian randomization
    +
    + + mr_egger_regression_bootstrap() + +
    +
    Run bootstrap to generate standard errors for MR
    +
    + + mr_forest_plot() + +
    +
    Forest plot
    +
    + + mr_funnel_plot() + +
    +
    Funnel plot
    +
    + + mr_heterogeneity() + +
    +
    Get heterogeneity statistics
    +
    + + mr_ivw() + +
    +
    Inverse variance weighted regression
    +
    + + mr_ivw_fe() + +
    +
    Inverse variance weighted regression (fixed effects)
    +
    + + mr_ivw_mre() + +
    +
    Inverse variance weighted regression (multiplicative random effects model)
    +
    + + mr_ivw_radial() + +
    +
    Radial IVW analysis
    +
    + + mr_leaveoneout() + +
    +
    Leave one out sensitivity analysis
    +
    + + mr_leaveoneout_plot() + +
    +
    Plot results from leaveoneout analysis
    +
    + + mr_median() + +
    +
    MR median estimators
    +
    + + mr_meta_fixed() + +
    +
    Perform 2 sample IV using fixed effects meta analysis and delta method for standard errors
    +
    + + mr_meta_fixed_simple() + +
    +
    Perform 2 sample IV using simple standard error
    +
    + + mr_meta_random() + +
    +
    Perform 2 sample IV using random effects meta analysis and delta method for standard errors
    +
    + + mr_method_list() + +
    +
    Get list of available MR methods
    +
    + + mr_mode() + +
    +
    MR mode estimators
    +
    + + mr_moe() + +
    +
    Mixture of experts
    +
    + + mr_penalised_weighted_median() + +
    +
    Penalised weighted median MR
    +
    + + mr_pleiotropy_test() + +
    +
    Test for horizontal pleiotropy in MR analysis
    +
    + + mr_raps() + +
    +
    Robust adjusted profile score
    +
    + + mr_report() + +
    +
    Generate MR report
    +
    + + mr_rucker() + +
    +
    MR Rucker framework
    +
    + + mr_rucker_bootstrap() + +
    +
    Run rucker with bootstrap estimates
    +
    + + mr_rucker_cooksdistance() + +
    +
    MR Rucker with outliers automatically detected and removed
    +
    + + mr_rucker_jackknife() + +
    +
    Run rucker with jackknife estimates
    +
    + + mr_scatter_plot() + +
    +
    Create scatter plot with lines showing the causal estimate for different MR tests
    +
    + + mr_sign() + +
    +
    MR sign test
    +
    + + mr_simple_median() + +
    +
    Simple median method
    +
    + + mr_simple_mode() + +
    +
    MR simple mode estimator
    +
    + + mr_simple_mode_nome() + +
    +
    MR simple mode estimator (NOME)
    +
    + + mr_singlesnp() + +
    +
    Perform 2 sample MR on each SNP individually
    +
    + + mr_steiger() + +
    +
    MR Steiger test of directionality
    +
    + + mr_steiger2() + +
    +
    MR Steiger test of directionality
    +
    + + mr_two_sample_ml() + +
    +
    Maximum likelihood MR method
    +
    + + mr_uwr() + +
    +
    Unweighted regression
    +
    + + mr_wald_ratio() + +
    +
    Perform 2 sample IV using Wald ratio.
    +
    + + mr_weighted_median() + +
    +
    Weighted median method
    +
    + + mr_weighted_mode() + +
    +
    MR weighted mode estimator
    +
    + + mr_weighted_mode_nome() + +
    +
    MR weighted mode estimator (NOME)
    +
    + + mr_wrapper() + +
    +
    Perform full set of MR analyses
    +
    + + mv_basic() + +
    +
    Perform basic multivariable MR
    +
    + + mv_extract_exposures() + +
    +
    Extract exposure variables for multivariable MR
    +
    + + mv_extract_exposures_local() + +
    +
    Attempt to perform MVMR using local data
    +
    + + mv_harmonise_data() + +
    +
    Harmonise exposure and outcome for multivariable MR
    +
    + + mv_ivw() + +
    +
    Perform IVW multivariable MR
    +
    + + mv_lasso_feature_selection() + +
    +
    Apply LASSO feature selection to mvdat object
    +
    + + mv_multiple() + +
    +
    Perform IVW multivariable MR
    +
    + + mv_residual() + +
    +
    Perform basic multivariable MR
    +
    + + mv_subset() + +
    +
    Perform multivariable MR on subset of features
    +
    + + power_prune() + +
    +
    Power prune
    +
    + + read_exposure_data() + +
    +
    Read exposure data
    +
    + + read_outcome_data() + +
    +
    Read outcome data
    +
    + + run_mr_presso() + +
    +
    Wrapper for MR-PRESSO
    +
    + + run_mrmix() + +
    +
    Perform MRMix analysis on harmonised dat object
    +
    + + size.prune() + +
    +
    Size prune
    +
    + + sort_1_to_many() + +
    +
    Sort results for 1-to-many forest plot
    +
    + + split_exposure() + +
    +
    Split exposure column
    +
    + + split_outcome() + +
    +
    Split outcome column
    +
    + + standardise_units() + +
    +
    Try to standardise continuous traits to be in standard deviation units
    +
    + + steiger_filtering() + +
    +
    Steiger filtering function
    +
    + + steiger_sensitivity() + +
    +
    Evaluate the Steiger test's sensitivity to measurement error
    +
    + + subset_on_method() + +
    +
    Subset MR-results on method
    +
    + + trim() + +
    +
    Trim function to remove leading and trailing blank spaces
    +
    + + weighted_median() + +
    +
    Weighted median method
    +
    + + weighted_median_bootstrap() + +
    +
    Calculate standard errors for weighted median method using bootstrap
    +
    +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/knit_report.html b/docs/reference/knit_report.html new file mode 100644 index 00000000..b2458bc5 --- /dev/null +++ b/docs/reference/knit_report.html @@ -0,0 +1,119 @@ + +Knit report using working environment — knit_report • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Warning: It is quite likely that this will be called within an Rmd file +implying a recursive call to knit(). This will generate "duplicate label" +errors for unlabelled chunks. To avoid this, all code chunks +in your Rmd file should be named. +Supposedly this error can also be avoided by setting the following option: +options(knitr.duplicate.label = 'allow'). +I tried this but it didn't seem to help.

    +
    + +
    +

    Usage

    +
    knit_report(input_filename, output_filename, ...)
    +
    + +
    +

    Arguments

    + + +
    input_filename
    +

    Rmd file.

    + + +
    output_filename
    +

    Markdown or HTML output file. An HTML file +is specified using the .htm, .html, .HTM or .HTML file extension. +When html is specified, a similarly named markdown file is also +generated. +All output files including cache and figures will appear in the +same folder as output_filename.

    + + +
    ...
    +

    Arguments to be passed to knitr::knit()

    + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/ld_matrix.html b/docs/reference/ld_matrix.html new file mode 100644 index 00000000..451ef587 --- /dev/null +++ b/docs/reference/ld_matrix.html @@ -0,0 +1,120 @@ + +Get LD matrix for list of SNPs — ld_matrix • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    This function takes a list of SNPs and searches for them in a specified super-population in the 1000 Genomes phase 3 reference panel. +It then creates an LD matrix of r values (signed, and not squared). +All LD values are with respect to the major alleles in the 1000G dataset. +You can specify whether the allele names are displayed.

    +
    + +
    +

    Usage

    +
    ld_matrix(snps, with_alleles = TRUE, pop = "EUR")
    +
    + +
    +

    Arguments

    + + +
    snps
    +

    List of SNPs.

    + + +
    with_alleles
    +

    Whether to append the allele names to the SNP names. The default is TRUE.

    + + +
    pop
    +

    Super-population to use as reference panel. Default = "EUR". Options are "EUR", "SAS", "EAS", "AFR", "AMR". 'legacy' also available - which is a previously used version of the EUR panel with a slightly different set of markers.

    + +
    +
    +

    Value

    +

    Matrix of LD r values

    +
    +
    +

    Details

    +

    The data used for generating the LD matrix includes only bi-allelic SNPs with MAF > 0.01, +so it's quite possible that a variant you want to include will be absent. +If it is absent, it will be automatically excluded from the results.

    +

    You can check if your variants are present in the LD reference panel using ieugwasr::ld_reflookup().

    +

    This function does put load on the OpenGWAS servers, which makes life more difficult for other users, +and has been limited to analyse only up to 500 variants at a time. +We have implemented a method and made available the LD reference panels to perform the operation locally, +see ieugwasr::ld_matrix() and related vignettes for details.

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/ldsc_h2.html b/docs/reference/ldsc_h2.html new file mode 100644 index 00000000..b4e7f23a --- /dev/null +++ b/docs/reference/ldsc_h2.html @@ -0,0 +1,111 @@ + +Univariate LDSC — ldsc_h2 • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Imported here to help estimate sample overlap between studies

    +
    + +
    +

    Usage

    +
    ldsc_h2(id, ancestry = "infer", snpinfo = NULL, splitsize = 20000)
    +
    + +
    +

    Arguments

    + + +
    id
    +

    ID to analyse

    + + +
    ancestry
    +

    ancestry of traits 1 and 2 (AFR, AMR, EAS, EUR, SAS) or 'infer' (default) in which case it will try to guess based on allele frequencies

    + + +
    snpinfo
    +

    Output from ieugwasr::afl2_list("hapmap3"), or NULL for it to be done automatically

    + + +
    splitsize
    +

    How many SNPs to extract at one time. Default=20000

    + +
    +
    +

    Value

    +

    model fit

    +
    +
    +

    References

    +

    Bulik-Sullivan,B.K. et al. (2015) An atlas of genetic correlations across human diseases and traits. Nat. Genet. 47, 1236–1241.

    +

    Guo,B. and Wu,B. (2018) Principal component based adaptive association test of multiple traits using GWAS summary statistics. bioRxiv 269597; doi: 10.1101/269597

    +

    Gua,B. and Wu,B. (2019) Integrate multiple traits to detect novel trait-gene association using GWAS summary data with an adaptive test approach. Bioinformatics. 2019 Jul 1;35(13):2251-2257. doi: 10.1093/bioinformatics/bty961.

    +

    https://github.com/baolinwu/MTAR

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/ldsc_h2_internal.html b/docs/reference/ldsc_h2_internal.html new file mode 100644 index 00000000..7f9f3dc8 --- /dev/null +++ b/docs/reference/ldsc_h2_internal.html @@ -0,0 +1,104 @@ + +Univariate LDSC — ldsc_h2_internal • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Imported here to help estimate sample overlap between studies

    +
    + +
    +

    Usage

    +
    ldsc_h2_internal(Z, r2, N, W = NULL)
    +
    + +
    +

    Arguments

    + + +
    Z
    +

    summary Z-statistics for M variants

    + + +
    r2
    +

    average reference LD scores for M variants

    + + +
    N
    +

    GWAS sample size for each variant (could be different across variants)

    + + +
    W
    +

    variant weight

    + +
    +
    +

    Value

    +

    model fit

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/ldsc_rg.html b/docs/reference/ldsc_rg.html new file mode 100644 index 00000000..11771261 --- /dev/null +++ b/docs/reference/ldsc_rg.html @@ -0,0 +1,108 @@ + +Bivariate LDSC — ldsc_rg • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Imported here to help estimate sample overlap between studies

    +
    + +
    +

    Usage

    +
    ldsc_rg(id1, id2, ancestry = "infer", snpinfo = NULL, splitsize = 20000)
    +
    + +
    +

    Arguments

    + + +
    id1
    +

    ID 1 to analyse

    + + +
    id2
    +

    ID 2 to analyse

    + + +
    ancestry
    +

    ancestry of traits 1 and 2 (AFR, AMR, EAS, EUR, SAS) or 'infer' (default) in which case it will try to guess based on allele frequencies

    + + +
    snpinfo
    +

    Output from ieugwasr::afl2_list("hapmap3"), or NULL for it to be done automatically

    + + +
    splitsize
    +

    How many SNPs to extract at one time. Default=20000

    + +
    +
    +

    Value

    +

    model fit

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/ldsc_rg_internal.html b/docs/reference/ldsc_rg_internal.html new file mode 100644 index 00000000..329c88b8 --- /dev/null +++ b/docs/reference/ldsc_rg_internal.html @@ -0,0 +1,127 @@ + +Bivariate LDSC — ldsc_rg_internal • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Imported here to help estimate sample overlap between studies

    +
    + +
    +

    Usage

    +
    ldsc_rg_internal(Zs, r2, h1, h2, N1, N2, Nc = 0, W = NULL)
    +
    + +
    +

    Arguments

    + + +
    Zs
    +

    Mx2 matrix of summary Z-statistics for M variants from two GWAS

    + + +
    r2
    +

    average reference LD scores for M variants

    + + +
    h1
    +

    hsq for trait 1

    + + +
    h2
    +

    hsq for trait 2

    + + +
    N1
    +

    sample size for the 1st GWAS

    + + +
    N2
    +

    sample size for the 2nd GWAS

    + + +
    Nc
    +

    overlapped sample size between the two GWAS

    + + +
    W
    +

    variant weight

    + +
    +
    +

    Value

    +

    List of models

    +
    +
    +

    References

    +

    Bulik-Sullivan,B.K. et al. (2015) An atlas of genetic correlations across human diseases and traits. Nat. Genet. 47, 1236–1241.

    +

    Guo,B. and Wu,B. (2018) Principal component based adaptive association test of multiple traits using GWAS summary statistics. bioRxiv 269597; doi: 10.1101/269597

    +

    Gua,B. and Wu,B. (2019) Integrate multiple traits to detect novel trait-gene association using GWAS summary data with an adaptive test approach. Bioinformatics. 2019 Jul 1;35(13):2251-2257. doi: 10.1093/bioinformatics/bty961.

    +

    https://github.com/baolinwu/MTAR

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/make_dat.html b/docs/reference/make_dat.html new file mode 100644 index 00000000..37bcec83 --- /dev/null +++ b/docs/reference/make_dat.html @@ -0,0 +1,104 @@ + +Convenient function to create a harmonised dataset — make_dat • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Convenient function to create a harmonised dataset.

    +
    + +
    +

    Usage

    +
    make_dat(
    +  exposures = c("ieu-a-2", "ieu-a-301"),
    +  outcomes = c("ieu-a-7", "ieu-a-1001"),
    +  proxies = TRUE
    +)
    +
    + +
    +

    Arguments

    + + +
    exposures
    +

    The default is c("ieu-a-2", "ieu-a-301") (BMI and LDL).

    + + +
    outcomes
    +

    The default is c("ieu-a-7", "ieu-a-1001") (CHD and EDU).

    + + +
    proxies
    +

    Look for proxies? Default = TRUE

    + +
    +
    +

    Value

    +

    Harmonised data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr.html b/docs/reference/mr.html new file mode 100644 index 00000000..ea38a921 --- /dev/null +++ b/docs/reference/mr.html @@ -0,0 +1,110 @@ + +Perform all Mendelian randomization tests — mr • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Perform all Mendelian randomization tests

    +
    + +
    +

    Usage

    +
    mr(
    +  dat,
    +  parameters = default_parameters(),
    +  method_list = subset(mr_method_list(), use_by_default)$obj
    +)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Harmonised exposure and outcome data. Output from harmonise_data().

    + + +
    parameters
    +

    Parameters to be used for various MR methods. Default is output from default_parameters().

    + + +
    method_list
    +

    List of methods to use in analysis. See mr_method_list() for details.

    + +
    +
    +

    Value

    +

    List with the following elements:

    mr
    +

    Table of MR results

    + +
    extra
    +

    Table of extra results

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_density_plot.html b/docs/reference/mr_density_plot.html new file mode 100644 index 00000000..caa2fe66 --- /dev/null +++ b/docs/reference/mr_density_plot.html @@ -0,0 +1,109 @@ + +Density plot — mr_density_plot • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Density plot

    +
    + +
    +

    Usage

    +
    mr_density_plot(
    +  singlesnp_results,
    +  mr_results,
    +  exponentiate = FALSE,
    +  bandwidth = "nrd0"
    +)
    +
    + +
    +

    Arguments

    + + +
    singlesnp_results
    +

    from mr_singlesnp().

    + + +
    mr_results
    +

    Results from mr().

    + + +
    exponentiate
    +

    Plot on exponentiated scale. The default is FALSE.

    + + +
    bandwidth
    +

    Density bandwidth parameter.

    + +
    +
    +

    Value

    +

    List of plots

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_egger_regression.html b/docs/reference/mr_egger_regression.html new file mode 100644 index 00000000..b8d8449f --- /dev/null +++ b/docs/reference/mr_egger_regression.html @@ -0,0 +1,135 @@ + +Egger's regression for Mendelian randomization — mr_egger_regression • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Egger's regression for Mendelian randomization

    +
    + +
    +

    Usage

    +
    mr_egger_regression(b_exp, b_out, se_exp, se_out, parameters)
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure.

    + + +
    b_out
    +

    Vector of genetic effects on outcome.

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure.

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome.

    + + +
    parameters
    +

    List of parameters.

    + +
    +
    +

    Value

    +

    List of with the following elements:

    b
    +

    MR estimate

    + +
    se
    +

    Standard error of MR estimate

    + +
    pval
    +

    p-value of MR estimate

    + +
    b_i
    +

    Estimate of horizontal pleiotropy (intercept)

    + +
    se_i
    +

    Standard error of intercept

    + +
    pval_i
    +

    p-value of intercept

    + +
    Q, Q_df, Q_pval
    +

    Heterogeneity stats

    + +
    mod
    +

    Summary of regression

    + +
    dat
    +

    Original data used for MR Egger regression

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_egger_regression_bootstrap.html b/docs/reference/mr_egger_regression_bootstrap.html new file mode 100644 index 00000000..e6561304 --- /dev/null +++ b/docs/reference/mr_egger_regression_bootstrap.html @@ -0,0 +1,132 @@ + +Run bootstrap to generate standard errors for MR — mr_egger_regression_bootstrap • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Run bootstrap to generate standard errors for MR

    +
    + +
    +

    Usage

    +
    mr_egger_regression_bootstrap(b_exp, b_out, se_exp, se_out, parameters)
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure.

    + + +
    b_out
    +

    Vector of genetic effects on outcome.

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure.

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome.

    + + +
    parameters
    +

    List of parameters. Specifically, the nboot parameter can be specified for the number of bootstrap replications. The default is parameters=list(nboot=1000).

    + +
    +
    +

    Value

    +

    List of with the following elements:

    b
    +

    MR estimate

    + +
    se
    +

    Standard error of MR estimate

    + +
    pval
    +

    p-value of MR estimate

    + +
    b_i
    +

    Estimate of horizontal pleiotropy (intercept)

    + +
    se_i
    +

    Standard error of intercept

    + +
    pval_i
    +

    p-value of intercept

    + +
    mod
    +

    Summary of regression

    + +
    dat
    +

    Original data used for MR Egger regression

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_forest_plot.html b/docs/reference/mr_forest_plot.html new file mode 100644 index 00000000..fe8cd296 --- /dev/null +++ b/docs/reference/mr_forest_plot.html @@ -0,0 +1,96 @@ + +Forest plot — mr_forest_plot • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Forest plot

    +
    + +
    +

    Usage

    +
    mr_forest_plot(singlesnp_results, exponentiate = FALSE)
    +
    + +
    +

    Arguments

    + + +
    singlesnp_results
    +

    from mr_singlesnp().

    + + +
    exponentiate
    +

    Plot on exponential scale. The default is FALSE.

    + +
    +
    +

    Value

    +

    List of plots

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_forest_plot_grouped.html b/docs/reference/mr_forest_plot_grouped.html new file mode 100644 index 00000000..36cdbd74 --- /dev/null +++ b/docs/reference/mr_forest_plot_grouped.html @@ -0,0 +1,164 @@ + +Grouped forest plot — mr_forest_plot_grouped • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Grouped forest plot

    +
    + +
    +

    Usage

    +
    mr_forest_plot_grouped(
    +  name,
    +  eff_Col = "b",
    +  exposure_Name = "exposure",
    +  outcome_Name = "outcome",
    +  forest_Title = "",
    +  outfile_Name = "annot_FP.pdf",
    +  left_Col_Names = c("Exposure", "Outcome"),
    +  left_Col_Titles = NULL,
    +  right_Col_Names = c("p", "Outcome.n.case", "Outcome.n.control", "Outcome.sample.size"),
    +  right_Col_Titles = NULL,
    +  debug = FALSE,
    +  log_ES = FALSE,
    +  decrease = TRUE,
    +  returnRobj = TRUE,
    +  se_Col = "se"
    +)
    +
    + +
    +

    Arguments

    + + +
    name
    +

    (character) name of the delimited file containing all of the results on the first sheet (needs to have headers), or of the r object.

    + + +
    eff_Col
    +

    (character) name of the column in the delimited file that contains the effect sizes.

    + + +
    exposure_Name
    +

    (character) name of the column in the delimited file containing the types of studies.

    + + +
    outcome_Name
    +

    (character) name of the column in the delimited file containing the names of each study.

    + + +
    forest_Title
    +

    (character) the title to be used for a forest plot.

    + + +
    outfile_Name
    +

    (character) name to be used for output file (.pdf) or (.wmf).

    + + +
    left_Col_Names
    +

    (character vector) vector containing the names of the left-hand-side annotation columns in the delimited file.

    + + +
    left_Col_Titles
    +

    (character vector) vector containing the titles for each left-hand-side annotation column.

    + + +
    right_Col_Names
    +

    (character vector) vector containing the names of the right-hand-side annotation columns in the delimited file.

    + + +
    right_Col_Titles
    +

    (character vector) vector containing the titles for each right-hand-side annotation column.

    + + +
    debug
    +

    (logical) show warnings TRUE/FALSE?

    + + +
    log_ES
    +

    (logical) perform natural log transform of effect sizes and confidence bounds TRUE/FALSE?

    + + +
    decrease
    +

    (logical) sort the studies by decreasing effect sizes TRUE/FALSE?

    + + +
    returnRobj
    +

    (logical) return the graph as an internal R object TRUE/FALSE?

    + + +
    se_Col
    +

    (character) name of the column giving the standard error of the effect sizes.

    + +
    +
    +

    Value

    +

    grid object giving the forest plot (or plot as pdf)

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_funnel_plot.html b/docs/reference/mr_funnel_plot.html new file mode 100644 index 00000000..6e072644 --- /dev/null +++ b/docs/reference/mr_funnel_plot.html @@ -0,0 +1,92 @@ + +Funnel plot — mr_funnel_plot • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Create funnel plot from single SNP analyses.

    +
    + +
    +

    Usage

    +
    mr_funnel_plot(singlesnp_results)
    +
    + +
    +

    Arguments

    + + +
    singlesnp_results
    +

    from mr_singlesnp().

    + +
    +
    +

    Value

    +

    List of plots

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_heterogeneity.html b/docs/reference/mr_heterogeneity.html new file mode 100644 index 00000000..59808257 --- /dev/null +++ b/docs/reference/mr_heterogeneity.html @@ -0,0 +1,104 @@ + +Get heterogeneity statistics — mr_heterogeneity • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Get heterogeneity statistics.

    +
    + +
    +

    Usage

    +
    mr_heterogeneity(
    +  dat,
    +  parameters = default_parameters(),
    +  method_list = subset(mr_method_list(), heterogeneity_test & use_by_default)$obj
    +)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Harmonised exposure and outcome data. Output from harmonise_data().

    + + +
    parameters
    +

    Parameters to be used for various MR methods. Default is output from default_parameters().

    + + +
    method_list
    +

    List of methods to use in analysis. See mr_method_list() for details.

    + +
    +
    +

    Value

    +

    Data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_ivw.html b/docs/reference/mr_ivw.html new file mode 100644 index 00000000..8092d4e1 --- /dev/null +++ b/docs/reference/mr_ivw.html @@ -0,0 +1,126 @@ + +Inverse variance weighted regression — mr_ivw • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    The default multiplicative random effects IVW estimate. +The standard error is corrected for under dispersion +Use the mr_ivw_mre() function for estimates that don't correct for under dispersion.

    +
    + +
    +

    Usage

    +
    mr_ivw(b_exp, b_out, se_exp, se_out, parameters = default_parameters())
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure.

    + + +
    b_out
    +

    Vector of genetic effects on outcome.

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure.

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome.

    + + +
    parameters
    +

    List of parameters.

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    MR estimate

    + +
    se
    +

    Standard error

    + +
    pval
    +

    p-value

    + +
    Q, Q_df, Q_pval
    +

    Heterogeneity stats

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_ivw_fe.html b/docs/reference/mr_ivw_fe.html new file mode 100644 index 00000000..b947ceee --- /dev/null +++ b/docs/reference/mr_ivw_fe.html @@ -0,0 +1,120 @@ + +Inverse variance weighted regression (fixed effects) — mr_ivw_fe • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Inverse variance weighted regression (fixed effects)

    +
    + +
    +

    Usage

    +
    mr_ivw_fe(b_exp, b_out, se_exp, se_out, parameters = default_parameters())
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure.

    + + +
    b_out
    +

    Vector of genetic effects on outcome.

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure.

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome.

    + + +
    parameters
    +

    List of parameters.

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    MR estimate

    + +
    se
    +

    Standard error

    + +
    pval
    +

    p-value

    + +
    Q, Q_df, Q_pval
    +

    Heterogeneity stats

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_ivw_mre.html b/docs/reference/mr_ivw_mre.html new file mode 100644 index 00000000..3cd22fc4 --- /dev/null +++ b/docs/reference/mr_ivw_mre.html @@ -0,0 +1,120 @@ + +Inverse variance weighted regression (multiplicative random effects model) — mr_ivw_mre • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Same as mr_ivw() but no correction for under dispersion.

    +
    + +
    +

    Usage

    +
    mr_ivw_mre(b_exp, b_out, se_exp, se_out, parameters = default_parameters())
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure.

    + + +
    b_out
    +

    Vector of genetic effects on outcome.

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure.

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome.

    + + +
    parameters
    +

    List of parameters.

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    MR estimate

    + +
    se
    +

    Standard error

    + +
    pval
    +

    p-value

    + +
    Q, Q_df, Q_pval
    +

    Heterogeneity stats

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_ivw_radial.html b/docs/reference/mr_ivw_radial.html new file mode 100644 index 00000000..b7c39254 --- /dev/null +++ b/docs/reference/mr_ivw_radial.html @@ -0,0 +1,117 @@ + +Radial IVW analysis — mr_ivw_radial • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Radial IVW analysis

    +
    + +
    +

    Usage

    +
    mr_ivw_radial(b_exp, b_out, se_exp, se_out, parameters = default_parameters())
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure.

    + + +
    b_out
    +

    Vector of genetic effects on outcome.

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure.

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome.

    + + +
    parameters
    +

    List of parameters.

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    causal effect estimate

    + +
    se
    +

    standard error

    + +
    pval
    +

    p-value

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_leaveoneout.html b/docs/reference/mr_leaveoneout.html new file mode 100644 index 00000000..5dd52f3e --- /dev/null +++ b/docs/reference/mr_leaveoneout.html @@ -0,0 +1,100 @@ + +Leave one out sensitivity analysis — mr_leaveoneout • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Leave one out sensitivity analysis

    +
    + +
    +

    Usage

    +
    mr_leaveoneout(dat, parameters = default_parameters(), method = mr_ivw)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from harmonise_data().

    + + +
    parameters
    +

    List of parameters.

    + + +
    method
    +

    Choose which method to use. The default is mr_ivw.

    + +
    +
    +

    Value

    +

    List of data frames

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_leaveoneout_plot.html b/docs/reference/mr_leaveoneout_plot.html new file mode 100644 index 00000000..73097b26 --- /dev/null +++ b/docs/reference/mr_leaveoneout_plot.html @@ -0,0 +1,92 @@ + +Plot results from leaveoneout analysis — mr_leaveoneout_plot • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Plot results from leaveoneout analysis.

    +
    + +
    +

    Usage

    +
    mr_leaveoneout_plot(leaveoneout_results)
    +
    + +
    +

    Arguments

    + + +
    leaveoneout_results
    +

    Output from mr_leaveoneout().

    + +
    +
    +

    Value

    +

    List of plots

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_median.html b/docs/reference/mr_median.html new file mode 100644 index 00000000..6397935c --- /dev/null +++ b/docs/reference/mr_median.html @@ -0,0 +1,96 @@ + +MR median estimators — mr_median • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    MR median estimators

    +
    + +
    +

    Usage

    +
    mr_median(dat, parameters = default_parameters())
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from harmonise_data().

    + + +
    parameters
    +

    List of parameters. The default is default_parameters().

    + +
    +
    +

    Value

    +

    data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_meta_fixed.html b/docs/reference/mr_meta_fixed.html new file mode 100644 index 00000000..1dc97f53 --- /dev/null +++ b/docs/reference/mr_meta_fixed.html @@ -0,0 +1,120 @@ + +Perform 2 sample IV using fixed effects meta analysis and delta method for standard errors — mr_meta_fixed • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Perform 2 sample IV using fixed effects meta analysis and delta method for standard errors

    +
    + +
    +

    Usage

    +
    mr_meta_fixed(b_exp, b_out, se_exp, se_out, parameters)
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure.

    + + +
    b_out
    +

    Vector of genetic effects on outcome.

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure.

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome.

    + + +
    parameters
    +

    List of parameters.

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    causal effect estimate

    + +
    se
    +

    standard error

    + +
    pval
    +

    p-value

    + +
    Q, Q_df, Q_pval
    +

    Heterogeneity stats

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_meta_fixed_simple.html b/docs/reference/mr_meta_fixed_simple.html new file mode 100644 index 00000000..cbb5e2ef --- /dev/null +++ b/docs/reference/mr_meta_fixed_simple.html @@ -0,0 +1,117 @@ + +Perform 2 sample IV using simple standard error — mr_meta_fixed_simple • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Perform 2 sample IV using simple standard error

    +
    + +
    +

    Usage

    +
    mr_meta_fixed_simple(b_exp, b_out, se_exp, se_out, parameters)
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure.

    + + +
    b_out
    +

    Vector of genetic effects on outcome.

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure.

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome.

    + + +
    parameters
    +

    List of parameters.

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    causal effect estimate

    + +
    se
    +

    standard error

    + +
    pval
    +

    p-value

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_meta_random.html b/docs/reference/mr_meta_random.html new file mode 100644 index 00000000..8a5c50b2 --- /dev/null +++ b/docs/reference/mr_meta_random.html @@ -0,0 +1,120 @@ + +Perform 2 sample IV using random effects meta analysis and delta method for standard errors — mr_meta_random • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Perform 2 sample IV using random effects meta analysis and delta method for standard errors

    +
    + +
    +

    Usage

    +
    mr_meta_random(b_exp, b_out, se_exp, se_out, parameters)
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure.

    + + +
    b_out
    +

    Vector of genetic effects on outcome.

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure.

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome.

    + + +
    parameters
    +

    List of parameters.

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    causal effect estimate

    + +
    se
    +

    standard error

    + +
    pval
    +

    p-value

    + +
    Q, Q_df, Q_pval
    +

    Heterogeneity stats

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_method_list.html b/docs/reference/mr_method_list.html new file mode 100644 index 00000000..13522b84 --- /dev/null +++ b/docs/reference/mr_method_list.html @@ -0,0 +1,84 @@ + +Get list of available MR methods — mr_method_list • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Get list of available MR methods

    +
    + +
    +

    Usage

    +
    mr_method_list()
    +
    + +
    +

    Value

    +

    character vector of method names

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_mode.html b/docs/reference/mr_mode.html new file mode 100644 index 00000000..728467df --- /dev/null +++ b/docs/reference/mr_mode.html @@ -0,0 +1,100 @@ + +MR mode estimators — mr_mode • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Perform simple, weighted, penalised modes, as well as versions that use the NOME assumption.

    +
    + +
    +

    Usage

    +
    mr_mode(dat, parameters = default_parameters(), mode_method = "all")
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from harmonise_data().

    + + +
    parameters
    +

    List of parameters. The default is default_parameters().

    + + +
    mode_method
    +

    The default is "all". The other choices are 'Simple mode', 'Weighted mode', 'Penalised mode', 'Simple mode (NOME)', 'Weighted mode (NOME)'.

    + +
    +
    +

    Value

    +

    data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_moe.html b/docs/reference/mr_moe.html new file mode 100644 index 00000000..bcf0d221 --- /dev/null +++ b/docs/reference/mr_moe.html @@ -0,0 +1,130 @@ + +Mixture of experts — mr_moe • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Based on the method described here https://www.biorxiv.org/content/10.1101/173682v2. +Once all MR methods have been applied to a summary set, you can then use the mixture of experts to predict the method most likely to be the most accurate.

    +
    + +
    +

    Usage

    +
    mr_moe(res, rf)
    +
    + +
    +

    Arguments

    + + +
    res
    +

    Output from mr_wrapper().

    + + +
    rf
    +

    The trained random forest for the methods. This is available to download at https://www.dropbox.com/s/5la7y38od95swcf/rf.rdata?dl=0.

    + +
    +
    +

    Value

    +

    List

    +
    +
    +

    Details

    +

    The mr_moe() function modifies the estimates item in the list of results from the mr_wrapper() function. It does three things:

    1. Adds the MOE column, which is a predictor for each method for how well it performs in terms of high power and low type 1 error (scaled 0-1, where 1 is best performance).

    2. +
    3. It renames the methods to be the estimating method + the instrument selection method. There are 4 instrument selection methods: Tophits (i.e. no filtering), directional filtering (DF, an unthresholded version of Steiger filtering), heterogeneity filtering (HF, removing instruments that make substantial (p < 0.05) contributions to Cochran's Q statistic), and DF + HF which is where DF is applied and the HF applied on top of that.

    4. +
    5. It orders the table to be in order of best performing method.

    6. +

    Note that the mixture of experts has only been trained on datasets with at least 5 SNPs. If your dataset has fewer than 5 SNPs this function might return errors.

    +
    + +
    +

    Examples

    +
    if (FALSE) { # \dontrun{
    +# Example of body mass index on coronary heart disease
    +# Extract and harmonise data
    +a <- extract_instruments("ieu-a-2")
    +b <- extract_outcome_data(a$SNP, 7)
    +dat <- harmonise_data(a, b)
    +
    +# Apply all MR methods
    +r <- mr_wrapper(dat)
    +
    +# Load the rf object containing the trained models
    +load("rf.rdata")
    +# Update the results with mixture of experts
    +r <- mr_moe(r, rf)
    +
    +# Now you can view the estimates, and see that they have
    +# been sorted in order from most likely to least likely to
    +# be accurate, based on MOE prediction
    +r[[1]]$estimates
    +} # }
    +
    +
    +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_penalised_weighted_median.html b/docs/reference/mr_penalised_weighted_median.html new file mode 100644 index 00000000..fb0659b7 --- /dev/null +++ b/docs/reference/mr_penalised_weighted_median.html @@ -0,0 +1,126 @@ + +Penalised weighted median MR — mr_penalised_weighted_median • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Modification to standard weighted median MR +Updated based on Burgess 2016 "Robust instrumental variable methods using multiple candidate instruments with application to Mendelian randomization"

    +
    + +
    +

    Usage

    +
    mr_penalised_weighted_median(
    +  b_exp,
    +  b_out,
    +  se_exp,
    +  se_out,
    +  parameters = default_parameters()
    +)
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure

    + + +
    b_out
    +

    Vector of genetic effects on outcome

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome

    + + +
    parameters
    +

    List containing penk - Constant term in penalisation, and nboot - number of bootstrap replications to calculate SE. default_parameters() sets parameters=list(penk=20, nboot=1000).

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    MR estimate

    + +
    se
    +

    Standard error

    + +
    pval
    +

    p-value

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_pleiotropy_test.html b/docs/reference/mr_pleiotropy_test.html new file mode 100644 index 00000000..cc0906e5 --- /dev/null +++ b/docs/reference/mr_pleiotropy_test.html @@ -0,0 +1,92 @@ + +Test for horizontal pleiotropy in MR analysis — mr_pleiotropy_test • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Performs MR Egger and returns intercept values.

    +
    + +
    +

    Usage

    +
    mr_pleiotropy_test(dat)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Harmonised exposure and outcome data. Output from harmonise_data().

    + +
    +
    +

    Value

    +

    data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_raps.html b/docs/reference/mr_raps.html new file mode 100644 index 00000000..218e4a8f --- /dev/null +++ b/docs/reference/mr_raps.html @@ -0,0 +1,131 @@ + +Robust adjusted profile score — mr_raps • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Robust adjusted profile score

    +
    + +
    +

    Usage

    +
    mr_raps(b_exp, b_out, se_exp, se_out, parameters = default_parameters())
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure.

    + + +
    b_out
    +

    Vector of genetic effects on outcome.

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure.

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome.

    + + +
    parameters
    +

    A list of parameters. Specifically, over.dispersion and loss.function. +over.dispersion is a logical concerning should the model consider overdispersion (systematic pleiotropy). +And loss.function allows using either the squared error loss ("l2") or robust loss functions/scores ("huber" or "tukey"). +The default is parameters=list(overdispersion = TRUE, loss.function = "tukey").

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    MR estimate

    + +
    se
    +

    Standard error

    + +
    pval
    +

    p-value

    + +
    nsnp
    +

    Number of SNPs

    + + +
    +
    +

    Details

    +

    This function calls the mr.raps package. Please refer to the documentation of that package for more detail.

    +
    +
    +

    References

    +

    Qingyuan Zhao, Jingshu Wang, Jack Bowden, Dylan S. Small. Statistical inference in two-sample summary-data Mendelian randomization using robust adjusted profile score. Forthcoming.

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_report.html b/docs/reference/mr_report.html new file mode 100644 index 00000000..8a5eed8f --- /dev/null +++ b/docs/reference/mr_report.html @@ -0,0 +1,125 @@ + +Generate MR report — mr_report • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Using the output from the mr() function this report will generate a report containing tables and graphs summarising the results. +A separate report is produced for each exposure - outcome pair that was analysed.

    +
    + +
    +

    Usage

    +
    mr_report(
    +  dat,
    +  output_path = ".",
    +  output_type = "html",
    +  author = "Analyst",
    +  study = "Two Sample MR",
    +  path = system.file("reports", package = "TwoSampleMR"),
    +  ...
    +)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from harmonise_data()

    + + +
    output_path
    +

    Directory in which reports should be saved.

    + + +
    output_type
    +

    Choose "html" or "md". Default is "html". +All output files including cache and figures will appear in the +folder specified in output_path.

    + + +
    author
    +

    Author name.

    + + +
    study
    +

    Study title.

    + + +
    path
    +

    The filepath to the report template.

    + + +
    ...
    +

    Extra options to be passed to knitr::knit().

    + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_rucker.html b/docs/reference/mr_rucker.html new file mode 100644 index 00000000..4ee65676 --- /dev/null +++ b/docs/reference/mr_rucker.html @@ -0,0 +1,96 @@ + +MR Rucker framework — mr_rucker • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    MR Rucker framework.

    +
    + +
    +

    Usage

    +
    mr_rucker(dat, parameters = default_parameters())
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from harmonise_data().

    + + +
    parameters
    +

    List of Qthresh for determining transition between models, and alpha values for calculating confidence intervals. Defaults to 0.05 for both in default_parameters().

    + +
    +
    +

    Value

    +

    list

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_rucker_bootstrap.html b/docs/reference/mr_rucker_bootstrap.html new file mode 100644 index 00000000..f3a77637 --- /dev/null +++ b/docs/reference/mr_rucker_bootstrap.html @@ -0,0 +1,96 @@ + +Run rucker with bootstrap estimates — mr_rucker_bootstrap • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Run Rucker with bootstrap estimates.

    +
    + +
    +

    Usage

    +
    mr_rucker_bootstrap(dat, parameters = default_parameters())
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from harmonise_data().

    + + +
    parameters
    +

    List of parameters. The default is default_parameters().

    + +
    +
    +

    Value

    +

    List

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_rucker_cooksdistance.html b/docs/reference/mr_rucker_cooksdistance.html new file mode 100644 index 00000000..8afd754a --- /dev/null +++ b/docs/reference/mr_rucker_cooksdistance.html @@ -0,0 +1,96 @@ + +MR Rucker with outliers automatically detected and removed — mr_rucker_cooksdistance • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Uses Cook's distance D > 4/nsnp to iteratively remove outliers.

    +
    + +
    +

    Usage

    +
    mr_rucker_cooksdistance(dat, parameters = default_parameters())
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from harmonise_data().

    + + +
    parameters
    +

    List of parameters. The default is default_parameters().

    + +
    +
    +

    Value

    +

    List

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_rucker_jackknife.html b/docs/reference/mr_rucker_jackknife.html new file mode 100644 index 00000000..6b7455c9 --- /dev/null +++ b/docs/reference/mr_rucker_jackknife.html @@ -0,0 +1,96 @@ + +Run rucker with jackknife estimates — mr_rucker_jackknife • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Run rucker with jackknife estimates.

    +
    + +
    +

    Usage

    +
    mr_rucker_jackknife(dat, parameters = default_parameters())
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from harmonise_data.

    + + +
    parameters
    +

    List of parameters. The default is default_parameters().

    + +
    +
    +

    Value

    +

    List

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_scatter_plot.html b/docs/reference/mr_scatter_plot.html new file mode 100644 index 00000000..b9d88e1f --- /dev/null +++ b/docs/reference/mr_scatter_plot.html @@ -0,0 +1,96 @@ + +Create scatter plot with lines showing the causal estimate for different MR tests — mr_scatter_plot • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Requires dev version of ggplot2

    +
    + +
    +

    Usage

    +
    mr_scatter_plot(mr_results, dat)
    +
    + +
    +

    Arguments

    + + +
    mr_results
    +

    Output from mr().

    + + +
    dat
    +

    Output from harmonise_data().

    + +
    +
    +

    Value

    +

    List of plots

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_sign.html b/docs/reference/mr_sign.html new file mode 100644 index 00000000..8febf6af --- /dev/null +++ b/docs/reference/mr_sign.html @@ -0,0 +1,132 @@ + +MR sign test — mr_sign • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Tests how often the SNP-exposure and SNP-outcome signs are concordant. +This is to avoid the problem of averaging over all SNPs, which can suffer bias due to outliers with strong effects; and to avoid excluding SNPs which is implicit in median and mode based estimators. +The effect estimate here is not to be interpreted as the effect size - it is the proportion of SNP-exposure and SNP-outcome effects that have concordant signs. +e.g. +1 means all have the same sign, -1 means all have opposite signs, and 0 means that there is an equal number of concordant and discordant signs. +Restricted to only work if there are 6 or more valid SNPs.

    +
    + +
    +

    Usage

    +
    mr_sign(b_exp, b_out, se_exp = NULL, se_out = NULL, parameters = NULL)
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure

    + + +
    b_out
    +

    Vector of genetic effects on outcome

    + + +
    se_exp
    +

    Not required

    + + +
    se_out
    +

    Not required

    + + +
    parameters
    +

    Not required

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    Concordance (see description)

    + +
    se
    +

    NA

    + +
    pval
    +

    p-value

    + +
    nsnp
    +

    Number of SNPs (excludes NAs and effect estimates that are 0)

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_simple_median.html b/docs/reference/mr_simple_median.html new file mode 100644 index 00000000..78fb6e1c --- /dev/null +++ b/docs/reference/mr_simple_median.html @@ -0,0 +1,126 @@ + +Simple median method — mr_simple_median • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Perform MR using summary statistics. Bootstraps used to calculate standard error.

    +
    + +
    +

    Usage

    +
    mr_simple_median(
    +  b_exp,
    +  b_out,
    +  se_exp,
    +  se_out,
    +  parameters = default_parameters()
    +)
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure.

    + + +
    b_out
    +

    Vector of genetic effects on outcome.

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure.

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome.

    + + +
    parameters
    +

    The number of bootstrap replications used to calculate the SE can be set through parameters=list(nboot = 1000). The default is list(nboot=1000).

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    MR estimate

    + +
    se
    +

    Standard error

    + +
    pval
    +

    p-value

    + +
    nsnp
    +

    The number of SNPs

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_simple_mode.html b/docs/reference/mr_simple_mode.html new file mode 100644 index 00000000..1322d748 --- /dev/null +++ b/docs/reference/mr_simple_mode.html @@ -0,0 +1,117 @@ + +MR simple mode estimator — mr_simple_mode • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    MR simple mode estimator

    +
    + +
    +

    Usage

    +
    mr_simple_mode(b_exp, b_out, se_exp, se_out, parameters = default_parameters())
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure

    + + +
    b_out
    +

    Vector of genetic effects on outcome

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome

    + + +
    parameters
    +

    List containing phi - Bandwidth parameter, and nboot - number of bootstraps to calculate SE. default_parameters() sets list(phi=1, nboot=1000).

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    MR estimate

    + +
    se
    +

    Standard error

    + +
    pval
    +

    p-value

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_simple_mode_nome.html b/docs/reference/mr_simple_mode_nome.html new file mode 100644 index 00000000..7bec287c --- /dev/null +++ b/docs/reference/mr_simple_mode_nome.html @@ -0,0 +1,123 @@ + +MR simple mode estimator (NOME) — mr_simple_mode_nome • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    MR simple mode estimator (NOME).

    +
    + +
    +

    Usage

    +
    mr_simple_mode_nome(
    +  b_exp,
    +  b_out,
    +  se_exp,
    +  se_out,
    +  parameters = default_parameters()
    +)
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure

    + + +
    b_out
    +

    Vector of genetic effects on outcome

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome

    + + +
    parameters
    +

    List containing phi - Bandwidth parameter, and nboot - number of bootstraps to calculate SE. default_parameters() sets list(phi=1, nboot=1000).

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    MR estimate

    + +
    se
    +

    Standard error

    + +
    pval
    +

    p-value

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_singlesnp.html b/docs/reference/mr_singlesnp.html new file mode 100644 index 00000000..9877ec42 --- /dev/null +++ b/docs/reference/mr_singlesnp.html @@ -0,0 +1,109 @@ + +Perform 2 sample MR on each SNP individually — mr_singlesnp • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Perform 2 sample MR on each SNP individually

    +
    + +
    +

    Usage

    +
    mr_singlesnp(
    +  dat,
    +  parameters = default_parameters(),
    +  single_method = "mr_wald_ratio",
    +  all_method = c("mr_ivw", "mr_egger_regression")
    +)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from harmonise_data().

    + + +
    parameters
    +

    List of parameters. The default is default_parameters().

    + + +
    single_method
    +

    Function to use for MR analysis. The default is "mr_wald_ratio".

    + + +
    all_method
    +

    Functions to use for MR analysis. The default is c("mr_ivw", "mr_egger_regression").

    + +
    +
    +

    Value

    +

    List of data frames

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_steiger.html b/docs/reference/mr_steiger.html new file mode 100644 index 00000000..cbe8f125 --- /dev/null +++ b/docs/reference/mr_steiger.html @@ -0,0 +1,163 @@ + +MR Steiger test of directionality — mr_steiger • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    A statistical test for whether the assumption that exposure causes outcome is valid

    +
    + +
    +

    Usage

    +
    mr_steiger(p_exp, p_out, n_exp, n_out, r_exp, r_out, r_xxo = 1, r_yyo = 1, ...)
    +
    + +
    +

    Arguments

    + + +
    p_exp
    +

    Vector of p-values of SNP-exposure

    + + +
    p_out
    +

    Vector of p-values of SNP-outcome

    + + +
    n_exp
    +

    Sample sizes for p_exp

    + + +
    n_out
    +

    Sample sizes for p_out

    + + +
    r_exp
    +

    Vector of absolute correlations for SNP-exposure

    + + +
    r_out
    +

    Vector of absolute correlations for SNP-outcome

    + + +
    r_xxo
    +

    Measurememt precision of exposure

    + + +
    r_yyo
    +

    Measurement precision of outcome

    + + +
    ...
    +

    Further arguments to be passed to lattice::wireframe()

    + +
    +
    +

    Value

    +

    List with the following elements:

    r2_exp
    +

    Estimated variance explained in x

    + +
    r2_out
    +

    Estimated variance explained in y

    + +
    r2_exp_adj
    +

    Predicted variance explained in x accounting for estimated measurement error

    + +
    r2_out_adj
    +

    Predicted variance explained in y accounting for estimated measurement error

    + +
    correct_causal_direction
    +

    TRUE/FALSE

    + +
    steiger_test
    +

    p-value for inference of direction

    + +
    correct_causal_direction_adj
    +

    TRUE/FALSE, direction of causality for given measurement error parameters

    + +
    steiger_test_adj
    +

    p-value for inference of direction of causality for given measurement error parameters

    + +
    vz
    +

    Total volume of the error parameter space

    + +
    vz0
    +

    Volume of the parameter space that gives the incorrect answer

    + +
    vz1
    +

    Volume of the paramtere space that gives the correct answer

    + +
    sensitivity_ratio
    +

    Ratio of vz1/vz0. Higher means inferred direction is less susceptible to measurement error

    + +
    sensitivity_plot
    +

    Plot of parameter space of causal directions and measurement error

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_steiger2.html b/docs/reference/mr_steiger2.html new file mode 100644 index 00000000..eba2ad2d --- /dev/null +++ b/docs/reference/mr_steiger2.html @@ -0,0 +1,155 @@ + +MR Steiger test of directionality — mr_steiger2 • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    A statistical test for whether the assumption that exposure causes outcome is valid

    +
    + +
    +

    Usage

    +
    mr_steiger2(r_exp, r_out, n_exp, n_out, r_xxo = 1, r_yyo = 1, ...)
    +
    + +
    +

    Arguments

    + + +
    r_exp
    +

    Vector of correlations of SNP-exposure

    + + +
    r_out
    +

    Vector of correlations of SNP-outcome

    + + +
    n_exp
    +

    Sample sizes for p_exp

    + + +
    n_out
    +

    Sample sizes for p_out

    + + +
    r_xxo
    +

    Measurememt precision of exposure

    + + +
    r_yyo
    +

    Measurement precision of outcome

    + + +
    ...
    +

    Further arguments to be passed to lattice::wireframe()

    + +
    +
    +

    Value

    +

    List with the following elements:

    r2_exp
    +

    Estimated variance explained in x

    + +
    r2_out
    +

    Estimated variance explained in y

    + +
    r2_exp_adj
    +

    Predicted variance explained in x accounting for estimated measurement error

    + +
    r2_out_adj
    +

    Predicted variance explained in y accounting for estimated measurement error

    + +
    correct_causal_direction
    +

    TRUE/FALSE

    + +
    steiger_test
    +

    p-value for inference of direction

    + +
    correct_causal_direction_adj
    +

    TRUE/FALSE, direction of causality for given measurement error parameters

    + +
    steiger_test_adj
    +

    p-value for inference of direction of causality for given measurement error parameters

    + +
    vz
    +

    Total volume of the error parameter space

    + +
    vz0
    +

    Volume of the parameter space that gives the incorrect answer

    + +
    vz1
    +

    Volume of the paramtere space that gives the correct answer

    + +
    sensitivity_ratio
    +

    Ratio of vz1/vz0. Higher means inferred direction is less susceptible to measurement error

    + +
    sensitivity_plot
    +

    Plot of parameter space of causal directions and measurement error

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_two_sample_ml.html b/docs/reference/mr_two_sample_ml.html new file mode 100644 index 00000000..b7be4100 --- /dev/null +++ b/docs/reference/mr_two_sample_ml.html @@ -0,0 +1,120 @@ + +Maximum likelihood MR method — mr_two_sample_ml • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Maximum likelihood MR method

    +
    + +
    +

    Usage

    +
    mr_two_sample_ml(b_exp, b_out, se_exp, se_out, parameters)
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure.

    + + +
    b_out
    +

    Vector of genetic effects on outcome.

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure.

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome.

    + + +
    parameters
    +

    List of parameters.

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    causal effect estimate

    + +
    se
    +

    standard error

    + +
    pval
    +

    p-value

    + +
    Q, Q_df, Q_pval
    +

    Heterogeneity stats

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_uwr.html b/docs/reference/mr_uwr.html new file mode 100644 index 00000000..7317b198 --- /dev/null +++ b/docs/reference/mr_uwr.html @@ -0,0 +1,126 @@ + +Unweighted regression — mr_uwr • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    The default multiplicative random effects IVW estimate. +The standard error is corrected for under dispersion +Use the mr_ivw_mre() function for estimates that don't correct for under dispersion.

    +
    + +
    +

    Usage

    +
    mr_uwr(b_exp, b_out, se_exp, se_out, parameters = default_parameters())
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure.

    + + +
    b_out
    +

    Vector of genetic effects on outcome.

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure.

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome.

    + + +
    parameters
    +

    List of parameters. The default is default_parameters().

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    MR estimate

    + +
    se
    +

    Standard error

    + +
    pval
    +

    p-value

    + +
    Q, Q_df, Q_pval
    +

    Heterogeneity stats

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_wald_ratio.html b/docs/reference/mr_wald_ratio.html new file mode 100644 index 00000000..42d7091a --- /dev/null +++ b/docs/reference/mr_wald_ratio.html @@ -0,0 +1,120 @@ + +Perform 2 sample IV using Wald ratio. — mr_wald_ratio • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Perform 2 sample IV using Wald ratio.

    +
    + +
    +

    Usage

    +
    mr_wald_ratio(b_exp, b_out, se_exp, se_out, parameters)
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure.

    + + +
    b_out
    +

    Vector of genetic effects on outcome.

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure.

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome.

    + + +
    parameters
    +

    List of parameters.

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    causal effect estimate

    + +
    se
    +

    standard error

    + +
    pval
    +

    p-value

    + +
    nsnp
    +

    1

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_weighted_median.html b/docs/reference/mr_weighted_median.html new file mode 100644 index 00000000..c0bc7bf7 --- /dev/null +++ b/docs/reference/mr_weighted_median.html @@ -0,0 +1,123 @@ + +Weighted median method — mr_weighted_median • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Perform MR using summary statistics. Bootstraps used to calculate standard error.

    +
    + +
    +

    Usage

    +
    mr_weighted_median(
    +  b_exp,
    +  b_out,
    +  se_exp,
    +  se_out,
    +  parameters = default_parameters()
    +)
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure.

    + + +
    b_out
    +

    Vector of genetic effects on outcome.

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure.

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome.

    + + +
    parameters
    +

    The default is default_parameters(). Specify the number of bootstrap replications to calculate the SE with nboot. The default is list(nboot=1000).

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    MR estimate

    + +
    se
    +

    Standard error

    + +
    pval
    +

    p-value

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_weighted_mode.html b/docs/reference/mr_weighted_mode.html new file mode 100644 index 00000000..5ecb94f0 --- /dev/null +++ b/docs/reference/mr_weighted_mode.html @@ -0,0 +1,123 @@ + +MR weighted mode estimator — mr_weighted_mode • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    MR weighted mode estimator

    +
    + +
    +

    Usage

    +
    mr_weighted_mode(
    +  b_exp,
    +  b_out,
    +  se_exp,
    +  se_out,
    +  parameters = default_parameters()
    +)
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure

    + + +
    b_out
    +

    Vector of genetic effects on outcome

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome

    + + +
    parameters
    +

    List containing phi - Bandwidth parameter, and nboot - number of bootstraps to calculate SE. default_parameters() sets list(phi=1, nboot=1000).

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    MR estimate

    + +
    se
    +

    Standard error

    + +
    pval
    +

    p-value

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_weighted_mode_nome.html b/docs/reference/mr_weighted_mode_nome.html new file mode 100644 index 00000000..31ca4d96 --- /dev/null +++ b/docs/reference/mr_weighted_mode_nome.html @@ -0,0 +1,123 @@ + +MR weighted mode estimator (NOME) — mr_weighted_mode_nome • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Weighted mode estimator

    +
    + +
    +

    Usage

    +
    mr_weighted_mode_nome(
    +  b_exp,
    +  b_out,
    +  se_exp,
    +  se_out,
    +  parameters = default_parameters()
    +)
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure

    + + +
    b_out
    +

    Vector of genetic effects on outcome

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome

    + + +
    parameters
    +

    List containing phi - Bandwidth parameter, and nboot - number of bootstraps to calculate SE. default_parameters() sets list(phi=1, nboot=1000).

    + +
    +
    +

    Value

    +

    List with the following elements:

    b
    +

    MR estimate

    + +
    se
    +

    Standard error

    + +
    pval
    +

    p-value

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mr_wrapper.html b/docs/reference/mr_wrapper.html new file mode 100644 index 00000000..dc4dc030 --- /dev/null +++ b/docs/reference/mr_wrapper.html @@ -0,0 +1,96 @@ + +Perform full set of MR analyses — mr_wrapper • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Perform full set of MR analyses

    +
    + +
    +

    Usage

    +
    mr_wrapper(dat, parameters = default_parameters())
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from harmonise_data().

    + + +
    parameters
    +

    Parameters to pass to MR functions. Output from default_parameters() used as default.

    + +
    +
    +

    Value

    +

    list

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mv_basic.html b/docs/reference/mv_basic.html new file mode 100644 index 00000000..76837a9b --- /dev/null +++ b/docs/reference/mv_basic.html @@ -0,0 +1,99 @@ + +Perform basic multivariable MR — mv_basic • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Performs initial multivariable MR analysis from Burgess et al 2015. +For each exposure the outcome is residualised for all the other exposures, then unweighted regression is applied.

    +
    + +
    +

    Usage

    +
    mv_basic(mvdat, pval_threshold = 5e-08)
    +
    + +
    +

    Arguments

    + + +
    mvdat
    +

    Output from mv_harmonise_data().

    + + +
    pval_threshold
    +

    P-value threshold to include instruments. The default is 5e-8.

    + +
    +
    +

    Value

    +

    List of results

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mv_extract_exposures.html b/docs/reference/mv_extract_exposures.html new file mode 100644 index 00000000..81825176 --- /dev/null +++ b/docs/reference/mv_extract_exposures.html @@ -0,0 +1,144 @@ + +Extract exposure variables for multivariable MR — mv_extract_exposures • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Requires a list of IDs from available_outcomes. For each ID, it extracts instruments. Then, it gets the full list of all instruments and extracts those SNPs for every exposure. Finally, it keeps only the SNPs that are a) independent and b) present in all exposures, and harmonises them to be all on the same strand.

    +
    + +
    +

    Usage

    +
    mv_extract_exposures(
    +  id_exposure,
    +  clump_r2 = 0.001,
    +  clump_kb = 10000,
    +  harmonise_strictness = 2,
    +  opengwas_jwt = ieugwasr::get_opengwas_jwt(),
    +  find_proxies = TRUE,
    +  force_server = FALSE,
    +  pval_threshold = 5e-08,
    +  pop = "EUR",
    +  plink_bin = NULL,
    +  bfile = NULL
    +)
    +
    + +
    +

    Arguments

    + + +
    id_exposure
    +

    Array of IDs (e.g. c(299, 300, 302) for HDL, LDL, trigs)

    + + +
    clump_r2
    +

    The default is 0.01.

    + + +
    clump_kb
    +

    The default is 10000.

    + + +
    harmonise_strictness
    +

    See the action option of harmonise_data(). The default is 2.

    + + +
    opengwas_jwt
    +

    Used to authenticate protected endpoints. Login to https://api.opengwas.io to obtain a jwt. Provide the jwt string here, or store in .Renviron under the keyname OPENGWAS_JWT.

    + + +
    find_proxies
    +

    Look for proxies? This slows everything down but is more accurate. The default is TRUE.

    + + +
    force_server
    +

    Whether to search through pre-clumped dataset or to re-extract and clump directly from the server. The default is FALSE.

    + + +
    pval_threshold
    +

    Instrument detection p-value threshold. Default = 5e-8

    + + +
    pop
    +

    Which 1000 genomes super population to use for clumping when using the server

    + + + +

    If NULL and bfile is not NULL then will detect packaged plink binary for specific OS. Otherwise specify path to plink binary. Default = NULL

    + + +
    bfile
    +

    If this is provided then will use the API. Default = NULL

    + +
    +
    +

    Value

    +

    data frame in exposure_dat format

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mv_extract_exposures_local.html b/docs/reference/mv_extract_exposures_local.html new file mode 100644 index 00000000..0a06bce7 --- /dev/null +++ b/docs/reference/mv_extract_exposures_local.html @@ -0,0 +1,218 @@ + +Attempt to perform MVMR using local data — mv_extract_exposures_local • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Allows you to read in summary data from text files to format the multivariable exposure dataset.

    +
    + +
    +

    Usage

    +
    mv_extract_exposures_local(
    +  filenames_exposure,
    +  sep = " ",
    +  phenotype_col = "Phenotype",
    +  snp_col = "SNP",
    +  beta_col = "beta",
    +  se_col = "se",
    +  eaf_col = "eaf",
    +  effect_allele_col = "effect_allele",
    +  other_allele_col = "other_allele",
    +  pval_col = "pval",
    +  units_col = "units",
    +  ncase_col = "ncase",
    +  ncontrol_col = "ncontrol",
    +  samplesize_col = "samplesize",
    +  gene_col = "gene",
    +  id_col = "id",
    +  min_pval = 1e-200,
    +  log_pval = FALSE,
    +  pval_threshold = 5e-08,
    +  plink_bin = NULL,
    +  bfile = NULL,
    +  clump_r2 = 0.001,
    +  clump_kb = 10000,
    +  pop = "EUR",
    +  harmonise_strictness = 2
    +)
    +
    + +
    +

    Arguments

    + + +
    filenames_exposure
    +

    Filenames for each exposure dataset. Must have header with at least SNP column present. Following arguments are used for determining how to read the filename and clumping etc.

    + + +
    sep
    +

    Specify delimeter in file. The default is space, i.e. sep=" ". If length is 1 it will use the same sep value for each exposure dataset. You can provide a vector of values, one for each exposure dataset, if the values are different across datasets. The same applies to all dataset-formatting options listed below.

    + + +
    phenotype_col
    +

    Optional column name for the column with phenotype name corresponding the the SNP. If not present then will be created with the value "Outcome". Default is "Phenotype".

    + + +
    snp_col
    +

    Required name of column with SNP rs IDs. The default is "SNP".

    + + +
    beta_col
    +

    Required for MR. Name of column with effect sizes. THe default is "beta".

    + + +
    se_col
    +

    Required for MR. Name of column with standard errors. The default is "se".

    + + +
    eaf_col
    +

    Required for MR. Name of column with effect allele frequency. The default is "eaf".

    + + +
    effect_allele_col
    +

    Required for MR. Name of column with effect allele. Must be "A", "C", "T" or "G". The default is "effect_allele".

    + + +
    other_allele_col
    +

    Required for MR. Name of column with non effect allele. Must be "A", "C", "T" or "G". The default is "other_allele".

    + + +
    pval_col
    +

    Required for enrichment tests. Name of column with p-value. The default is "pval".

    + + +
    units_col
    +

    Optional column name for units. The default is "units".

    + + +
    ncase_col
    +

    Optional column name for number of cases. The default is "ncase".

    + + +
    ncontrol_col
    +

    Optional column name for number of controls. The default is "ncontrol".

    + + +
    samplesize_col
    +

    Optional column name for sample size. The default is "samplesize".

    + + +
    gene_col
    +

    Optional column name for gene name. The default is "gene".

    + + +
    id_col
    +

    Optional column name to give the dataset an ID. Will be generated automatically if not provided for every trait / unit combination. The default is "id".

    + + +
    min_pval
    +

    Minimum allowed p-value. The default is 1e-200.

    + + +
    log_pval
    +

    The pval is -log10(P). The default is FALSE.

    + + +
    pval_threshold
    +

    Default=5e-8 for clumping

    + + + +

    If NULL and bfile is not NULL then will detect packaged plink binary for specific OS. Otherwise specify path to plink binary. Default = NULL

    + + +
    bfile
    +

    If this is provided then will use the API. Default = NULL

    + + +
    clump_r2
    +

    Default=0.001 for clumping

    + + +
    clump_kb
    +

    Default=10000 for clumping

    + + +
    pop
    +

    Which 1000 genomes super population to use for clumping when using the server

    + + +
    harmonise_strictness
    +

    See action argument in harmonise_data(). Default=2

    + +
    +
    +

    Value

    +

    List

    +
    +
    +

    Details

    +

    Note that you can provide an array of column names for each column, which is of length filenames_exposure

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mv_harmonise_data.html b/docs/reference/mv_harmonise_data.html new file mode 100644 index 00000000..62acabcd --- /dev/null +++ b/docs/reference/mv_harmonise_data.html @@ -0,0 +1,124 @@ + +Harmonise exposure and outcome for multivariable MR — mv_harmonise_data • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Harmonise exposure and outcome for multivariable MR

    +
    + +
    +

    Usage

    +
    mv_harmonise_data(exposure_dat, outcome_dat, harmonise_strictness = 2)
    +
    + +
    +

    Arguments

    + + +
    exposure_dat
    +

    Output from mv_extract_exposures().

    + + +
    outcome_dat
    +

    Output from extract_outcome_data(exposure_dat$SNP, id_output).

    + + +
    harmonise_strictness
    +

    See the action option of harmonise_data(). The default is 2.

    + +
    +
    +

    Value

    +

    List of vectors and matrices required for mv analysis.

    exposure_beta
    +

    a matrix of beta coefficients, in which rows correspond to SNPs and columns correspond to exposures.

    + +
    exposure_se
    +

    is the same as exposure_beta, but for standard errors.

    + +
    exposure_pval
    +

    the same as exposure_beta, but for p-values.

    + +
    expname
    +

    A data frame with two variables, id.exposure and exposure which are character strings.

    + +
    outcome_beta
    +

    an array of effects for the outcome, corresponding to the SNPs in exposure_beta.

    + +
    outcome_se
    +

    an array of standard errors for the outcome.

    + +
    outcome_pval
    +

    an array of p-values for the outcome.

    + +
    outname
    +

    A data frame with two variables, id.outcome and outcome which are character strings.

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mv_ivw.html b/docs/reference/mv_ivw.html new file mode 100644 index 00000000..59588077 --- /dev/null +++ b/docs/reference/mv_ivw.html @@ -0,0 +1,99 @@ + +Perform IVW multivariable MR — mv_ivw • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Performs modified multivariable MR analysis. +For each exposure the instruments are selected then all exposures for those SNPs are regressed against the outcome together, weighting for the inverse variance of the outcome.

    +
    + +
    +

    Usage

    +
    mv_ivw(mvdat, pval_threshold = 5e-08)
    +
    + +
    +

    Arguments

    + + +
    mvdat
    +

    Output from mv_harmonise_data().

    + + +
    pval_threshold
    +

    P-value threshold to include instruments. The default is 5e-8.

    + +
    +
    +

    Value

    +

    List of results

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mv_lasso_feature_selection.html b/docs/reference/mv_lasso_feature_selection.html new file mode 100644 index 00000000..18808046 --- /dev/null +++ b/docs/reference/mv_lasso_feature_selection.html @@ -0,0 +1,92 @@ + +Apply LASSO feature selection to mvdat object — mv_lasso_feature_selection • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Apply LASSO feature selection to mvdat object

    +
    + +
    +

    Usage

    +
    mv_lasso_feature_selection(mvdat)
    +
    + +
    +

    Arguments

    + + +
    mvdat
    +

    Output from mv_harmonise_data().

    + +
    +
    +

    Value

    +

    data frame of retained features

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mv_multiple.html b/docs/reference/mv_multiple.html new file mode 100644 index 00000000..40e73d27 --- /dev/null +++ b/docs/reference/mv_multiple.html @@ -0,0 +1,117 @@ + +Perform IVW multivariable MR — mv_multiple • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Performs modified multivariable MR analysis. +For each exposure the instruments are selected then all exposures for those SNPs are regressed against the outcome together, weighting for the inverse variance of the outcome.

    +
    + +
    +

    Usage

    +
    mv_multiple(
    +  mvdat,
    +  intercept = FALSE,
    +  instrument_specific = FALSE,
    +  pval_threshold = 5e-08,
    +  plots = FALSE
    +)
    +
    + +
    +

    Arguments

    + + +
    mvdat
    +

    Output from mv_harmonise_data().

    + + +
    intercept
    +

    Should the intercept by estimated (TRUE) or force line through the origin (FALSE, default).

    + + +
    instrument_specific
    +

    Should the estimate for each exposure be obtained by using all instruments from all exposures (FALSE, default) or by using only the instruments specific to each exposure (TRUE).

    + + +
    pval_threshold
    +

    P-value threshold to include instruments. The default is 5e-8.

    + + +
    plots
    +

    Create plots? The default is FALSE.

    + +
    +
    +

    Value

    +

    List of results

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mv_residual.html b/docs/reference/mv_residual.html new file mode 100644 index 00000000..3e88d209 --- /dev/null +++ b/docs/reference/mv_residual.html @@ -0,0 +1,117 @@ + +Perform basic multivariable MR — mv_residual • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Performs initial multivariable MR analysis from Burgess et al 2015. +For each exposure the outcome is residualised for all the other exposures, then unweighted regression is applied.

    +
    + +
    +

    Usage

    +
    mv_residual(
    +  mvdat,
    +  intercept = FALSE,
    +  instrument_specific = FALSE,
    +  pval_threshold = 5e-08,
    +  plots = FALSE
    +)
    +
    + +
    +

    Arguments

    + + +
    mvdat
    +

    Output from mv_harmonise_data().

    + + +
    intercept
    +

    Should the intercept by estimated (TRUE) or force line through the origin (FALSE, default).

    + + +
    instrument_specific
    +

    Should the estimate for each exposure be obtained by using all instruments from all exposures (FALSE, default) or by using only the instruments specific to each exposure (TRUE).

    + + +
    pval_threshold
    +

    P-value threshold to include instruments. The default is 5e-8.

    + + +
    plots
    +

    Create plots? The default is FALSE.

    + +
    +
    +

    Value

    +

    List of results

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/mv_subset.html b/docs/reference/mv_subset.html new file mode 100644 index 00000000..80d6f372 --- /dev/null +++ b/docs/reference/mv_subset.html @@ -0,0 +1,131 @@ + +Perform multivariable MR on subset of features — mv_subset • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    The function proceeds as follows:

    1. Select features (by default this is done using LASSO feature selection).

    2. +
    3. Subset the mvdat to only retain relevant features and instruments.

    4. +
    5. Perform MVMR on remaining data.

    6. +
    + +
    +

    Usage

    +
    mv_subset(
    +  mvdat,
    +  features = mv_lasso_feature_selection(mvdat),
    +  intercept = FALSE,
    +  instrument_specific = FALSE,
    +  pval_threshold = 5e-08,
    +  plots = FALSE
    +)
    +
    + +
    +

    Arguments

    + + +
    mvdat
    +

    Output from mv_harmonise_data().

    + + +
    features
    +

    Dataframe of features to retain, must have column with name 'exposure' that has list of exposures to retain from mvdat. The default is mvdat_lasso_feature_selection(mvdat).

    + + +
    intercept
    +

    Should the intercept by estimated (TRUE) or force line through the origin (FALSE, the default).

    + + +
    instrument_specific
    +

    Should the estimate for each exposure be obtained by using all instruments from all exposures (FALSE, default) or by using only the instruments specific to each exposure (TRUE).

    + + +
    pval_threshold
    +

    P-value threshold to include instruments. The default is 5e-8.

    + + +
    plots
    +

    Create plots? The default is FALSE.

    + +
    +
    +

    Value

    +

    List of results

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/pipe.html b/docs/reference/pipe.html new file mode 100644 index 00000000..5fd30f2c --- /dev/null +++ b/docs/reference/pipe.html @@ -0,0 +1,79 @@ + +Pipe operator — %>% • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    See magrittr::%>% for details.

    +
    + +
    +

    Usage

    +
    lhs %>% rhs
    +
    + + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/power_prune.html b/docs/reference/power_prune.html new file mode 100644 index 00000000..723c7af0 --- /dev/null +++ b/docs/reference/power_prune.html @@ -0,0 +1,128 @@ + +Power prune — power_prune • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    When there are duplicate summary sets for a particular exposure-outcome combination, this function keeps the +exposure-outcome summary set with the highest expected statistical power. +This can be done by dropping the duplicate summary sets with the smaller sample sizes. +Alternatively, the pruning procedure can take into account instrument strength and outcome sample size. +The latter is useful, for example, when there is considerable variation in SNP coverage between duplicate summary sets +(e.g. because some studies have used targeted or fine mapping arrays). +If there are a large number of SNPs available to instrument an exposure, +the outcome GWAS with the better SNP coverage may provide better power than the outcome GWAS with the larger sample size.

    +
    + +
    +

    Usage

    +
    power_prune(dat, method = 1, dist.outcome = "binary")
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Results from harmonise_data().

    + + +
    method
    +

    Should the duplicate summary sets be pruned on the basis of sample size alone (method = 1) +or a combination of instrument strength and sample size (method = 2)? Default set to 1. +When set to 1, the duplicate summary sets are first dropped on the basis of the outcome sample size (smaller duplicates dropped). +If duplicates are still present, remaining duplicates are dropped on the basis of the exposure sample size (smaller duplicates dropped). +When method is set to 2, duplicates are dropped on the basis of instrument strength +(amount of variation explained in the exposure by the instrumental SNPs) and sample size, +and assumes that the SNP-exposure effects correspond to a continuous trait with a normal distribution (i.e. exposure cannot be binary). +The SNP-outcome effects can correspond to either a binary or continuous trait. If the exposure is binary then method=1 should be used.

    + + +
    dist.outcome
    +

    The distribution of the outcome. Can either be "binary" or "continuous". Default set to "binary".

    + +
    +
    +

    Value

    +

    data.frame with duplicate summary sets removed

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/read_exposure_data.html b/docs/reference/read_exposure_data.html new file mode 100644 index 00000000..0d3760b0 --- /dev/null +++ b/docs/reference/read_exposure_data.html @@ -0,0 +1,197 @@ + +Read exposure data — read_exposure_data • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Reads in exposure data. Checks and organises columns for use with MR or enrichment tests. +Infers p-values when possible from beta and se.

    +
    + +
    +

    Usage

    +
    read_exposure_data(
    +  filename,
    +  clump = FALSE,
    +  sep = " ",
    +  phenotype_col = "Phenotype",
    +  snp_col = "SNP",
    +  beta_col = "beta",
    +  se_col = "se",
    +  eaf_col = "eaf",
    +  effect_allele_col = "effect_allele",
    +  other_allele_col = "other_allele",
    +  pval_col = "pval",
    +  units_col = "units",
    +  ncase_col = "ncase",
    +  ncontrol_col = "ncontrol",
    +  samplesize_col = "samplesize",
    +  gene_col = "gene",
    +  id_col = "id",
    +  min_pval = 1e-200,
    +  log_pval = FALSE,
    +  chr_col = "chr",
    +  pos_col = "pos"
    +)
    +
    + +
    +

    Arguments

    + + +
    filename
    +

    Filename. Must have header with at least SNP column present.

    + + +
    clump
    +

    Whether to perform LD clumping with clump_data() on the exposure data. The default is FALSE.

    + + +
    sep
    +

    Specify delimeter in file. The default is a space, i.e. " ".

    + + +
    phenotype_col
    +

    Optional column name for the column with phenotype name corresponding the the SNP. If not present then will be created with the value "Outcome". The default is "Phenotype".

    + + +
    snp_col
    +

    Required name of column with SNP rs IDs. The default is "SNP".

    + + +
    beta_col
    +

    Required for MR. Name of column with effect sizes. The default is "beta".

    + + +
    se_col
    +

    Required for MR. Name of column with standard errors. The default is "se".

    + + +
    eaf_col
    +

    Required for MR. Name of column with effect allele frequency. The default is "eaf".

    + + +
    effect_allele_col
    +

    Required for MR. Name of column with effect allele. Must be "A", "C", "T" or "G". The default is "effect_allele".

    + + +
    other_allele_col
    +

    Required for MR. Name of column with non effect allele. Must be "A", "C", "T" or "G". The default is "other_allele".

    + + +
    pval_col
    +

    Required for enrichment tests. Name of column with p-value. The default is "pval".

    + + +
    units_col
    +

    Optional column name for units. The default is "units".

    + + +
    ncase_col
    +

    Optional column name for number of cases. The default is "ncase".

    + + +
    ncontrol_col
    +

    Optional column name for number of controls. The default is "ncontrol".

    + + +
    samplesize_col
    +

    Optional column name for sample size. The default is "samplesize".

    + + +
    gene_col
    +

    Optional column name for gene name. The default is "gene".

    + + +
    id_col
    +

    Optional column name to give the dataset an ID. Will be generated automatically if not provided for every trait / unit combination. The default is "id".

    + + +
    min_pval
    +

    Minimum allowed p-value. The default is 1e-200.

    + + +
    log_pval
    +

    The p-value is -log10(P). The default is FALSE.

    + + +
    chr_col
    +

    Optional column name for chromosome. Default is "chr".

    + + +
    pos_col
    +

    Optional column name for genetic position Default is "pos".

    + +
    +
    +

    Value

    +

    data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/read_outcome_data.html b/docs/reference/read_outcome_data.html new file mode 100644 index 00000000..d45fe577 --- /dev/null +++ b/docs/reference/read_outcome_data.html @@ -0,0 +1,197 @@ + +Read outcome data — read_outcome_data • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Reads in outcome data. Checks and organises columns for use with MR or enrichment tests. +Infers p-values when possible from beta and se.

    +
    + +
    +

    Usage

    +
    read_outcome_data(
    +  filename,
    +  snps = NULL,
    +  sep = " ",
    +  phenotype_col = "Phenotype",
    +  snp_col = "SNP",
    +  beta_col = "beta",
    +  se_col = "se",
    +  eaf_col = "eaf",
    +  effect_allele_col = "effect_allele",
    +  other_allele_col = "other_allele",
    +  pval_col = "pval",
    +  units_col = "units",
    +  ncase_col = "ncase",
    +  ncontrol_col = "ncontrol",
    +  samplesize_col = "samplesize",
    +  gene_col = "gene",
    +  id_col = "id",
    +  min_pval = 1e-200,
    +  log_pval = FALSE,
    +  chr_col = "chr",
    +  pos_col = "pos"
    +)
    +
    + +
    +

    Arguments

    + + +
    filename
    +

    Filename. Must have header with at least SNP column present.

    + + +
    snps
    +

    SNPs to extract. If NULL, which the default, then doesn't extract any and keeps all.

    + + +
    sep
    +

    Specify delimeter in file. The default is space, i.e. sep=" ".

    + + +
    phenotype_col
    +

    Optional column name for the column with phenotype name corresponding the the SNP. If not present then will be created with the value "Outcome". Default is "Phenotype".

    + + +
    snp_col
    +

    Required name of column with SNP rs IDs. The default is "SNP".

    + + +
    beta_col
    +

    Required for MR. Name of column with effect sizes. THe default is "beta".

    + + +
    se_col
    +

    Required for MR. Name of column with standard errors. The default is "se".

    + + +
    eaf_col
    +

    Required for MR. Name of column with effect allele frequency. The default is "eaf".

    + + +
    effect_allele_col
    +

    Required for MR. Name of column with effect allele. Must be "A", "C", "T" or "G". The default is "effect_allele".

    + + +
    other_allele_col
    +

    Required for MR. Name of column with non effect allele. Must be "A", "C", "T" or "G". The default is "other_allele".

    + + +
    pval_col
    +

    Required for enrichment tests. Name of column with p-value. The default is "pval".

    + + +
    units_col
    +

    Optional column name for units. The default is "units".

    + + +
    ncase_col
    +

    Optional column name for number of cases. The default is "ncase".

    + + +
    ncontrol_col
    +

    Optional column name for number of controls. The default is "ncontrol".

    + + +
    samplesize_col
    +

    Optional column name for sample size. The default is "samplesize".

    + + +
    gene_col
    +

    Optional column name for gene name. The default is "gene".

    + + +
    id_col
    +

    Optional column name to give the dataset an ID. Will be generated automatically if not provided for every trait / unit combination. The default is "id".

    + + +
    min_pval
    +

    Minimum allowed p-value. The default is 1e-200.

    + + +
    log_pval
    +

    The pval is -log10(P). The default is FALSE.

    + + +
    chr_col
    +

    Optional column name for chromosome. Default is "chr".

    + + +
    pos_col
    +

    Optional column name for genetic position Default is "pos".

    + +
    +
    +

    Value

    +

    data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/run_mr_presso.html b/docs/reference/run_mr_presso.html new file mode 100644 index 00000000..043a5cfa --- /dev/null +++ b/docs/reference/run_mr_presso.html @@ -0,0 +1,100 @@ + +Wrapper for MR-PRESSO — run_mr_presso • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    See https://github.com/rondolab/MR-PRESSO for more details.

    +
    + +
    +

    Usage

    +
    run_mr_presso(dat, NbDistribution = 1000, SignifThreshold = 0.05)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from harmonise_data().

    + + +
    NbDistribution
    +

    Number of bootstrap replications. The default is 1000.

    + + +
    SignifThreshold
    +

    Outlier significance threshold. The default is 0.05.

    + +
    +
    +

    Value

    +

    List of results for every exposure/outcome combination

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/run_mrmix.html b/docs/reference/run_mrmix.html new file mode 100644 index 00000000..73b7dd22 --- /dev/null +++ b/docs/reference/run_mrmix.html @@ -0,0 +1,92 @@ + +Perform MRMix analysis on harmonised dat object — run_mrmix • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    See https://github.com/gqi/MRMix for more details.

    +
    + +
    +

    Usage

    +
    run_mrmix(dat)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from harmonise_data(). Ensures that no eaf.exposure values are missing.

    + +
    +
    +

    Value

    +

    List of results, with one list item for every exposure/outcome pair in dat object

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/simple_cap.html b/docs/reference/simple_cap.html new file mode 100644 index 00000000..107baa6b --- /dev/null +++ b/docs/reference/simple_cap.html @@ -0,0 +1,92 @@ + +Simple attempt at correcting string case — simple_cap • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Simple attempt at correcting string case

    +
    + +
    +

    Usage

    +
    simple_cap(x)
    +
    + +
    +

    Arguments

    + + +
    x
    +

    Character or array of character

    + +
    +
    +

    Value

    +

    Character or array of character

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/size.prune.html b/docs/reference/size.prune.html new file mode 100644 index 00000000..8d5b6386 --- /dev/null +++ b/docs/reference/size.prune.html @@ -0,0 +1,98 @@ + +Size prune — size.prune • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Whens there are duplicate summary sets for a particular exposure-outcome combination, +this function drops the duplicates with the smaller total sample size +(for binary outcomes, the number of cases is used instead of total sample size).

    +
    + +
    +

    Usage

    +
    size.prune(dat)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Results from harmonise_data().

    + +
    +
    +

    Value

    +

    data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/sort_1_to_many.html b/docs/reference/sort_1_to_many.html new file mode 100644 index 00000000..25b8edc2 --- /dev/null +++ b/docs/reference/sort_1_to_many.html @@ -0,0 +1,125 @@ + +Sort results for 1-to-many forest plot — sort_1_to_many • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    This function sorts user-supplied results for the forest_plot_1_to_many() function. The user supplies their results in the form of a data frame.

    +
    + +
    +

    Usage

    +
    sort_1_to_many(
    +  mr_res,
    +  b = "b",
    +  trait_m = "outcome",
    +  sort_action = 4,
    +  group = NULL,
    +  priority = NULL
    +)
    +
    + +
    +

    Arguments

    + + +
    mr_res
    +

    Data frame of results supplied by the user.

    + + +
    b
    +

    Name of the column specifying the effect of the exposure on the outcome. The default is "b".

    + + +
    trait_m
    +

    The column specifying the names of the traits. Corresponds to 'many' in the 1-to-many forest plot. The default is "outcome".

    + + +
    sort_action
    +

    Choose how to sort results.

    • sort_action = 1: sort results by effect size within groups. Use the group order supplied by the user.

    • +
    • sort_action = 2: sort results by effect size and group. Overides the group ordering supplied by the user.

    • +
    • sort_action = 3: group results for the same trait together (e.g. multiple results for the same trait from different MR methods).

    • +
    • sort_action = 4: sort by decreasing effect size (largest effect size at top and smallest at bottom).

    • +
    • sort_action = 5: sort by increasing effect size (smallest effect size at top and largest at bottom).

    • +
    + + +
    group
    +

    Name of grouping variable in mr_res.

    + + +
    priority
    +

    If sort_action = 3, choose which value of the trait_m variable should be given priority and go above the other trait_m values. +The trait with the largest effect size for the prioritised group will go to the top of the plot.

    + +
    +
    +

    Value

    +

    data frame.

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/split_exposure.html b/docs/reference/split_exposure.html new file mode 100644 index 00000000..9b1bf2e9 --- /dev/null +++ b/docs/reference/split_exposure.html @@ -0,0 +1,92 @@ + +Split exposure column — split_exposure • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    This function takes the exposure column from the results generated by mr() and splits it into separate columns for 'exposure name' and 'id'.

    +
    + +
    +

    Usage

    +
    split_exposure(mr_res)
    +
    + +
    +

    Arguments

    + + +
    mr_res
    +

    Results from mr().

    + +
    +
    +

    Value

    +

    data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/split_outcome.html b/docs/reference/split_outcome.html new file mode 100644 index 00000000..c3be97b0 --- /dev/null +++ b/docs/reference/split_outcome.html @@ -0,0 +1,92 @@ + +Split outcome column — split_outcome • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    This function takes the outcome column from the results generated by mr() and splits it into separate columns for 'outcome name' and 'id'.

    +
    + +
    +

    Usage

    +
    split_outcome(mr_res)
    +
    + +
    +

    Arguments

    + + +
    mr_res
    +

    Results from mr().

    + +
    +
    +

    Value

    +

    data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/standardise_units.html b/docs/reference/standardise_units.html new file mode 100644 index 00000000..0a9ef300 --- /dev/null +++ b/docs/reference/standardise_units.html @@ -0,0 +1,92 @@ + +Try to standardise continuous traits to be in standard deviation units — standardise_units • TwoSampleMR + Skip to contents + + +
    +
    +
    + + + +
    +

    Usage

    +
    standardise_units(dat)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from harmonise_data().

    + +
    +
    +

    Value

    +

    Data frame

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/steiger_filtering.html b/docs/reference/steiger_filtering.html new file mode 100644 index 00000000..598f6324 --- /dev/null +++ b/docs/reference/steiger_filtering.html @@ -0,0 +1,123 @@ + +Steiger filtering function — steiger_filtering • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    This function takes an object from harmonise_data() and does the following: +If there is no rsq.exposure or rsq.outcome column it will try to estimate it. +This is done differently for traits that have "log odds" units. +To estimate rsq for quantitative traits there must be either p-values and sample sizes for each SNP, +or effect sizes and standard errors AND the units are in SD units (the column must contain "SD"). +To estimate rsq for binary traits the units must be called "log odds" and there must be beta.exposure, +eaf.exposure, ncase.exposure, ncontrol.exposure, prevalence.exposure. +The same principles apply for calculating the rsq for the outcome trait, except column names are beta.outcome etc. +If prevalence isn't supplied then it uses 0.1 by default.

    +
    + +
    +

    Usage

    +
    steiger_filtering(dat)
    +
    + +
    +

    Arguments

    + + +
    dat
    +

    Output from harmonise_data().

    + +
    +
    +

    Value

    +

    harmonise_data() style data frame with additional columns rsq.exposure, rsq.outcome, steiger_dir (which is TRUE if the rsq.exposure is larger than rsq.outcome) and steiger_pval which is a test to see if rsq.exposure is significantly larger than rsq.outcome.

    +
    +
    +

    Details

    +

    Once rsq is calculated for the exposure and outcome, it will then perform the Steiger test for each SNP to see if the rsq of the exposure is larger than the rsq of the outcome.

    +

    Note that Steiger filtering, while useful, does have its own pitfalls. +Try to use replication effect estimates for the exposure (which are not biased by winner's curse), +and note that if there is strong antagonistic confounding or differential measurement error between the exposure and outcome then the causal directions could be inferred incorrectly.

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/steiger_sensitivity.html b/docs/reference/steiger_sensitivity.html new file mode 100644 index 00000000..76460d55 --- /dev/null +++ b/docs/reference/steiger_sensitivity.html @@ -0,0 +1,115 @@ + +Evaluate the Steiger test's sensitivity to measurement error — steiger_sensitivity • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Evaluate the Steiger test's sensitivity to measurement error

    +
    + +
    +

    Usage

    +
    steiger_sensitivity(rgx_o, rgy_o, ...)
    +
    + +
    +

    Arguments

    + + +
    rgx_o
    +

    Observed variance of exposure explained by SNPs

    + + +
    rgy_o
    +

    Observed variance of outcome explained by SNPs

    + + +
    ...
    +

    Further arguments to be passed to lattice::wireframe()

    + +
    +
    +

    Value

    +

    List with the following elements:

    vz
    +

    Total volume of the error parameter space

    + +
    vz0
    +

    Volume of the parameter space that gives the incorrect answer

    + +
    vz1
    +

    Volume of the paramtere space that gives the correct answer

    + +
    sensitivity_ratio
    +

    Ratio of vz1/vz0. Higher means inferred direction is less susceptible to measurement error

    + +
    pl
    +

    plot of parameter space

    + + +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/subset_on_method.html b/docs/reference/subset_on_method.html new file mode 100644 index 00000000..3d1536ae --- /dev/null +++ b/docs/reference/subset_on_method.html @@ -0,0 +1,104 @@ + +Subset MR-results on method — subset_on_method • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    This function takes MR results from mr() and restricts to a single method per exposure x disease combination.

    +
    + +
    +

    Usage

    +
    subset_on_method(
    +  mr_res,
    +  single_snp_method = "Wald ratio",
    +  multi_snp_method = "Inverse variance weighted"
    +)
    +
    + +
    +

    Arguments

    + + +
    mr_res
    +

    Results from mr().

    + + +
    single_snp_method
    +

    Which of the single SNP methods to use when only 1 SNP was used to estimate the causal effect? The default is "Wald ratio".

    + + +
    multi_snp_method
    +

    Which of the multi-SNP methods to use when there was more than 1 SNPs used to estimate the causal effect? The default is "Inverse variance weighted".

    + +
    +
    +

    Value

    +

    data frame.

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/trim.html b/docs/reference/trim.html new file mode 100644 index 00000000..526b3b1b --- /dev/null +++ b/docs/reference/trim.html @@ -0,0 +1,92 @@ + +Trim function to remove leading and trailing blank spaces — trim • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Trim function to remove leading and trailing blank spaces

    +
    + +
    +

    Usage

    +
    trim(x)
    +
    + +
    +

    Arguments

    + + +
    x
    +

    Character or array of character

    + +
    +
    +

    Value

    +

    Character or array of character

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/weighted_median.html b/docs/reference/weighted_median.html new file mode 100644 index 00000000..800eb12d --- /dev/null +++ b/docs/reference/weighted_median.html @@ -0,0 +1,96 @@ + +Weighted median method — weighted_median • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    New method from Jack

    +
    + +
    +

    Usage

    +
    weighted_median(b_iv, weights)
    +
    + +
    +

    Arguments

    + + +
    b_iv
    +

    Wald ratios

    + + +
    weights
    +

    Weights of each SNP

    + +
    +
    +

    Value

    +

    MR estimate

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/reference/weighted_median_bootstrap.html b/docs/reference/weighted_median_bootstrap.html new file mode 100644 index 00000000..a37b87ee --- /dev/null +++ b/docs/reference/weighted_median_bootstrap.html @@ -0,0 +1,112 @@ + +Calculate standard errors for weighted median method using bootstrap — weighted_median_bootstrap • TwoSampleMR + Skip to contents + + +
    +
    +
    + +
    +

    Based on new script for weighted median confidence interval, update 31 July 2015.

    +
    + +
    +

    Usage

    +
    weighted_median_bootstrap(b_exp, b_out, se_exp, se_out, weights, nboot)
    +
    + +
    +

    Arguments

    + + +
    b_exp
    +

    Vector of genetic effects on exposure.

    + + +
    b_out
    +

    Vector of genetic effects on outcome.

    + + +
    se_exp
    +

    Standard errors of genetic effects on exposure.

    + + +
    se_out
    +

    Standard errors of genetic effects on outcome.

    + + +
    weights
    +

    Weights to apply to each SNP.

    + + +
    nboot
    +

    Number of bootstrap replications. The default is 1000.

    + +
    +
    +

    Value

    +

    Empirical standard error

    +
    + +
    + + +
    + + + +
    + + + + + + + diff --git a/docs/search.json b/docs/search.json new file mode 100644 index 00000000..e8e63325 --- /dev/null +++ b/docs/search.json @@ -0,0 +1 @@ +[{"path":"https://mrcieu.github.io/TwoSampleMR/LICENSE.html","id":null,"dir":"","previous_headings":"","what":"MIT License","title":"MIT License","text":"Copyright (c) 2019 Gibran Hemani Permission hereby granted, free charge, person obtaining copy software associated documentation files (“Software”), deal Software without restriction, including without limitation rights use, copy, modify, merge, publish, distribute, sublicense, /sell copies Software, permit persons Software furnished , subject following conditions: copyright notice permission notice shall included copies substantial portions Software. SOFTWARE PROVIDED “”, WITHOUT WARRANTY KIND, EXPRESS IMPLIED, INCLUDING LIMITED WARRANTIES MERCHANTABILITY, FITNESS PARTICULAR PURPOSE NONINFRINGEMENT. EVENT SHALL AUTHORS COPYRIGHT HOLDERS LIABLE CLAIM, DAMAGES LIABILITY, WHETHER ACTION CONTRACT, TORT OTHERWISE, ARISING , CONNECTION SOFTWARE USE DEALINGS SOFTWARE.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/exposure.html","id":"introduction","dir":"Articles","previous_headings":"","what":"Introduction","title":"Exposure data","text":"data frame instruments exposure required. line information one variant one exposure. minimum information required MR analysis following: SNP - rs ID beta - effect size. trait binary log() used se - standard error effect size effect_allele - allele SNP effect marked beta information useful MR can also provided: other_allele - non-effect allele eaf - effect allele frequency Phenotype - name phenotype SNP effect can also provide following extra information: chr - Physical position variant (chromosome) position - Physical position variant (position) samplesize - Sample size estimating effect size ncase - Number cases ncontrol - Number controls pval - P-value SNP’s association exposure units - units effects presented gene - gene annotation SNP","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/exposure.html","id":"reading-in-from-a-file","dir":"Articles","previous_headings":"","what":"Reading in from a file","title":"Exposure data","text":"data can read text file using read_exposure_data function. file must header column names corresponding columns described .","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/exposure.html","id":"example-1-the-default-column-names-are-used","dir":"Articles","previous_headings":"Reading in from a file","what":"Example 1: The default column names are used","title":"Exposure data","text":"example text file default column names provided part package, first rows look like : exact path file different everyone’s computer, can located like : can read data like : output function new data frame standardised column names: SNP exposure beta.exposure se.exposure effect_allele.exposure other_allele.exposure eaf.exposure mr_keep.exposure pval.exposure pval_origin.exposure id.exposure data_source.exposure units.exposure gene.exposure samplesize.exposure function attempts match columns ones expects. also checks data type expected. required data MR performed present (SNP name, effect size, standard error, effect allele) particular SNP, column mr_keep.exposure FALSE.","code":"Phenotype SNP beta se effect_allele other_allele eaf pval units gene samplesize BMI rs10767664 0.19 0.0306122448979592 A T 0.78 5e-26 kg/m2 BDNF 225238 BMI rs13078807 0.1 0.0204081632653061 G A 0.2 4e-11 kg/m2 CADM2 221431 BMI rs1514175 0.07 0.0204081632653061 A G 0.43 8e-14 kg/m2 TNNI3K 207641 BMI rs1558902 0.39 0.0204081632653061 A T 0.42 5e-120 kg/m2 FTO 222476 BMI rs10968576 0.11 0.0204081632653061 G A 0.31 3e-13 kg/m2 LRRN6C 247166 BMI rs2241423 0.13 0.0204081632653061 G A 0.78 1e-18 kg/m2 LBXCOR1 227886 bmi_file <- system.file(\"extdata\", \"bmi.txt\", package = \"TwoSampleMR\") bmi_exp_dat <- read_exposure_data(bmi_file) head(bmi_exp_dat) #> SNP beta.exposure se.exposure effect_allele.exposure #> 1 rs10767664 0.19 0.03061224 A #> 2 rs13078807 0.10 0.02040816 G #> 3 rs1514175 0.07 0.02040816 A #> 4 rs1558902 0.39 0.02040816 A #> 5 rs10968576 0.11 0.02040816 G #> 6 rs2241423 0.13 0.02040816 G #> other_allele.exposure eaf.exposure pval.exposure units.exposure gene.exposure #> 1 T 0.78 5e-26 kg/m2 BDNF #> 2 A 0.20 4e-11 kg/m2 CADM2 #> 3 G 0.43 8e-14 kg/m2 TNNI3K #> 4 T 0.42 5e-120 kg/m2 FTO #> 5 A 0.31 3e-13 kg/m2 LRRN6C #> 6 A 0.78 1e-18 kg/m2 LBXCOR1 #> samplesize.exposure exposure mr_keep.exposure pval_origin.exposure #> 1 225238 BMI TRUE reported #> 2 221431 BMI TRUE reported #> 3 207641 BMI TRUE reported #> 4 222476 BMI TRUE reported #> 5 247166 BMI TRUE reported #> 6 227886 BMI TRUE reported #> units.exposure_dat id.exposure data_source.exposure #> 1 kg/m2 ImbABK textfile #> 2 kg/m2 ImbABK textfile #> 3 kg/m2 ImbABK textfile #> 4 kg/m2 ImbABK textfile #> 5 kg/m2 ImbABK textfile #> 6 kg/m2 ImbABK textfile"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/exposure.html","id":"example-2-the-text-file-has-non-default-column-names","dir":"Articles","previous_headings":"Reading in from a file","what":"Example 2: The text file has non-default column names","title":"Exposure data","text":"text file default column names, can still read follows. first rows example: Note CSV file, commas separating fields. file located : read data: Phenotype column provided (case example) assume phenotype’s name simply “exposure”. entered exposure column. can renamed manually:","code":"rsid,effect,SE,a1,a2,a1_freq,p-value,Units,Gene,n rs10767664,0.19,0.030612245,A,T,0.78,5.00E-26,kg/m2,BDNF,225238 rs13078807,0.1,0.020408163,G,A,0.2,4.00E-11,kg/m2,CADM2,221431 rs1514175,0.07,0.020408163,A,G,0.43,8.00E-14,kg/m2,TNNI3K,207641 rs1558902,0.39,0.020408163,A,T,0.42,5.00E-120,kg/m2,FTO,222476 bmi2_file <- system.file(\"extdata/bmi.csv\", package = \"TwoSampleMR\") bmi_exp_dat <- read_exposure_data( filename = bmi2_file, sep = \",\", snp_col = \"rsid\", beta_col = \"effect\", se_col = \"SE\", effect_allele_col = \"a1\", other_allele_col = \"a2\", eaf_col = \"a1_freq\", pval_col = \"p-value\", units_col = \"Units\", gene_col = \"Gene\", samplesize_col = \"n\" ) #> No phenotype name specified, defaulting to 'exposure'. head(bmi_exp_dat) #> SNP beta.exposure se.exposure effect_allele.exposure #> 1 rs10767664 0.19 0.03061224 A #> 2 rs13078807 0.10 0.02040816 G #> 3 rs1514175 0.07 0.02040816 A #> 4 rs1558902 0.39 0.02040816 A #> 5 rs10968576 0.11 0.02040816 G #> 6 rs2241423 0.13 0.02040816 G #> other_allele.exposure eaf.exposure pval.exposure units.exposure gene.exposure #> 1 T 0.78 5e-26 kg/m2 BDNF #> 2 A 0.20 4e-11 kg/m2 CADM2 #> 3 G 0.43 8e-14 kg/m2 TNNI3K #> 4 T 0.42 5e-120 kg/m2 FTO #> 5 A 0.31 3e-13 kg/m2 LRRN6C #> 6 A 0.78 1e-18 kg/m2 LBXCOR1 #> samplesize.exposure exposure mr_keep.exposure pval_origin.exposure #> 1 225238 exposure TRUE reported #> 2 221431 exposure TRUE reported #> 3 207641 exposure TRUE reported #> 4 222476 exposure TRUE reported #> 5 247166 exposure TRUE reported #> 6 227886 exposure TRUE reported #> units.exposure_dat id.exposure data_source.exposure #> 1 kg/m2 Ku3B84 textfile #> 2 kg/m2 Ku3B84 textfile #> 3 kg/m2 Ku3B84 textfile #> 4 kg/m2 Ku3B84 textfile #> 5 kg/m2 Ku3B84 textfile #> 6 kg/m2 Ku3B84 textfile bmi_exp_dat$exposure <- \"BMI\""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/exposure.html","id":"using-an-existing-data-frame","dir":"Articles","previous_headings":"","what":"Using an existing data frame","title":"Exposure data","text":"data already exists data frame R can converted correct format using format_data() function. example, randomly created data: can formatted like :","code":"random_df <- data.frame( SNP = c(\"rs1\", \"rs2\"), beta = c(1, 2), se = c(1, 2), effect_allele = c(\"A\", \"T\") ) random_df #> SNP beta se effect_allele #> 1 rs1 1 1 A #> 2 rs2 2 2 T random_exp_dat <- format_data(random_df, type = \"exposure\") #> No phenotype name specified, defaulting to 'exposure'. #> Warning in format_data(random_df, type = \"exposure\"): The following columns are not present but are helpful for harmonisation #> other_alleleeaf #> Inferring p-values random_exp_dat #> SNP beta.exposure se.exposure effect_allele.exposure exposure #> 1 rs1 1 1 A exposure #> 2 rs2 2 2 T exposure #> mr_keep.exposure pval.exposure pval_origin.exposure id.exposure #> 1 TRUE 0.3173105 inferred 4nec1Z #> 2 TRUE 0.3173105 inferred 4nec1Z #> other_allele.exposure eaf.exposure #> 1 NA NA #> 2 NA NA"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/exposure.html","id":"obtaining-instruments-from-existing-catalogues","dir":"Articles","previous_headings":"","what":"Obtaining instruments from existing catalogues","title":"Exposure data","text":"number sources instruments already curated available use. provided data objects MRInstruments package. install: package contains number data.frames, repository SNP-trait associations. access data frames detailed :","code":"remotes::install_github(\"MRCIEU/MRInstruments\")"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/exposure.html","id":"gwas-catalog","dir":"Articles","previous_headings":"Obtaining instruments from existing catalogues","what":"GWAS catalog","title":"Exposure data","text":"NHGRI-EBI GWAS catalog contains catalog significant associations obtained GWASs. version data filtered harmonised contain associations required data perform MR, ensure units used report effect sizes particular study , data cleaning operations. use GWAS catalog: example, obtain instruments body mass index using Speliotes et al 2010 study:","code":"library(MRInstruments) data(gwas_catalog) head(gwas_catalog) #> Phenotype_simple #> 1 Eosinophil percentage of white cells #> 2 Eosinophil counts #> 3 Medication use (agents acting on the renin-angiotensin system) #> 4 Post bronchodilator FEV1 #> 5 DNA methylation variation (age effect) #> 6 Ankylosing spondylitis #> MAPPED_TRAIT_EFO #> 1 eosinophil percentage of leukocytes #> 2 eosinophil count #> 3 Agents acting on the renin-angiotensin system use measurement #> 4 forced expiratory volume, response to bronchodilator #> 5 DNA methylation #> 6 ankylosing spondylitis #> MAPPED_TRAIT_EFO_URI #> 1 http://www.ebi.ac.uk/efo/EFO_0007991 #> 2 http://www.ebi.ac.uk/efo/EFO_0004842 #> 3 http://www.ebi.ac.uk/efo/EFO_0009931 #> 4 http://www.ebi.ac.uk/efo/EFO_0004314, http://purl.obolibrary.org/obo/GO_0097366 #> 5 http://purl.obolibrary.org/obo/GO_0006306 #> 6 http://www.ebi.ac.uk/efo/EFO_0003898 #> Initial_sample_description #> 1 172,378 European ancestry individuals #> 2 172,275 European ancestry individuals #> 3 62,752 European ancestry cases, 174,778 European ancestry controls #> 4 10,094 European ancestry current and former smoker individuals, 3,260 African American current and former smoker individuals, 178 current and former smoker individuals #> 5 Up to 954 individuals #> 6 921 Turkish ancestry cases, 907 Turkish ancestry controls, 422 Iranian ancestry cases, 754 Iranian ancestry controls #> Replication_sample_description STUDY.ACCESSION #> 1 GCST004600 #> 2 GCST004606 #> 3 GCST007930 #> 4 GCST003262 #> 5 GCST006660 #> 6 GCST007844 #> Phenotype Phenotype_info #> 1 Eosinophil percentage of white cells #> 2 Eosinophil counts #> 3 Medication use (agents acting on the renin-angiotensin system) #> 4 Post bronchodilator FEV1 #> 5 DNA methylation variation (age effect) #> 6 Ankylosing spondylitis #> PubmedID Author Year SNP chr bp_ens_GRCh38 Region gene #> 1 27863252 Astle WJ 2016 rs1000005 21 33060745 21q22.11 AP000282.2 #> 2 27863252 Astle WJ 2016 rs1000005 21 33060745 21q22.11 AP000282.2 #> 3 31015401 Wu Y 2019 rs1000010 3 11562645 3p25.3 VGLL4 #> 4 26634245 Lutz SM 2015 rs10000225 4 144312789 4q31.21 Intergenic #> 5 30348214 Zhang Q 2018 rs10000513 4 160334994 4q32.1 NR #> 6 30946743 Li Z 2019 rs10000518 4 11502867 4p15.33 HS3ST1 #> Gene_ens effect_allele other_allele beta se pval #> 1 AP000282.2,LINC00945 C G -0.02652552 0.003826531 2e-13 #> 2 AP000282.2,LINC00945 C G -0.02481715 0.003571429 7e-12 #> 3 G A -0.03724189 0.006377551 6e-09 #> 4 Intergenic A T -0.04400000 0.009420188 3e-06 #> 5 NR NA NA 4e-08 #> 6 G A 0.73396926 NA 6e-06 #> units eaf date_added_to_MRBASE #> 1 unit decrease 0.589400 2019-08-29 #> 2 unit decrease 0.589400 2019-08-29 #> 3 unit decrease 0.351806 2019-08-29 #> 4 NR unit decrease 0.350000 2019-08-29 #> 5 NA 2019-08-29 #> 6 NA 2019-08-29 bmi_gwas <- subset(gwas_catalog, grepl(\"Speliotes\", Author) & Phenotype == \"Body mass index\") bmi_exp_dat <- format_data(bmi_gwas)"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/exposure.html","id":"metabolites","dir":"Articles","previous_headings":"Obtaining instruments from existing catalogues","what":"Metabolites","title":"Exposure data","text":"Independent top hits GWASs 121 metabolites whole blood stored metab_qtls data object. Use ?metab_qtls get information. example, obtain instruments Alanine:","code":"data(metab_qtls) head(metab_qtls) #> phenotype chromosome position SNP effect_allele other_allele eaf #> 1 AcAce 8 9181395 rs2169387 G A 0.870251 #> 2 AcAce 11 116648917 rs964184 C G 0.857715 #> 3 Ace 6 12042473 rs6933521 C T 0.120256 #> 4 Ala 2 27730940 rs1260326 C T 0.638817 #> 5 Ala 2 65220910 rs2160387 C T 0.403170 #> 6 Ala 12 47201814 rs4554975 G A 0.644059 #> beta se pval n_studies n #> 1 0.085630 0.015451 3.61e-08 11 19257 #> 2 -0.096027 0.014624 6.71e-11 11 19261 #> 3 -0.091667 0.015885 8.10e-09 14 24742 #> 4 -0.104582 0.009940 7.40e-26 13 22569 #> 5 -0.071001 0.009603 1.49e-13 14 24793 #> 6 -0.069135 0.009598 6.12e-13 14 24792 ala_exp_dat <- format_metab_qtls(subset(metab_qtls, phenotype == \"Ala\"))"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/exposure.html","id":"proteins","dir":"Articles","previous_headings":"Obtaining instruments from existing catalogues","what":"Proteins","title":"Exposure data","text":"Independent top hits GWASs 47 protein levels whole blood stored proteomic_qtls data object. Use ?proteomic_qtls get information. example, obtain instruments ApoH protein:","code":"data(proteomic_qtls) head(proteomic_qtls) #> analyte chr position SNP gene location annotation other_allele #> 1 CFHR1 1 196698945 rs12144939 CFH cis missense T #> 2 IL6r 1 154425456 rs12126142 IL6R cis missense A #> 3 ApoA4 11 116677723 rs1263167 APOA4 cis intergenic G #> 4 SELE 9 136149399 rs507666 ABO trans intronic A #> 5 FetuinA 3 186335941 rs2070633 AHSG cis missense T #> 6 ACE 17 61566031 rs4343 ACE cis synonymous A #> effect_allele eaf maf pval beta se #> 1 G 0.643 0.357 8.99e-143 -1.108 0.04355258 #> 2 G 0.608 0.392 1.81e-106 0.850 0.03878364 #> 3 A 0.803 0.197 2.64e-54 -0.919 0.05922332 #> 4 G 0.809 0.191 1.01e-52 -0.882 0.05771545 #> 5 C 0.676 0.324 2.88e-44 -0.629 0.04506925 #> 6 G 0.508 0.492 6.66e-44 0.493 0.03547679 apoh_exp_dat <- format_proteomic_qtls(subset(proteomic_qtls, analyte == \"ApoH\"))"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/exposure.html","id":"gene-expression-levels","dir":"Articles","previous_headings":"Obtaining instruments from existing catalogues","what":"Gene expression levels","title":"Exposure data","text":"Independent top hits GWASs 32432 gene identifiers 44 tissues available GTEX study gtex_eqtl. Use ?gtex_eqtl get information. example, obtain instruments IRAK1BP1 gene expression levels subcutaneous adipose tissue:","code":"data(gtex_eqtl) head(gtex_eqtl) #> tissue gene_name gene_start SNP snp_position #> 1 Adipose Subcutaneous RP4-669L17.10 1:317720 rs2519065 1:787151 #> 2 Adipose Subcutaneous RP11-206L10.1 1:661611 rs11804171 1:723819 #> 3 Adipose Subcutaneous RP11-206L10.3 1:677193 rs149110718 1:759227 #> 4 Adipose Subcutaneous RP11-206L10.2 1:700306 rs148649543 1:752796 #> 5 Adipose Subcutaneous RP11-206L10.9 1:714150 rs12184279 1:717485 #> 6 Adipose Subcutaneous RP11-206L10.8 1:736259 rs10454454 1:754954 #> effect_allele other_allele beta se pval n #> 1 A G 0.551788 0.0747180 2.14627e-12 298 #> 2 A T -0.917475 0.1150060 4.99967e-14 298 #> 3 T C 0.807571 0.1776530 8.44694e-06 298 #> 4 T C 0.745393 0.0958531 1.82660e-13 298 #> 5 A C 1.927250 0.2247390 9.55098e-16 298 #> 6 A G 1.000400 0.1787470 5.61079e-08 298 irak1bp1_exp_dat <- format_gtex_eqtl(subset( gtex_eqtl, gene_name == \"IRAK1BP1\" & tissue == \"Adipose Subcutaneous\" )) #> Warning in format_data(gtex_eqtl_subset, type = type, phenotype_col = type, : The following columns are not present but are helpful for harmonisation #> eaf #> Inferring p-values"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/exposure.html","id":"dna-methylation-levels","dir":"Articles","previous_headings":"Obtaining instruments from existing catalogues","what":"DNA methylation levels","title":"Exposure data","text":"Independent top hits GWASs 0 DNA methylation levels whole blood across 5 time points available ARIES study aries_mqtl. Use ?aries_mqtl get information. example, obtain instruments cg25212131 CpG DNA methylation levels birth:","code":"data(aries_mqtl) head(aries_mqtl) #> SNP timepoint cpg beta pval se snp_chr #> 1 esv2656832 1 cg21826606 0.3459 1.60408e-26 0.03265336 1 #> 2 esv2658098 1 cg22681495 -0.6263 1.55765e-66 0.03643240 15 #> 3 esv2660043 1 cg24276624 -0.5772 3.16370e-26 0.05481823 11 #> 4 esv2660043 1 cg11157765 -0.5423 1.33928e-22 0.05583777 11 #> 5 esv2660673 1 cg05832925 -0.5919 2.88011e-50 0.03982467 11 #> 6 esv2660769 1 cg05859533 -0.6224 1.49085e-58 0.03868158 16 #> snp_pos effect_allele other_allele eaf sex age units #> 1 25591901 I R 0.3974 mixed Birth SD units #> 2 86057007 D R 0.2076 mixed Birth SD units #> 3 69982552 D R 0.1450 mixed Birth SD units #> 4 69982552 D R 0.1450 mixed Birth SD units #> 5 74024905 D R 0.1671 mixed Birth SD units #> 6 57725395 D R 0.2136 mixed Birth SD units #> island_location cpg_chr cpg_pos gene gene_location cis_trans #> 1 N_Shore 1 25593055 cis #> 2 15 86058755 AKAP13 Body cis #> 3 11 69982941 ANO1 Body cis #> 4 11 69982996 ANO1 Body cis #> 5 S_Shelf 11 74026371 cis #> 6 16 57727230 CCDC135 TSS1500 cis cg25212131_exp_dat <- format_aries_mqtl(subset(aries_mqtl, cpg == \"cg25212131\" & age == \"Birth\"))"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/exposure.html","id":"ieu-opengwas-database","dir":"Articles","previous_headings":"Obtaining instruments from existing catalogues","what":"IEU OpenGWAS database","title":"Exposure data","text":"IEU OpenGWAS database contains entire summary statistics thousands GWASs. can browse : https://gwas.mrcieu.ac.uk/ can use database define instruments particular exposure. can also use database obtain effects constructing polygenic risk scores using different p-value thresholds. can check status API: obtain list details available GWASs following: information authentication see https://mrcieu.github.io/ieugwasr/articles/guide.html#authentication. available_outcomes() function returns table available studies database. study unique ID. e.g., might obtain extract instruments particular trait using particular study, example obtain SNPs body mass index using Locke et al. 2015 GIANT study, specify study ID follows: returns set LD clumped SNPs GWAS significant BMI. can specify various parameters function: p1 = P-value threshold keeping SNP clump = Whether return independent SNPs (default TRUE) r2 = maximum LD R-square allowed returned SNPs kb = distance search LD R-square values changing changing p1 parameter possible obtain SNP effects constructing polygenic risk scores.","code":"ieugwasr::api_status() ao <- available_outcomes() head(ao) head(subset(ao, select = c(trait, id))) #> trait id #> 1 Schizophrenia ieu-b-5103 #> 2 Schizophrenia ieu-b-5102 #> 3 Schizophrenia ieu-b-5101 #> 4 Schizophrenia ieu-b-5100 #> 5 Schizophrenia ieu-b-5099 #> 6 Schizophrenia ieu-b-5098 bmi2014_exp_dat <- extract_instruments(outcomes = 'ieu-a-2') str(bmi2014_exp_dat) #> 'data.frame': 79 obs. of 15 variables: #> $ pval.exposure : num 2.18e-08 4.57e-11 5.06e-14 5.45e-10 1.88e-28 ... #> $ samplesize.exposure : num 339152 339065 313621 338768 338123 ... #> $ chr.exposure : chr \"1\" \"1\" \"1\" \"1\" ... #> $ se.exposure : num 0.003 0.0031 0.0087 0.0029 0.003 0.0037 0.0031 0.003 0.0038 0.003 ... #> $ beta.exposure : num -0.0168 0.0201 0.0659 0.0181 0.0331 0.0497 -0.0227 0.0221 0.0209 0.0175 ... #> $ pos.exposure : int 47684677 78048331 110082886 201784287 72837239 177889480 49589847 96924097 164567689 181550962 ... #> $ id.exposure : chr \"ieu-a-2\" \"ieu-a-2\" \"ieu-a-2\" \"ieu-a-2\" ... #> $ SNP : chr \"rs977747\" \"rs17381664\" \"rs7550711\" \"rs2820292\" ... #> $ effect_allele.exposure: chr \"G\" \"C\" \"T\" \"C\" ... #> $ other_allele.exposure : chr \"T\" \"T\" \"C\" \"A\" ... #> $ eaf.exposure : num 0.5333 0.425 0.0339 0.5083 0.6083 ... #> $ exposure : chr \"Body mass index || id:ieu-a-2\" \"Body mass index || id:ieu-a-2\" \"Body mass index || id:ieu-a-2\" \"Body mass index || id:ieu-a-2\" ... #> $ mr_keep.exposure : logi TRUE TRUE TRUE TRUE TRUE TRUE ... #> $ pval_origin.exposure : chr \"reported\" \"reported\" \"reported\" \"reported\" ... #> $ data_source.exposure : chr \"igd\" \"igd\" \"igd\" \"igd\" ..."},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/exposure.html","id":"clumping","dir":"Articles","previous_headings":"","what":"Clumping","title":"Exposure data","text":"standard two sample MR important ensure instruments exposure independent. instruments identified exposure variable, IEU OpenGWAS database can used perform clumping. can provide list SNP IDs, SNPs extracted 1000 genomes data, LD calculated , amongst SNPs LD R-square specified threshold SNP lowest P-value retained. , use following command: clump_data() function takes data frame formatted exposure data type data frame. Note instruments MRInstruments package SNPs already LD clumped. Note: LD reference panel includes SNPs (INDELs). five super-populations LD can calculated, default European samples used. SNPs MAF > 0.01 within-population available. NOTE: variant dropped unclumped data absent reference panel. flexibility, including using LD reference data, see : https://mrcieu.github.io/ieugwasr/","code":"bmi_exp_dat <- clump_data(bmi2014_exp_dat) str(bmi_exp_dat) #> 'data.frame': 30 obs. of 16 variables: #> $ SNP : chr \"rs10767664\" \"rs13078807\" \"rs1514175\" \"rs1558902\" ... #> $ beta.exposure : num 0.19 0.1 0.07 0.39 0.11 0.13 0.06 0.09 0.13 0.06 ... #> $ se.exposure : num 0.0306 0.0204 0.0204 0.0204 0.0204 ... #> $ effect_allele.exposure: chr \"A\" \"G\" \"A\" \"A\" ... #> $ other_allele.exposure : chr \"T\" \"A\" \"G\" \"T\" ... #> $ eaf.exposure : num 0.78 0.2 0.43 0.42 0.31 0.78 0.41 0.24 0.21 0.21 ... #> $ pval.exposure : num 5e-26 4e-11 8e-14 5e-120 3e-13 ... #> $ units.exposure : chr \"kg/m2\" \"kg/m2\" \"kg/m2\" \"kg/m2\" ... #> $ gene.exposure : chr \"BDNF\" \"CADM2\" \"TNNI3K\" \"FTO\" ... #> $ samplesize.exposure : int 225238 221431 207641 222476 247166 227886 209051 218439 209849 220081 ... #> $ exposure : chr \"BMI\" \"BMI\" \"BMI\" \"BMI\" ... #> $ mr_keep.exposure : logi TRUE TRUE TRUE TRUE TRUE TRUE ... #> $ pval_origin.exposure : chr \"reported\" \"reported\" \"reported\" \"reported\" ... #> $ units.exposure_dat : chr \"kg/m2\" \"kg/m2\" \"kg/m2\" \"kg/m2\" ... #> $ id.exposure : chr \"FXhiAH\" \"FXhiAH\" \"FXhiAH\" \"FXhiAH\" ... #> $ data_source.exposure : chr \"textfile\" \"textfile\" \"textfile\" \"textfile\" ..."},{"path":[]},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"dataset-ids","dir":"Articles","previous_headings":"What has changed","what":"Dataset IDs","title":"Major changes to the IEU GWAS resources for 2020","text":"made new system naming datasets, datasets organised data batches. Either new datasets uploaded one time case added ieu-data batch, bulk upload case new batch created. example, ukb-bulk upload first round Neale lab UKBiobank GWAS, ukb-b IEU GWAS analysis UKBiobank data. cases, dataset numbered arbitrarily within batch. example, Locke et al 2014 BMI analysis previously known 2, now known ieu--2. backward compatibility built R packages access data, use ‘old’ ID, automatically translate new one. give warning, urge update scripts reflect change.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"authentication","dir":"Articles","previous_headings":"What has changed","what":"Authentication","title":"Major changes to the IEU GWAS resources for 2020","text":"Previously automatically asked authenticate query database, google. Now, making authentication voluntary - something start session need access specific private datasets database. vast majority use cases required. Another change R package managed authentication updated, file tokens generated slightly different. full information deal , see : https://mrcieu.github.io/ieugwasr/articles/guide.html#authentication","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"ukbiobank-data-has-been-curated","dir":"Articles","previous_headings":"What has changed","what":"UKBiobank data has been curated","title":"Major changes to the IEU GWAS resources for 2020","text":"conducted large GWAS analysis using pipeline systematically analysed every PHESANT phenotype UK Biobank. previously ~20k traits complete GWAS data, majority binary traits based numbers cases. now filtered unreliable datasets, 2514 traits remaining, binary traits removed fewer 1000 cases. Another issue combination small numbers cases allele frequency - minor allele count (MAC) particular association small lead high false positives using Bolt-LMM. remaining traits filtered retain associations MAC > 90. Document detailing investigation : https://htmlpreview.github.io/?https://raw.githubusercontent.com/MRCIEU/ukbb-gwas-analysis/master/docs/ldsc_clumped_analysis.html?token=AAOV6TBQXEXEPT7SUXXLWMC6DWP3O","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"all-data-is-now-harmonised","dir":"Articles","previous_headings":"What has changed","what":"All data is now harmonised","title":"Major changes to the IEU GWAS resources for 2020","text":"Previously data QC’d remove malformed results deposited found . now also pre-harmonising data. means alleles coded forward strand, non-effect allele always aligned human genome reference sequence B37 (effect allele non-reference allele). mean sometimes variants removed map human genome, datasets effect allele switched approximately half sites. effect allele changes course switch sign effect size, impact MR results.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"ld-reference-panel-is-now-harmonised","dir":"Articles","previous_headings":"What has changed","what":"LD reference panel is now harmonised","title":"Major changes to the IEU GWAS resources for 2020","text":"updated LD reference panel harmonised human genome build 37, consequence variants lost version previously used.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"instrument-lists-are-up-to-date","dir":"Articles","previous_headings":"What has changed","what":"Instrument lists are up-to-date","title":"Major changes to the IEU GWAS resources for 2020","text":"Previously pre-clumping tophits storing MRInstruments R package, often delay updating MRInstruments R package new datasets uploaded database. moved away model. Everything dataset pre-clumped, stored database. request default clumping values extracting tophits dataset, still fast retrieving data server, MRInstruments package. can continue use MRInstruments package GWAS hits e.g. GTEx EBI GWAS catalog.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"dbsnp-rs-ids","dir":"Articles","previous_headings":"What has changed","what":"dbSNP rs IDs","title":"Major changes to the IEU GWAS resources for 2020","text":"rs IDs mapped dbSNP build 144. Therefore, rs IDs may changed, stronger alignment across datasets.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"everything-is-faster","dir":"Articles","previous_headings":"What has changed","what":"Everything is faster","title":"Major changes to the IEU GWAS resources for 2020","text":"using Elasticsearch Neo4j Oracle Cloud Infrastructure serve data. ’s much faster. Interestingly, actually gets faster people using cache gets ‘warmed ’ requests.","code":""},{"path":[]},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"browse-available-datasets-online","dir":"Articles","previous_headings":"What is new","what":"Browse available datasets online","title":"Major changes to the IEU GWAS resources for 2020","text":"new home GWAS summary data: https://gwas.mrcieu.ac.uk/.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"chromosome-and-position","dir":"Articles","previous_headings":"What is new","what":"Chromosome and position","title":"Major changes to the IEU GWAS resources for 2020","text":"variants mapped chromosome position (hg19/build37). can query based chromosome position coordinates. means either list values, list ranges.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"indels-are-retained","dir":"Articles","previous_headings":"What is new","what":"INDELs are retained","title":"Major changes to the IEU GWAS resources for 2020","text":"Previously excluding , now retained","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"multi-allelic-variants-are-retained","dir":"Articles","previous_headings":"What is new","what":"Multi-allelic variants are retained","title":"Major changes to the IEU GWAS resources for 2020","text":"Previously excluding , now retained. warned extract variant multiple alleles may get one row variant.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"more-data","dir":"Articles","previous_headings":"What is new","what":"More data","title":"Major changes to the IEU GWAS resources for 2020","text":"Automated download EBI repository, automated upload system batch data processing system means data can added faster keep database current.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"error-messages-are-more-informative","dir":"Articles","previous_headings":"What is new","what":"Error messages are more informative","title":"Major changes to the IEU GWAS resources for 2020","text":"Previously query database failed didn’t give reason, hopefully clarity regarding happening now. can also check status server : https://api.opengwas.io/api/","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"easier-programmatic-access-to-the-database","dir":"Articles","previous_headings":"What is new","what":"Easier programmatic access to the database","title":"Major changes to the IEU GWAS resources for 2020","text":"trying make flexible possible access data. TwoSampleMR R package previously programmatic way access data, now following options: ieugwasr R package: TwoSampleMR functions access data done calling package now. simple wrapper around API controls access database. ieugwaspy python package: Similar functionality ieugwasr (construction). API: can use API directly, e.g. building services applications.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"local-ld-operations","dir":"Articles","previous_headings":"What is new","what":"Local LD operations","title":"Major changes to the IEU GWAS resources for 2020","text":"now possible perform clumping, create LD matrices, using local LD reference dataset. can download one using : https://github.com/mrcieu/gwasglue#reference-datasets, create plink format dataset e.g. larger samples different ancestries. See LD clumping functions ieugwasr package details.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"access-the-data-directly","dir":"Articles","previous_headings":"What is new","what":"Access the data directly","title":"Major changes to the IEU GWAS resources for 2020","text":"Previously data accessible database. Now data can downloaded “GWAS VCF” format https://gwas.mrcieu.ac.uk/. (IEU members can access data RDSF bluecrystal4 directly). means want perform large numerous operations, can HPC locally performant manner using data files directly. Please see gwasvcf R package work data.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"connect-the-data-to-different-analytical-tools","dir":"Articles","previous_headings":"What is new","what":"Connect the data to different analytical tools","title":"Major changes to the IEU GWAS resources for 2020","text":"Either data database, GWAS VCF files, can queried results translated formats bunch different R packages MR, colocalisation, fine mapping, etc. look gwasglue R package, see available . ’s still construction, feel free try , make suggestions, contribute code.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"key-links","dir":"Articles","previous_headings":"","what":"Key links","title":"Major changes to the IEU GWAS resources for 2020","text":"IEU GWAS database: https://gwas.mrcieu.ac.uk API IEU GWAS database: https://api.opengwas.io/api/ ieugwasr package, R access API: https://mrcieu.github.io/ieugwasr/ ieugwaspy package, python access API: https://github.com/MRCIEU/ieugwaspy/ (construction) gwasvcf package, R interface GWAS VCF files: https://mrcieu.github.io/gwasvcf/ pygwasvcf package, python interface GWAS VCF files: https://github.com/mrcieu/pygwasvcf (construction) gwasglue package, linking GWAS data various analytical methods: https://mrcieu.github.io/gwasglue/ (Functional, construction) gwas2vcf online tool, allowing users create GWAS VCF files summary data: https://github.com/MRCIEU/gwas2vcf","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"how-to-request-new-data","dir":"Articles","previous_headings":"","what":"How to request new data","title":"Major changes to the IEU GWAS resources for 2020","text":"setup github issues page : https://github.com/MRCIEU/opengwas-requests/issues Please visit make log new data requests, contribute new data.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","id":"backwards-compatibility","dir":"Articles","previous_headings":"","what":"Backwards compatibility","title":"Major changes to the IEU GWAS resources for 2020","text":"install new version TwoSampleMR, perform normal: update package just run remotes::install_github(\"MRCIEU/TwoSampleMR\") command . recommend using new version going forwards limited time enabling backwards compatibility, case middle analysis need reproduce old analysis. order use legacy version package database, install using:","code":"install.packages(\"remotes\") remotes::install_github(\"MRCIEU/TwoSampleMR\") install.packages(\"remotes\") remotes::install_github(\"MRCIEU/TwoSampleMR@0.4.26\")"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/harmonise.html","id":"introduction","dir":"Articles","previous_headings":"","what":"Introduction","title":"Harmonise data","text":"exposure data outcome data now obtained, e.g.: important harmonise effects. means effect SNP exposure effect SNP outcome must correspond allele. Note: IEU GWAS database contains data already harmonised, meaning non-effect allele aligned human genome reference sequence (build 37). ’s still recommended harmonise, principle everything forward strand effect alleles always relating allele. discrepancies arise multi-allelic variants represented different bi-allelic variants different studies. harmonise exposure outcome data, following: creates new data frame exposure data outcome data combined. 3 exposure traits 3 outcome traits 9 sets harmonisations performed - harmonising SNP effects exposure trait 1 outcome trait 1; exposure trait 1 outcome trait 2; .","code":"bmi_exp_dat <- extract_instruments(outcomes = 'ieu-a-2') chd_out_dat <- extract_outcome_data(snps = bmi_exp_dat$SNP, outcomes = 'ieu-a-7') dat <- harmonise_data( exposure_dat = bmi_exp_dat, outcome_dat = chd_out_dat ) #> Harmonising Body mass index || id:ieu-a-2 (ieu-a-2) and Coronary heart disease || id:ieu-a-7 (ieu-a-7)"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/harmonise.html","id":"dealing-with-strand-issues","dir":"Articles","previous_headings":"","what":"Dealing with strand issues","title":"Harmonise data","text":"Recent GWASs typically present effects SNP reference allele forward strand. reference panels updated forward strand sometimes changes, GWASs years ago aren’t guaranteed using forward strand conventions. examples shown :","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/harmonise.html","id":"correct-unambigious","dir":"Articles","previous_headings":"Dealing with strand issues","what":"Correct, unambigious","title":"Harmonise data","text":"effect allele exposure outcome ","code":"exposure effect = 0.5 effect allele = A other allele = G outcome effect = 0.05 effect allele = A other allele = G"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/harmonise.html","id":"incorrect-reference-unambigious","dir":"Articles","previous_headings":"Dealing with strand issues","what":"Incorrect reference, unambigious","title":"Harmonise data","text":"outcome GWAS presenting effect alternate allele reverse strand. need flip outcome effect 0.05 correspond allele exposure GWAS forward strand.","code":"exposure effect = 0.5 effect allele = A other allele = G outcome effect = -0.05 effect allele = C other allele = T"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/harmonise.html","id":"ambiguous","dir":"Articles","previous_headings":"Dealing with strand issues","what":"Ambiguous","title":"Harmonise data","text":"alleles correspond SNP, SNP discarded analysis.","code":"exposure effect = 0.5 effect allele = A other allele = G outcome effect = -0.05 effect allele = A other allele = C"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/harmonise.html","id":"palindromic-snp-inferrable","dir":"Articles","previous_headings":"Dealing with strand issues","what":"Palindromic SNP, inferrable","title":"Harmonise data","text":"alleles correspond, palindromic SNP, alleles forward strand reverse strand (/T forward T/reverse). However, allele frequency effect allele gives us information - outcome effect allele () forward strand expect low allele frequency, given high frequency (0.91) infer outcome GWAS presenting effect reverse strand alternative allele. flip effect 0.05 outcome GWAS.","code":"exposure effect = 0.5 effect allele = A other allele = T effect allele frequency = 0.11 outcome effect = -0.05 effect allele = A other allele = T effect allele frequency = 0.91"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/harmonise.html","id":"palindromic-snp-not-inferrable","dir":"Articles","previous_headings":"Dealing with strand issues","what":"Palindromic SNP, not inferrable","title":"Harmonise data","text":"similar , except allele frequency longer gives us information strand. discard SNP. done palindromic SNPs minor allele frequency 0.42.","code":"exposure effect = 0.5 effect allele = A other allele = T effect allele frequency = 0.50 outcome effect = -0.05 effect allele = A other allele = T effect allele frequency = 0.50"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/harmonise.html","id":"options","dir":"Articles","previous_headings":"Dealing with strand issues","what":"Options","title":"Harmonise data","text":"three options harmonising data. Assume alleles presented forward strand Try infer forward strand alleles using allele frequency information Correct strand non-palindromic SNPs, drop palindromic SNPs default, harmonise_data function uses option 2, can modified using action argument, e.g. harmonise_data(exposure_dat, outcome_dat, action = 3).","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/harmonise.html","id":"drop-duplicate-exposure-outcome-summary-sets","dir":"Articles","previous_headings":"","what":"Drop duplicate exposure-outcome summary sets","title":"Harmonise data","text":"data harmonisation, users may find dataset contains duplicate exposure-outcome summary sets. can arise, example, GWAS consortium released multiple results separate GWAS analyses trait. example, multiple GWAS summary datasets body mass index coronary heart disease: therefore multiple potential combinations body mass index coronary heart disease, likely lead duplicate MR analyses. recommend users prune datasets exposure-outcome combination highested expected power retained. can done selecting exposure-outcome summary set largest sample size outcome, using power_prune function: drops duplicate exposure-outcome sets smaller outcome sample size (number cases binary outcomes). Remaining duplicates dropped basis exposure sample size. However, large number SNPs available instrument exposure, outcome GWAS better SNP coverage may provide better power outcome GWAS larger sample size. can occur, example, larger outcome GWAS used targeted genotyping array. instances, may better prune studies basis instrument strength (.e. variation exposure explained instrumental SNPs) well sample size. can done setting method argument 2: procedure drops duplicate exposure-outcome sets basis instrument strength sample size, assumes SNP-exposure effects correspond continuous trait normal distribution (.e. exposure binary). SNP-outcome effects can correspond either binary continuous trait (default behaviour assume binary distribution). exposure binary method 1 used.","code":"ao <- available_outcomes() ao[ao$trait == \"Body mass index\", c(\"trait\", \"id\", \"pmid\", \"author\", \"sample_size\", \"nsnp\")] #> trait id pmid author #> 3958 Body mass index ebi-a-GCST90103751 35051171 Wong HS #> 4015 Body mass index ebi-a-GCST90095039 35399580 Fernndez-Rhodes L #> 4020 Body mass index ebi-a-GCST90095034 35399580 Fernndez-Rhodes L #> 6032 Body mass index ebi-a-GCST90029007 29892013 Loh PR #> 6821 Body mass index ebi-a-GCST90025994 34226706 Barton AR #> 7045 Body mass index ebi-a-GCST90018947 34594039 Sakaue S #> 7259 Body mass index ebi-a-GCST90018727 34594039 Sakaue S #> 10738 Body mass index ieu-a-94 23754948 Randall JC #> 12717 Body mass index ieu-a-2 25673413 Locke AE #> 14254 Body mass index ieu-a-95 23754948 Randall JC #> 16676 Body mass index ieu-a-974 25673413 Locke AE #> 19343 Body mass index bbj-a-3 28892062 Ishigaki K #> 26475 Body mass index ebi-a-GCST006368 30108127 Hoffmann TJ #> 28065 Body mass index ieu-b-4815 NA Howe LJ #> 28419 Body mass index bbj-a-2 28892062 Ishigaki K #> 32371 Body mass index ieu-b-4816 NA Howe LJ #> 33869 Body mass index ieu-a-785 25673413 Locke AE #> 39217 Body mass index ebi-a-GCST002783 25673413 Locke AE #> 40065 Body mass index bbj-a-1 28892062 Ishigaki K #> 43262 Body mass index ebi-a-GCST004904 28892062 Akiyama M #> 43743 Body mass index ebi-a-GCST006802 26961502 Wood AR #> 47894 Body mass index ieu-a-835 25673413 Locke AE #> 48917 Body mass index ebi-a-GCST008025 31217584 Wojcik GL #> 49208 Body mass index ieu-a-1089 26961502 Wood #> sample_size nsnp #> 3958 21930 6370138 #> 4015 330793 2401077 #> 4020 56161 8764141 #> 6032 532396 11973091 #> 6821 457756 4238669 #> 7045 359983 19066885 #> 7259 163835 12502877 #> 10738 60586 2736876 #> 12717 339224 2555511 #> 14254 73137 2736876 #> 16676 171977 2494613 #> 19343 72390 6108953 #> 26475 315347 27854527 #> 28065 51852 NA #> 28419 85894 6108953 #> 32371 99998 7191606 #> 33869 152893 2477659 #> 39217 236781 2529499 #> 40065 158284 5961600 #> 43262 158284 5952516 #> 43743 119688 8580466 #> 47894 322154 2554668 #> 48917 21955 34343880 #> 49208 120286 8654252 ao[ao$trait == \"Coronary heart disease\", c(\"trait\", \"id\", \"pmid\", \"author\", \"ncase\", \"ncontrol\", \"nsnp\")] #> trait id pmid author ncase #> 14897 Coronary heart disease ieu-a-7 26343387 Nikpay 60801 #> 23614 Coronary heart disease ieu-a-9 23202125 Deloukas 63746 #> 27414 Coronary heart disease ebi-a-GCST000998 21378990 Schunkert H 22233 #> 38602 Coronary heart disease ieu-a-8 21378990 Schunkert H 22233 #> 45294 Coronary heart disease ieu-a-6 21378988 Peden 15420 #> ncontrol nsnp #> 14897 123504 9455779 #> 23614 130681 79129 #> 27414 64762 2415020 #> 38602 64762 2420361 #> 45294 15062 540233 dat <- power_prune(dat, method = 1, dist.outcome = \"binary\") dat <- power_prune(dat, method = 2, dist.outcome = \"binary\")"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/introduction.html","id":"background","dir":"Articles","previous_headings":"","what":"Background","title":"Introduction","text":"Two sample Mendelian randomisation (2SMR) method estimate causal effect exposure outcome using summary statistics genome wide association studies (GWAS). Though conceptually straightforward, number steps required perform analysis properly, can cumbersome. TwoSampleMR package aims make easy combining three important components data management harmonisation statistical routines estimate causal effects connection large repository actual GWAS summary statistics needed perform analyses. general principles (G. Davey Smith Ebrahim 2003; George Davey Smith Hemani 2014), statistical methods (Pierce Burgess 2013; Bowden, Davey Smith, Burgess 2015) can found elsewhere, just outline use R package. package uses ieugwasr package connect database thousands complete GWAS summary data.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/introduction.html","id":"installation","dir":"Articles","previous_headings":"","what":"Installation","title":"Introduction","text":"install directly GitHub repository following: don’t remotes package install CRAN using install.packages(\"remotes\").","code":"library(remotes) install_github(\"MRCIEU/TwoSampleMR\")"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/introduction.html","id":"overview","dir":"Articles","previous_headings":"","what":"Overview","title":"Introduction","text":"workflow performing MR follows: Select instruments exposure (perform LD clumping necessary) Extract instruments IEU GWAS database outcomes interest Harmonise effect sizes instruments exposures outcomes reference allele Perform MR analysis, sensitivity analyses, create plots, compile reports diagrammatic overview shown : basic analysis, e.g. causal effect body mass index coronary heart disease, looks like : step documented pages documentation.","code":"library(TwoSampleMR) # List available GWASs ao <- available_outcomes() # Get instruments exposure_dat <- extract_instruments(\"ieu-a-2\") # Get effects of instruments on outcome outcome_dat <- extract_outcome_data(snps=exposure_dat$SNP, outcomes = \"ieu-a-7\") # Harmonise the exposure and outcome data dat <- harmonise_data(exposure_dat, outcome_dat) # Perform MR res <- mr(dat)"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/introduction.html","id":"authentication","dir":"Articles","previous_headings":"","what":"Authentication","title":"Introduction","text":"statistical methods TwoSampleMR can used data, number functions connect OpenGWAS database data extraction. OpenGWAS data access functions require authentication. Authentication changing main differences : Authentication required queries OpenGWAS everyone (.e. anonymous usage) longer using Google Oauth2. replaced simple API key system. Detailed information given : https://mrcieu.github.io/ieugwasr/articles/guide.html#authentication.","code":""},{"path":[]},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/outcome.html","id":"available-studies-in-ieu-gwas-database","dir":"Articles","previous_headings":"","what":"Available studies in IEU GWAS database","title":"Outcome data","text":"IEU GWAS database (IGD) contains complete GWAS summary statistics large number studies. can browse : https://gwas.mrcieu.ac.uk/ obtain details available GWASs programmatically following: information authentication see https://mrcieu.github.io/ieugwasr/articles/guide.html#authentication. available_outcomes function returns table available studies database. study unique ID. e.g.","code":"ao <- available_outcomes() head(ao) #> id trait ncase group_name year author consortium #> 1 ieu-b-5103 Schizophrenia 1234 public 2022 Trubetskoy V PGC #> 2 ieu-b-5102 Schizophrenia 52017 public 2022 Trubetskoy V PGC #> 3 ieu-b-5101 Schizophrenia 12305 public 2022 Trubetskoy V PGC #> 4 ieu-b-5100 Schizophrenia 64322 public 2022 Trubetskoy V PGC #> 5 ieu-b-5099 Schizophrenia 76755 public 2022 Trubetskoy V PGC #> 6 ieu-b-5098 Schizophrenia 5998 public 2022 Trubetskoy V PGC #> sex pmid population unit #> 1 Males and Females 35396580 Hispanic or Latin American logOR #> 2 Males and Females 35396580 European logOR #> 3 Males and Females 35396580 East Asian logOR #> 4 Males and Females 35396580 Mixed logOR #> 5 Males and Females 35396580 Mixed logOR #> 6 Males and Females 35396580 African American or Afro-Caribbean logOR #> sample_size build ncontrol category subcategory ontology #> 1 4324 HG19/GRCh37 3090 Disease NA MONDO:0005090 #> 2 127906 HG19/GRCh37 75889 Disease NA MONDO:0005090 #> 3 27363 HG19/GRCh37 15058 Disease NA MONDO:0005090 #> 4 155269 HG19/GRCh37 90947 Disease NA MONDO:0005090 #> 5 320404 HG19/GRCh37 243649 Disease NA MONDO:0005090 #> 6 9824 HG19/GRCh37 3826 Disease NA MONDO:0005090 #> note mr #> 1 NA #> 2 NA #> 3 NA #> 4 Core - East Asian and European meta analysis NA #> 5 Primary - meta analysis of Eur, East Asian, African American and Latino NA #> 6 NA #> nsnp doi coverage study_design priority sd #> 1 NA NA NA #> 2 NA NA NA #> 3 NA NA NA #> 4 NA NA NA #> 5 NA NA NA #> 6 NA NA NA head(subset(ao, select = c(trait, id))) #> trait id #> 1 Schizophrenia ieu-b-5103 #> 2 Schizophrenia ieu-b-5102 #> 3 Schizophrenia ieu-b-5101 #> 4 Schizophrenia ieu-b-5100 #> 5 Schizophrenia ieu-b-5099 #> 6 Schizophrenia ieu-b-5098"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/outcome.html","id":"extracting-particular-snps-from-particular-studies","dir":"Articles","previous_headings":"","what":"Extracting particular SNPs from particular studies","title":"Outcome data","text":"want perform MR BMI coronary heart disease, need identify SNPs influence BMI, extract SNPs GWAS coronary heart disease. Let’s get Locke et al 2014 instruments BMI example: now need find suitable GWAS coronary heart disease. can search available studies: recent CARDIOGRAM GWAS ID number ieu--7. can extract BMI SNPs GWAS follows: extract_outcome_data() function flexible. snps argument requires array rsIDs, outcomes argument can vector outcomes, e.g. extract two SNPs outcomes ieu--2 ieu--7.","code":"bmi_exp_dat <- extract_instruments(outcomes = 'ieu-a-2') head(bmi_exp_dat) #> pval.exposure samplesize.exposure chr.exposure se.exposure beta.exposure #> 1 2.18198e-08 339152 1 0.0030 -0.0168 #> 2 4.56773e-11 339065 1 0.0031 0.0201 #> 3 5.05941e-14 313621 1 0.0087 0.0659 #> 4 5.45205e-10 338768 1 0.0029 0.0181 #> 5 1.88018e-28 338123 1 0.0030 0.0331 #> 6 2.28718e-40 339078 1 0.0037 0.0497 #> pos.exposure id.exposure SNP effect_allele.exposure #> 1 47684677 ieu-a-2 rs977747 G #> 2 78048331 ieu-a-2 rs17381664 C #> 3 110082886 ieu-a-2 rs7550711 T #> 4 201784287 ieu-a-2 rs2820292 C #> 5 72837239 ieu-a-2 rs7531118 C #> 6 177889480 ieu-a-2 rs543874 G #> other_allele.exposure eaf.exposure exposure #> 1 T 0.5333 Body mass index || id:ieu-a-2 #> 2 T 0.4250 Body mass index || id:ieu-a-2 #> 3 C 0.0339 Body mass index || id:ieu-a-2 #> 4 A 0.5083 Body mass index || id:ieu-a-2 #> 5 T 0.6083 Body mass index || id:ieu-a-2 #> 6 A 0.2667 Body mass index || id:ieu-a-2 #> mr_keep.exposure pval_origin.exposure data_source.exposure #> 1 TRUE reported igd #> 2 TRUE reported igd #> 3 TRUE reported igd #> 4 TRUE reported igd #> 5 TRUE reported igd #> 6 TRUE reported igd ao[grepl(\"heart disease\", ao$trait), ] #> id #> 7958 finn-b-I9_CHD #> 10829 ukb-b-3983 #> 12268 ukb-e-I25_AFR #> 14221 ukb-b-2205 #> 14897 ieu-a-7 #> 15028 finn-b-I9_SECONDRIGHT_EXNONE #> 16883 ukb-b-7436 #> 18046 ukb-a-534 #> 18048 ukb-e-I25_CSA #> 20207 finn-b-I9_OTHHEART #> 22249 finn-b-I9_VHD_EXNONE #> 22725 finn-b-I9_PULMHEART #> 23614 ieu-a-9 #> 24603 finn-b-FG_OTHHEART #> 27414 ebi-a-GCST000998 #> 33264 finn-b-FG_PULMHEART #> 35220 ukb-d-I9_CHD #> 35231 finn-b-I9_OTHILLHEART #> 36931 ukb-b-8184 #> 37302 finn-b-I9_OTHILLHEART_EXNONE #> 37894 ukb-b-1668 #> 38319 finn-b-I9_IHD #> 38448 finn-b-I9_RHEUFEV #> 38602 ieu-a-8 #> 41994 finn-b-I9_ISCHHEART #> 42095 ukb-d-I9_IHD #> 42882 finn-b-I9_SECONDRIGHT #> 43747 ukb-d-I9_CHD_NOREV #> 45294 ieu-a-6 #> 46126 finn-b-I9_VHD #> 46689 ukb-b-16606 #> trait #> 7958 Major coronary heart disease event #> 10829 Diagnoses - main ICD10: I25.9 Chronic ischaemic heart disease, unspecified #> 12268 I25 Chronic ischaemic heart disease #> 14221 Diagnoses - secondary ICD10: Z82.4 Family history of ischaemic heart disease and other diseases of the circulatory system #> 14897 Coronary heart disease #> 15028 Secondary right heart disease (no controls excluded) #> 16883 Diagnoses - secondary ICD10: I25.1 Atherosclerotic heart disease #> 18046 Diagnoses - main ICD10: I25 Chronic ischaemic heart disease #> 18048 I25 Chronic ischaemic heart disease #> 20207 Other heart diseases (I9_OTHHEART) #> 22249 Valvular heart disease including rheumatic fever (no controls excluded) #> 22725 Pulmonary heart disease, diseases of pulmonary circulation #> 23614 Coronary heart disease #> 24603 Other heart diseases (FG_OTHHEART) #> 27414 Coronary heart disease #> 33264 Pulmonary heart disease #> 35220 Major coronary heart disease event #> 35231 Other or ill-defined heart diseases #> 36931 Diagnoses - secondary ICD10: I25.9 Chronic ischaemic heart disease, unspecified #> 37302 Other or ill-defined heart diseases (no controls excluded) #> 37894 Diagnoses - main ICD10: I25.1 Atherosclerotic heart disease #> 38319 Ischaemic heart disease, wide definition #> 38448 Rheumatic fever incl heart disease #> 38602 Coronary heart disease #> 41994 Ischemic heart diseases #> 42095 Ischaemic heart disease, wide definition #> 42882 Secondary right heart disease #> 43747 Major coronary heart disease event excluding revascularizations #> 45294 Coronary heart disease #> 46126 Valvular heart disease including rheumatic fever #> 46689 Diagnoses - secondary ICD10: I25.8 Other forms of chronic ischaemic heart disease #> ncase group_name year author consortium sex #> 7958 21012 public 2021 NA NA Males and Females #> 10829 1195 public 2018 Ben Elsworth MRC-IEU Males and Females #> 12268 302 public 2020 Pan-UKB team NA Males and Females #> 14221 9330 public 2018 Ben Elsworth MRC-IEU Males and Females #> 14897 60801 public 2015 Nikpay CARDIoGRAMplusC4D Males and Females #> 15028 428 public 2021 NA NA Males and Females #> 16883 5771 public 2018 Ben Elsworth MRC-IEU Males and Females #> 18046 8755 public 2017 Neale Neale Lab Males and Females #> 18048 1205 public 2020 Pan-UKB team NA Males and Females #> 20207 62081 public 2021 NA NA Males and Females #> 22249 38209 public 2021 NA NA Males and Females #> 22725 4564 public 2021 NA NA Males and Females #> 23614 63746 public 2013 Deloukas CARDIoGRAMplusC4D Males and Females #> 24603 58173 public 2021 NA NA Males and Females #> 27414 22233 public 2011 Schunkert H NA NA #> 33264 4185 public 2021 NA NA Males and Females #> 35220 10157 public 2018 Neale lab NA Males and Females #> 35231 713 public 2021 NA NA Males and Females #> 36931 5861 public 2018 Ben Elsworth MRC-IEU Males and Females #> 37302 713 public 2021 NA NA Males and Females #> 37894 12171 public 2018 Ben Elsworth MRC-IEU Males and Females #> 38319 31640 public 2021 NA NA Males and Females #> 38448 573 public 2021 NA NA Males and Females #> 38602 22233 public 2011 Schunkert H CARDIoGRAM Males and Females #> 41994 30952 public 2021 NA NA Males and Females #> 42095 20857 public 2018 Neale lab NA Males and Females #> 42882 428 public 2021 NA NA Males and Females #> 43747 10157 public 2018 Neale lab NA Males and Females #> 45294 15420 public 2011 Peden C4D Males and Females #> 46126 38209 public 2021 NA NA Males and Females #> 46689 5738 public 2018 Ben Elsworth MRC-IEU Males and Females #> pmid population unit sample_size #> 7958 NA European NA NA #> 10829 NA European SD 463010 #> 12268 NA African American or Afro-Caribbean NA 6636 #> 14221 NA European SD 463010 #> 14897 26343387 Mixed log odds 184305 #> 15028 NA European NA NA #> 16883 NA European SD 463010 #> 18046 NA European SD 337199 #> 18048 NA South Asian NA 8876 #> 20207 NA European NA NA #> 22249 NA European NA NA #> 22725 NA European NA NA #> 23614 23202125 Mixed log odds 194427 #> 24603 NA European NA NA #> 27414 21378990 European logOR 86995 #> 33264 NA European NA NA #> 35220 NA European NA 361194 #> 35231 NA European NA NA #> 36931 NA European SD 463010 #> 37302 NA European NA NA #> 37894 NA European SD 463010 #> 38319 NA European NA NA #> 38448 NA European NA NA #> 38602 21378990 European log odds 86995 #> 41994 NA European NA NA #> 42095 NA European NA 361194 #> 42882 NA European NA NA #> 43747 NA European NA 361194 #> 45294 21378988 Mixed log odds 30482 #> 46126 NA European NA NA #> 46689 NA European SD 463010 #> build ncontrol category subcategory ontology #> 7958 HG19/GRCh37 197780 Binary NA NA #> 10829 HG19/GRCh37 461815 Binary NA NA #> 12268 HG19/GRCh37 6334 Binary NA NA #> 14221 HG19/GRCh37 453680 Binary NA NA #> 14897 HG19/GRCh37 123504 Disease Cardiovascular NA #> 15028 HG19/GRCh37 218364 Binary NA NA #> 16883 HG19/GRCh37 457239 Binary NA NA #> 18046 HG19/GRCh37 328444 NA NA NA #> 18048 HG19/GRCh37 7671 Binary NA NA #> 20207 HG19/GRCh37 156711 Binary NA NA #> 22249 HG19/GRCh37 180583 Binary NA NA #> 22725 HG19/GRCh37 214228 Binary NA NA #> 23614 HG19/GRCh37 130681 Disease Cardiovascular NA #> 24603 HG19/GRCh37 160619 Binary NA NA #> 27414 HG19/GRCh37 64762 NA NA NA #> 33264 HG19/GRCh37 214607 Binary NA NA #> 35220 HG19/GRCh37 351037 Binary NA NA #> 35231 HG19/GRCh37 156711 Binary NA NA #> 36931 HG19/GRCh37 457149 Binary NA NA #> 37302 HG19/GRCh37 218079 Binary NA NA #> 37894 HG19/GRCh37 450839 Binary NA NA #> 38319 HG19/GRCh37 187152 Binary NA NA #> 38448 HG19/GRCh37 218219 Binary NA NA #> 38602 HG19/GRCh37 64762 Disease Cardiovascular NA #> 41994 HG19/GRCh37 187840 Binary NA NA #> 42095 HG19/GRCh37 340337 Binary NA NA #> 42882 HG19/GRCh37 214228 Binary NA NA #> 43747 HG19/GRCh37 351037 Binary NA NA #> 45294 HG19/GRCh37 15062 Disease Cardiovascular NA #> 46126 HG19/GRCh37 156711 Binary NA NA #> 46689 HG19/GRCh37 457272 Binary NA NA #> note #> 7958 I9_CHD #> 10829 41202#I259: Output from GWAS pipeline using Phesant derived variables from UKBiobank #> 12268 NA #> 14221 41204#Z824: Output from GWAS pipeline using Phesant derived variables from UKBiobank #> 14897 #> 15028 I9_SECONDRIGHT_EXNONE #> 16883 41204#I251: Output from GWAS pipeline using Phesant derived variables from UKBiobank #> 18046 NA #> 18048 NA #> 20207 I9_OTHHEART #> 22249 I9_VHD_EXNONE #> 22725 I9_PULMHEART #> 23614 #> 24603 FG_OTHHEART #> 27414 NA #> 33264 FG_PULMHEART #> 35220 NA #> 35231 I9_OTHILLHEART #> 36931 41204#I259: Output from GWAS pipeline using Phesant derived variables from UKBiobank #> 37302 I9_OTHILLHEART_EXNONE #> 37894 41202#I251: Output from GWAS pipeline using Phesant derived variables from UKBiobank #> 38319 I9_IHD #> 38448 I9_RHEUFEV #> 38602 #> 41994 I9_ISCHHEART #> 42095 NA #> 42882 I9_SECONDRIGHT #> 43747 NA #> 45294 #> 46126 I9_VHD #> 46689 41204#I258: Output from GWAS pipeline using Phesant derived variables from UKBiobank #> mr nsnp doi coverage study_design priority sd #> 7958 1 16380466 0 NA #> 10829 1 9851867 1 NA #> 12268 1 15478580 0 NA #> 14221 1 9851867 1 NA #> 14897 1 9455779 1 NA #> 15028 1 16380466 0 NA #> 16883 1 9851867 1 NA #> 18046 1 10894596 1 NA #> 18048 1 9811287 0 NA #> 20207 1 16380466 0 NA #> 22249 1 16380466 0 NA #> 22725 1 16380466 0 NA #> 23614 1 79129 1 NA #> 24603 1 16380466 0 NA #> 27414 1 2415020 0 NA #> 33264 1 16380466 0 NA #> 35220 1 13295130 0 NA #> 35231 1 16380177 0 NA #> 36931 1 9851867 1 NA #> 37302 1 16380466 0 NA #> 37894 1 9851867 1 NA #> 38319 1 16380466 0 NA #> 38448 1 16380466 0 NA #> 38602 1 2420361 2 NA #> 41994 1 16380466 0 NA #> 42095 1 13586589 0 NA #> 42882 1 16380459 0 NA #> 43747 1 13295130 0 NA #> 45294 1 540233 3 NA #> 46126 1 16380358 0 NA #> 46689 1 9851867 1 NA chd_out_dat1 <- extract_outcome_data( snps = bmi_exp_dat$SNP, outcomes = 'ieu-a-7' ) chd_out_dat2 <- extract_outcome_data( snps = c(\"rs234\", \"rs17097147\"), outcomes = c('ieu-a-2', 'ieu-a-7') )"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/outcome.html","id":"ld-proxies","dir":"Articles","previous_headings":"","what":"LD proxies","title":"Outcome data","text":"default particular requested SNP present outcome GWAS SNP (proxy) LD requested SNP (target) searched instead. LD proxies defined using 1000 genomes European sample data. effect proxy SNP outcome returned, along proxy SNP, effect allele proxy SNP, corresponding allele (phase) target SNP. parameters handling LD proxies follows: proxies = TRUE FALSE (TRUE default) rsq = numeric value minimum rsq find proxy. Default 0.8, minimum 0.6 palindromes = Allow palindromic SNPs? Default 1 (yes) maf_threshold = palindromes allowed maximum minor allele frequency palindromes allowed? Default 0.3.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/outcome.html","id":"using-local-gwas-summary-data","dir":"Articles","previous_headings":"","what":"Using local GWAS summary data","title":"Outcome data","text":"GWAS summary data present IEU GWAS database, can still used perform analysis. Supposing GWAS summary file called “gwas_summary.csv” e.g. 2 million rows looks like : extract exposure SNPs data, use following command: returns outcome data frame SNPs requested (SNPs present “gwas_summary.csv” file).","code":"rsid,effect,SE,a1,a2,a1_freq,p-value,Units,Gene,n rs10767664,0.19,0.030612245,A,T,0.78,5.00E-26,kg/m2,BDNF,225238 rs13078807,0.1,0.020408163,G,A,0.2,4.00E-11,kg/m2,CADM2,221431 rs1514175,0.07,0.020408163,A,G,0.43,8.00E-14,kg/m2,TNNI3K,207641 rs1558902,0.39,0.020408163,A,T,0.42,5.00E-120,kg/m2,FTO,222476 ... ... outcome_dat <- read_outcome_data( snps = bmi_exp_dat$SNP, filename = \"gwas_summary.csv\", sep = \",\", snp_col = \"rsid\", beta_col = \"effect\", se_col = \"SE\", effect_allele_col = \"a1\", other_allele_col = \"a2\", eaf_col = \"a1_freq\", pval_col = \"p-value\", units_col = \"Units\", gene_col = \"Gene\", samplesize_col = \"n\" )"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/outcome.html","id":"outcome-data-format","dir":"Articles","previous_headings":"","what":"Outcome data format","title":"Outcome data","text":"extract_outcome_data function returns table SNP effects requested SNPs requested outcomes. format data similar exposure data format, except main columns follows: SNP beta.outcome se.outcome samplesize.outcome ncase.outcome ncontrol.outcome pval.outcome eaf.outcome effect_allele.outcom other_allele.outcome units.outcome outcome consortium.outcome year.outcome pmid.outcome id.outcome originalname.outcome proxy.outcome target_snp.outcome proxy_snp.outcome target_a1.outcome target_a2.outcome proxy_a1.outcome proxy_a2.outcome mr_keep.outcome data_source.outcome","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/outcome.html","id":"more-advanced-use-of-local-data","dir":"Articles","previous_headings":"","what":"More advanced use of local data","title":"Outcome data","text":"developed summary data format called “GWAS VCF”, designed store GWAS results strict performant way. possible use format TwoSampleMR package. Going avenue also allows use LD proxy functionality using LD reference files (ones provide). details, see package explains format query R: https://github.com/mrcieu/gwasvcf package connect data packages including TwoSampleMR https://github.com/MRCIEU/gwasglue","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"introduction","dir":"Articles","previous_headings":"","what":"Introduction","title":"Perform MR","text":"Let’s continue example BMI CHD: exposure outcome data harmonised, effects standard errors instrument SNP available exposure outcome traits. can use information perform Mendelian randomisation. , simply run: returns data frame estimates causal effect exposure outcome range different MR methods. multiple exposures multiple outcomes dat, mr() function perform MR method combination exposure-outcome traits.","code":"bmi_exp_dat <- extract_instruments(outcomes = 'ieu-a-2') chd_out_dat <- extract_outcome_data(snps = bmi_exp_dat$SNP, outcomes = 'ieu-a-7') dat <- harmonise_data(bmi_exp_dat, chd_out_dat) #> Harmonising Body mass index || id:ieu-a-2 (ieu-a-2) and Coronary heart disease || id:ieu-a-7 (ieu-a-7) res <- mr(dat) #> Analysing 'ieu-a-2' on 'ieu-a-7' res #> id.exposure id.outcome outcome #> 1 ieu-a-2 ieu-a-7 Coronary heart disease || id:ieu-a-7 #> 2 ieu-a-2 ieu-a-7 Coronary heart disease || id:ieu-a-7 #> 3 ieu-a-2 ieu-a-7 Coronary heart disease || id:ieu-a-7 #> 4 ieu-a-2 ieu-a-7 Coronary heart disease || id:ieu-a-7 #> 5 ieu-a-2 ieu-a-7 Coronary heart disease || id:ieu-a-7 #> exposure method nsnp b #> 1 Body mass index || id:ieu-a-2 MR Egger 79 0.5024935 #> 2 Body mass index || id:ieu-a-2 Weighted median 79 0.3870065 #> 3 Body mass index || id:ieu-a-2 Inverse variance weighted 79 0.4459091 #> 4 Body mass index || id:ieu-a-2 Simple mode 79 0.3401554 #> 5 Body mass index || id:ieu-a-2 Weighted mode 79 0.3790910 #> se pval #> 1 0.14396056 8.012590e-04 #> 2 0.07639889 4.071091e-07 #> 3 0.05898302 4.032020e-14 #> 4 0.15001315 2.612742e-02 #> 5 0.10221374 3.881092e-04"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"mr-methods","dir":"Articles","previous_headings":"","what":"MR methods","title":"Perform MR","text":"list available MR methods can obtained: perform , can specified mr() function, e.g. perform MR Egger regression Inverse variance weighted methods, default, methods labelled TRUE use_by_default column used mr() function.","code":"mr_method_list() #> obj #> 1 mr_wald_ratio #> 2 mr_two_sample_ml #> 3 mr_egger_regression #> 4 mr_egger_regression_bootstrap #> 5 mr_simple_median #> 6 mr_weighted_median #> 7 mr_penalised_weighted_median #> 8 mr_ivw #> 9 mr_ivw_radial #> 10 mr_ivw_mre #> 11 mr_ivw_fe #> 12 mr_simple_mode #> 13 mr_weighted_mode #> 14 mr_weighted_mode_nome #> 15 mr_simple_mode_nome #> 16 mr_raps #> 17 mr_sign #> 18 mr_uwr #> name PubmedID #> 1 Wald ratio #> 2 Maximum likelihood #> 3 MR Egger 26050253 #> 4 MR Egger (bootstrap) 26050253 #> 5 Simple median #> 6 Weighted median #> 7 Penalised weighted median #> 8 Inverse variance weighted #> 9 IVW radial #> 10 Inverse variance weighted (multiplicative random effects) #> 11 Inverse variance weighted (fixed effects) #> 12 Simple mode #> 13 Weighted mode #> 14 Weighted mode (NOME) #> 15 Simple mode (NOME) #> 16 Robust adjusted profile score (RAPS) #> 17 Sign concordance test #> 18 Unweighted regression #> Description use_by_default #> 1 TRUE #> 2 FALSE #> 3 TRUE #> 4 FALSE #> 5 FALSE #> 6 TRUE #> 7 FALSE #> 8 TRUE #> 9 FALSE #> 10 FALSE #> 11 FALSE #> 12 TRUE #> 13 TRUE #> 14 FALSE #> 15 FALSE #> 16 FALSE #> 17 Tests for concordance of signs between exposure and outcome FALSE #> 18 Doesn't use any weights FALSE #> heterogeneity_test #> 1 FALSE #> 2 TRUE #> 3 TRUE #> 4 FALSE #> 5 FALSE #> 6 FALSE #> 7 FALSE #> 8 TRUE #> 9 TRUE #> 10 FALSE #> 11 FALSE #> 12 FALSE #> 13 FALSE #> 14 FALSE #> 15 FALSE #> 16 FALSE #> 17 FALSE #> 18 TRUE mr(dat, method_list = c(\"mr_egger_regression\", \"mr_ivw\")) #> Analysing 'ieu-a-2' on 'ieu-a-7' #> id.exposure id.outcome outcome #> 1 ieu-a-2 ieu-a-7 Coronary heart disease || id:ieu-a-7 #> 2 ieu-a-2 ieu-a-7 Coronary heart disease || id:ieu-a-7 #> exposure method nsnp b #> 1 Body mass index || id:ieu-a-2 MR Egger 79 0.5024935 #> 2 Body mass index || id:ieu-a-2 Inverse variance weighted 79 0.4459091 #> se pval #> 1 0.14396056 8.01259e-04 #> 2 0.05898302 4.03202e-14"},{"path":[]},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"heterogeneity-statistics","dir":"Articles","previous_headings":"Sensitivity analyses","what":"Heterogeneity statistics","title":"Perform MR","text":"MR methods can also perform tests heterogeneity. obtain statistics: mr() function, mr_heterogeneity() function can take argument perform heterogeneity tests using specified methods, e.g.","code":"mr_heterogeneity(dat) #> id.exposure id.outcome outcome #> 1 ieu-a-2 ieu-a-7 Coronary heart disease || id:ieu-a-7 #> 2 ieu-a-2 ieu-a-7 Coronary heart disease || id:ieu-a-7 #> exposure method Q Q_df #> 1 Body mass index || id:ieu-a-2 MR Egger 143.3046 77 #> 2 Body mass index || id:ieu-a-2 Inverse variance weighted 143.6508 78 #> Q_pval #> 1 6.841585e-06 #> 2 8.728420e-06 mr_heterogeneity(dat, method_list = c(\"mr_egger_regression\", \"mr_ivw\")) #> id.exposure id.outcome outcome #> 1 ieu-a-2 ieu-a-7 Coronary heart disease || id:ieu-a-7 #> 2 ieu-a-2 ieu-a-7 Coronary heart disease || id:ieu-a-7 #> exposure method Q Q_df #> 1 Body mass index || id:ieu-a-2 MR Egger 143.3046 77 #> 2 Body mass index || id:ieu-a-2 Inverse variance weighted 143.6508 78 #> Q_pval #> 1 6.841585e-06 #> 2 8.728420e-06"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"horizontal-pleiotropy","dir":"Articles","previous_headings":"Sensitivity analyses","what":"Horizontal pleiotropy","title":"Perform MR","text":"intercept term MR Egger regression can useful indication whether directional horizontal pleiotropy driving results MR analysis. can obtained follows:","code":"mr_pleiotropy_test(dat) #> id.exposure id.outcome outcome #> 1 ieu-a-2 ieu-a-7 Coronary heart disease || id:ieu-a-7 #> exposure egger_intercept se pval #> 1 Body mass index || id:ieu-a-2 -0.001719304 0.003985962 0.6674266"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"single-snp-analysis","dir":"Articles","previous_headings":"Sensitivity analyses","what":"Single SNP analysis","title":"Perform MR","text":"obtain MR estimates using SNPs singly can following: returns data.frame results similar output mr() except performs analysis multiple times exposure-outcome combination - time using different single SNP perform analysis. method used perform single SNP MR Wald ratio default, though can changed, e.g. use fixed effects meta analysis method instead: mr_singlesnp() function calculates full MR using available SNPs well, default uses IVW MR Egger methods. can specified : perform maximum likelihood method combined test.","code":"res_single <- mr_singlesnp(dat) res_single <- mr_singlesnp(dat, single_method = \"mr_meta_fixed\") res_single <- mr_singlesnp(dat, all_method = \"mr_two_sample_ml\")"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"leave-one-out-analysis","dir":"Articles","previous_headings":"Sensitivity analyses","what":"Leave-one-out analysis","title":"Perform MR","text":"possible perform leave-one-analysis, MR performed leaving SNP turn, identify single SNP driving association. default method used inverse variance weighted method, can changed using method argument.","code":"res_loo <- mr_leaveoneout(dat)"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"plots","dir":"Articles","previous_headings":"","what":"Plots","title":"Perform MR","text":"ways visualise results, listed ","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"scatter-plot","dir":"Articles","previous_headings":"Plots","what":"Scatter plot","title":"Perform MR","text":"can depict relationship SNP effects exposure SNP effects outcome using scatter plot. scatter plot created exposure-outcome test, stored p1 list plots. example, plot first scatter plot: see many plots : Lines drawn method used mr(dat), slope line corresponding estimated causal effect. limit lines drawn, simply specify desired methods, e.g. draw MR Egger IVW: possible save plot using ggsave() function ggplot2 package, e.g. save pdf save png See ?ggplot2::ggsave info.","code":"res <- mr(dat) #> Analysing 'ieu-a-2' on 'ieu-a-7' p1 <- mr_scatter_plot(res, dat) p1[[1]] length(p1) #> [1] 1 res <- mr(dat, method_list = c(\"mr_egger_regression\", \"mr_ivw\")) #> Analysing 'ieu-a-2' on 'ieu-a-7' p1 <- mr_scatter_plot(res, dat) ggsave(p1[[1]], file = \"filename.pdf\", width = 7, height = 7) ggsave(p1[[1]], file = \"filename.png\", width = 7, height = 7)"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"forest-plot","dir":"Articles","previous_headings":"Plots","what":"Forest plot","title":"Perform MR","text":"Use mr_forest_plot() function compare MR estimates using different MR methods single SNP tests. , plot shows causal effect estimated using SNPs , comparing causal effect estimated using methods use SNPs. get plots use different methods, specify mr_singlesnp() function:","code":"res_single <- mr_singlesnp(dat) p2 <- mr_forest_plot(res_single) p2[[1]] res_single <- mr_singlesnp(dat, all_method = c(\"mr_ivw\", \"mr_two_sample_ml\")) p2 <- mr_forest_plot(res_single) p2[[1]]"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"leave-one-out-plot","dir":"Articles","previous_headings":"Plots","what":"Leave-one-out plot","title":"Perform MR","text":"Use mr_leaveoneout_plot() function visualise leave-one-analysis: Specify test use e.g. mr_leaveoneout(dat, method = mr_egger_regression) use MR-Egger regression.","code":"res_loo <- mr_leaveoneout(dat) p3 <- mr_leaveoneout_plot(res_loo) p3[[1]]"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"funnel-plot","dir":"Articles","previous_headings":"Plots","what":"Funnel plot","title":"Perform MR","text":"Asymmetry funnel plot useful gauging reliability particular MR analysis. Funnel plots can produced using single SNP results follows:","code":"res_single <- mr_singlesnp(dat) p4 <- mr_funnel_plot(res_single) p4[[1]]"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"to-many-forest-plot","dir":"Articles","previous_headings":"","what":"1-to-many forest plot","title":"Perform MR","text":"1--many MR analysis interrogates effect single exposure multiple outcomes multiple exposures single outcome. results analysis can visualised using 1--many forest plot, without stratification categorical variable. visual point view, function works best 50 fewer results really designed handle 100 results. number results much greater 50, may better split across two separate plots. example, 100 sets results divide equally across two plots combine two plots together another programme like Powerpoint. function assumes results already right order plotting. , users advised sort results according like appear plot. Users can use code can use sort_1_to_many() function.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"step-1-generate-1-to-many-mr-results","dir":"Articles","previous_headings":"1-to-many forest plot","what":"Step 1: generate 1-to-many MR results","title":"Perform MR","text":"","code":"exp_dat <- extract_instruments(outcomes = c(2, 100, 1032, 104, 1, 72, 999)) table(exp_dat$exposure) chd_out_dat <- extract_outcome_data( snps = exp_dat$SNP, outcomes = 7 ) dat2 <- harmonise_data( exposure_dat = exp_dat, outcome_dat = chd_out_dat ) res <- mr(dat2)"},{"path":[]},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"example-1--effect-of-multiple-risk-factors-on-coronary-heart-disease","dir":"Articles","previous_headings":"1-to-many forest plot > Step 2. Make the 1-to-many forest plot","what":"Example 1. Effect of multiple risk factors on coronary heart disease","title":"Perform MR","text":"example wish plot results MR analysis effect multiple exposures coronary heart disease, results sorted decreasing effect size (largest effect top plot) one MR method unique exposure-outcome combination. also make size point estimate proportional inverse variance. useful way draw attention towards reliable results away results wide confidence intervals. specify size point estimate, set weight argument name column data weight information. also possible add additional columns column titles choose size text columns: workflow prefer keep plot free axis column titles add separately program like powerpoint:","code":"res <- subset_on_method(res) # default is to subset on either the IVW method (>1 instrumental SNP) or Wald ratio method (1 instrumental SNP). res <- sort_1_to_many(res, b = \"b\", sort_action = 4) # this sorts results by decreasing effect size (largest effect at top of the plot) res <- split_exposure(res) # to keep the Y axis label clean we exclude the exposure ID labels from the exposure column res$weight <- 1/res$se min(exp(res$b - 1.96*res$se)) # identify value for 'lo' in forest_plot_1_to_many max(exp(res$b + 1.96*res$se)) # identify value for 'up' in forest_plot_1_to_many forest_plot_1_to_many( res, b = \"b\", se = \"se\", exponentiate = TRUE, ao_slc = FALSE, lo = 0.3, up = 2.5, TraitM = \"exposure\", col1_width = 2, by = NULL, trans = \"log2\", xlab = \"OR for CHD per SD increase in risk factor (95% confidence interval)\", weight = \"weight\" ) res$pval<-formatC(res$pval, format = \"e\", digits = 2) forest_plot_1_to_many( res, b = \"b\", se = \"se\", exponentiate = TRUE, ao_slc = FALSE, lo = 0.3, up = 2.5, TraitM = \"exposure\", by = NULL, trans = \"log2\", xlab = \"OR for CHD per SD increase in risk factor (95% CI)\", weight = \"weight\", subheading_size = 11, col1_title = \"Risk factor\", col1_width = 2.5, col_text_size = 4, addcols = c(\"nsnp\", \"pval\"), addcol_widths = c(1.0, 1.0), addcol_titles = c(\"No. SNPs\", \"P-val\") ) forest_plot_1_to_many( res, b = \"b\", se = \"se\", exponentiate = TRUE, ao_slc = FALSE, lo = 0.3, up = 3.0, TraitM = \"exposure\", col1_width = 2.0, by = NULL, trans = \"log2\", xlab = \"\", addcols = c(\"nsnp\", \"pval\"), weight = \"weight\", col_text_size = 4, addcol_widths = c(0.5, 1.0), addcol_titles = c(\"\", \"\") )"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"example-2--mr-results-for-multiple-mr-methods-grouped-by-multiple-exposures","dir":"Articles","previous_headings":"1-to-many forest plot > Step 2. Make the 1-to-many forest plot","what":"Example 2. MR results for multiple MR methods grouped by multiple exposures","title":"Perform MR","text":"next example plot results analysis effect multiple exposures coronary heart disease using multiple methods, results grouped exposure. also want result IVW method given priority go methods. also want exposure largest IVW effect size go top plot. also set TraitM argument column describing MR method. grouping results exposures. Normally row labels correspond exposures example want row names correspond MR method.","code":"res <- mr(dat2) res <- split_exposure(res) # to keep the Y axis label clean we exclude the exposure ID labels from the exposure column res <- sort_1_to_many( res, group = \"exposure\", sort_action = 3, priority = \"Inverse variance weighted\", trait_m = \"method\" ) forest_plot_1_to_many( res, b = \"b\", se = \"se\", exponentiate = TRUE, trans = \"log2\", ao_slc = FALSE, lo = 0.03, up = 22, col1_width = 2, by = \"exposure\", TraitM = \"method\", xlab = \"OR for CHD per SD increase in risk factor (95% confidence interval)\", subheading_size = 12, col_text_size = 4 )"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"example-3--stratify-results-on-a-grouping-variable","dir":"Articles","previous_headings":"1-to-many forest plot > Step 2. Make the 1-to-many forest plot","what":"Example 3. Stratify results on a grouping variable","title":"Perform MR","text":"next example plot results results stratified grouping variable. also select one MR method unique exposure-outcome combination sort results decreasing effect size within group (.e. largest effect top). example made arbitrary grouping variable called “subcategory” values “Group 1” “Group 2”. Typically, however, grouping variable might correspond something like trait ontology (e.g. anthropometric glycemic traits) study design (e.g. MR observational studies).","code":"res <- mr(dat2) res <- split_exposure(res) res <- subset_on_method(res) res$subcategory[res$exposure %in% c(\"Adiponectin\", \"Hip circumference\", \"Waist circumference\")] <- \"Group 1\" res$subcategory[is.na(res$subcategory)] <- \"Group 2\" res$weight <- 1/res$se res <- sort_1_to_many(res, sort_action = 1, group = \"subcategory\") forest_plot_1_to_many( res, b = \"b\", se = \"se\", exponentiate = TRUE, trans = \"log2\", ao_slc = FALSE, lo = 0.3, up = 2.5, TraitM = \"exposure\", col_text_size = 4, col1_width = 1.5, by = \"subcategory\", xlab = \"OR for CHD per SD increase in risk factor (95% confidence interval)\", subheading_size = 14, weight = \"weight\" )"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"example-4--effect-of-bmi-on-103-diseases","dir":"Articles","previous_headings":"1-to-many forest plot > Step 2. Make the 1-to-many forest plot","what":"Example 4. Effect of BMI on 103 diseases","title":"Perform MR","text":"plot function works best 50 fewer rows really designed handle 100. Visualising single-column forest plot 100 results also quite difficult. number results much greater 50, advisable split results across two different plots. example select BMI exposure test 103 diseases IEU GWAS database: MR results 103 diseases can difficult visualise single-column forest plot. workflow split across two plots join together separate program, Powerpoint, refinements . typically save plots using pdf() graphics device. particular example disease labels probably require cleaning (bit long) alternatively column text size made smaller. also possible change colour plot shape point estimates. Type ?forest_plot_1_to_many details.","code":"exp_dat <- extract_instruments(outcomes = 2) # extract instruments for BMI ao <- available_outcomes() ao <- ao[ao$category == \"Disease\", ] # identify diseases ao <- ao[which(ao$ncase > 100), ] dis_dat <- extract_outcome_data( snps = exp_dat$SNP, outcomes = ao$id ) dat3 <- harmonise_data( exposure_dat = exp_dat, outcome_dat = dis_dat ) res <- mr(dat3, method_list = c(\"mr_wald_ratio\", \"mr_ivw\")) res <- split_outcome(res) # to keep the Y axis label clean we exclude the exposure ID labels from the exposure column res <- sort_1_to_many(res, b = \"b\", sort_action = 4) # this sorts results by decreasing effect size (largest effect at top of the plot) res1 <- res[1:52, ] res2 <- res[53:103, ] plot1 <- forest_plot_1_to_many( res1, b = \"b\", se = \"se\", exponentiate = TRUE, trans = \"log2\", ao_slc = FALSE, lo = 0.004, up = 461, col1_width = 2, TraitM = \"outcome\", col_text_size = 3, xlab = \"\" ) plot2 <- forest_plot_1_to_many( res2, b = \"b\", se = \"se\", exponentiate = TRUE, trans = \"log2\", ao_slc = FALSE, lo = 0.004, up = 461, col1_width = 2, TraitM = \"outcome\", subheading_size = 11, col_text_size = 3, xlab = \"\" ) plot1 plot2 pdf(\"plot1.pdf\", height = 10, width = 8) plot1 dev.off()"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"mr-raps-many-weak-instruments-analysis","dir":"Articles","previous_headings":"","what":"MR.RAPS: Many weak instruments analysis","title":"Perform MR","text":"MR.RAPS (Robust Adjusted Profile Score) recently proposed method considers measurement error SNP-exposure effects, unbiased many (e.g. hundreds ) weak instruments, robust systematic idiosyncratic pleiotropy. See arXiv preprint detail statistical methodology. MR.RAPS implemented R package mr.raps available CRAN. can directly called TwoSampleMR MR.RAPS comes two main options: .dispersion (whether method consider systematic pleiotropy) loss.function (either \"l2\", \"huber\", \"tukey\"). latter two loss functions robust idiosyncratic pleiotropy. default option .dispersion = TRUE loss.function = \"tukey\". change options, modify parameters argument mr() (example)","code":"res <- mr(dat, method_list = c(\"mr_raps\")) res <- mr( dat, method_list = c(\"mr_raps\"), parameters = list(over.dispersion = FALSE, loss.function = \"l2\") )"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"reports","dir":"Articles","previous_headings":"","what":"Reports","title":"Perform MR","text":"report can generated performs MR analyses, sensitivity analyses, plots, presents single self-contained html web page, word document, pdf document. default produces html file current working directory, see help pages modify . function create separate report file every exposure-outcome combination present dat object.","code":"mr_report(dat)"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"mr-steiger-directionality-test","dir":"Articles","previous_headings":"","what":"MR Steiger directionality test","title":"Perform MR","text":"implementation method described : Hemani G, Tilling K, Davey Smith G. Orienting causal relationship imprecisely measured traits using GWAS summary data. PLoS Genetics. 2017. 13(11): e1007081. MR assumed instruments influence exposure first outcome exposure. sometimes difficult evaluate, example cis-acting SNP influencing gene expression levels DNA methylation levels first? causal direction hypothesised exposure outcomes can tested using Steiger test (Hemani, Tilling, Davey Smith 2017). example: calculates variance explained exposure outcome instrumenting SNPs, tests variance outcome less exposure. test , like many others, liable give inaccurate causal directions measurement error parameters exposure outcome (e.g. outcome much lower measurement precision proportion variance explained underestimated). Sensitivity can applied evaluate extent inferred causal direction liable measurement error, two ways. Provide estimates measurement error exposure outcome, obtain adjusted estimate causal direction possible values measurement error, identify proportion parameter space supports inferred causal direction tests obtained using:","code":"out <- directionality_test(dat) #> r.exposure and/or r.outcome not present. #> Calculating approximate SNP-exposure and/or SNP-outcome correlations, assuming all are quantitative traits. Please pre-calculate r.exposure and/or r.outcome using get_r_from_lor() for any binary traits knitr::kable(out) mr_steiger( p_exp = dat$pval.exposure, p_out = dat$pval.outcome, n_exp = dat$samplesize.exposure, n_out = dat$samplesize.outcome, r_xxo = 1, r_yyo = 1, r_exp=0 )"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"multivariable-mr","dir":"Articles","previous_headings":"","what":"Multivariable MR","title":"Perform MR","text":"SNPs instrument multiple potential exposures, example case different lipid fractions, one method overcoming problem estimate influence lipid conditioning effects SNPs lipids. Multivariable MR can performed using R package follows. Practically speaking, process needs occur perspective generating data correct format: Get instruments exposure Combine set instruments Clump avoid possibility e.g. variant exposure 1 LD variant exposure 2 Re-extract final clumped SNPs (3) exposures Harmonise effect allele Use multivariable MR method harmonised data Example - GWAS IDs HDL, LDL total cholesterol ieu--299, ieu--300 ieu--302. GWAS ID coronary heart disease (CHD) ieu--7. example estimate multivariable effects HDL, LDL total cholesterol CHD. First obtain instruments lipid fraction. entails obtaining combined set SNPs including instruments, getting SNPs lipid fraction. Therefore, e.g. 20 instruments 3 lipid fractions, combined 30 unique SNPs, need extract 30 SNPs lipid fraction (exposure). Next, also extract SNPs outcome. data obtained, harmonise reference allele. Finally, perform multivariable MR analysis generates table results.","code":"id_exposure <- c(\"ieu-a-299\", \"ieu-a-300\", \"ieu-a-302\") id_outcome <- \"ieu-a-7\" mv_exposure_dat <- mv_extract_exposures(id_exposure) mv_outcome_dat <- extract_outcome_data(exposure_dat$SNP, id_outcome) mvdat <- mv_harmonise_data(mv_exposure_dat, mv_outcome_dat) #> Harmonising HDL cholesterol || id:ieu-a-299 (ieu-a-299) and Coronary heart disease || id:ieu-a-7 (ieu-a-7) res <- mv_multiple(mvdat)"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"note-about-mv-methods","dir":"Articles","previous_headings":"Multivariable MR","what":"Note about MV methods","title":"Perform MR","text":"several different ways analysis can formulated. e.g. consider 3 exposures one outcome, one : Fit exposures together fit one exposure time residuals outcome adjusted outcomes. former recommended default R package mv_multiple() function latter MV MR originally described Burgess et al 2015 can done mv_residual(). Fitting instruments exposures (default) fitting instruments exposure sequentially Forcing slopes origin (default) allowing intercept term. three different parameters eight different ways MV analysis. recommend default settings described .","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"note-about-visualisation","dir":"Articles","previous_headings":"Multivariable MR","what":"Note about visualisation","title":"Perform MR","text":"Plots can generated using plots = TRUE argument mv_multiple() mv_residual(). current plots generated necessarily adequate show slope raw points, demonstrate raw points might effectively different plots conditional exposures.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"using-your-own-summary-data","dir":"Articles","previous_headings":"Multivariable MR","what":"Using your own summary data","title":"Perform MR","text":"want perform analysis local summary data (.e. OpenGWAS database) use look mv_extract_exposures_local() function instead mv_extract_exposures() function.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"mr-estimates-when-instruments-are-correlated","dir":"Articles","previous_headings":"","what":"MR estimates when instruments are correlated","title":"Perform MR","text":"examples shown far assumed instruments independent (.e. linkage disequilibrium, LD). avoid ‘double counting’ effects. alternative approach estimate MR effects accounting correlation variants. TwoSampleMR package implemented yet, MendelianRandomization R package Olena Yavorska Stephen Burgess functionality. can use TwoSampleMR package extract, format harmonise data, convert format required MendelianRandomization package. IEU GWAS database server individual level genetic data ~500 Europeans 1000 genomes data, can obtain LD matrix set SNPs using data. example: ld_matrix() returns LD correlation values (R2) pair variants present 1000 genomes data set. Convert MRInput format MendelianRandomization package: produces list MRInput objects can used MendelianRandomization functions, e.g. Alternatively, convert MRInput format also obtaining LD matrix instruments","code":"snplist <- c(\"rs234\", \"rs1205\") ld_mat <- ld_matrix(snplist) ld_mat #> rs234_A_G rs1205_T_C #> rs234_A_G 1.0000000 0.0797023 #> rs1205_T_C 0.0797023 1.0000000 dat <- harmonise_data( exposure_dat = bmi_exp_dat, outcome_dat = chd_out_dat ) #> Harmonising Body mass index || id:ieu-a-2 (ieu-a-2) and Coronary heart disease || id:ieu-a-7 (ieu-a-7) dat2 <- dat_to_MRInput(dat) #> Converting: #> - exposure: Body mass index || id:ieu-a-2 #> - outcome: Coronary heart disease || id:ieu-a-7 MendelianRandomization::mr_ivw(dat2[[1]]) #> #> Inverse-variance weighted method #> (variants uncorrelated, random-effect model) #> #> Number of Variants : 79 #> #> ------------------------------------------------------------------ #> Method Estimate Std Error 95% CI p-value #> IVW 0.446 0.059 0.330, 0.562 0.000 #> ------------------------------------------------------------------ #> Residual standard error = 1.357 #> Heterogeneity test statistic (Cochran's Q) = 143.6508 on 78 degrees of freedom, (p-value = 0.0000). I^2 = 45.7%. #> F statistic = 65.6. dat2 <- try(dat_to_MRInput(dat, get_correlation = TRUE)) #> Converting: #> - exposure: Body mass index || id:ieu-a-2 #> - outcome: Coronary heart disease || id:ieu-a-7 #> - obtaining LD matrix #> Please look at vignettes for options on running this locally if you need to run many instances of this command. #> Warning in ieugwasr::ld_matrix(variants = snps, with_alleles = with_alleles, : The following variants are not present in the LD reference panel #> rs2033529 if (class(dat2) != \"try-error\") MendelianRandomization::mr_ivw(dat2[[1]], correl = TRUE) #> #> Inverse-variance weighted method #> (variants correlated, random-effect model) #> #> Number of Variants : 78 #> #> ------------------------------------------------------------------ #> Method Estimate Std Error 95% CI p-value #> IVW 0.441 0.056 0.331, 0.551 0.000 #> ------------------------------------------------------------------ #> Residual standard error = 1.414 #> Heterogeneity test statistic (Cochran's Q) = 153.8519 on 77 degrees of freedom, (p-value = 0.0000). I^2 = 50.0%. #> F statistic = 80.3. #> #> (Estimates with correlated variants are sensitive to the signs in the correlation matrix #> - please ensure that your correlations are expressed with respect to the same effect alleles as your summarized association estimates.)"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"mr-moe-using-a-mixture-of-experts-machine-learning-approach","dir":"Articles","previous_headings":"","what":"MR-MoE: Using a mixture of experts machine learning approach","title":"Perform MR","text":"recently developed MR-MoE, method choose appropriate amongst several MR tests using machine learning algorithm. Note method still review, full details described : https://doi.org/10.1101/173682. MR-MoE operates taking set harmonised data, inferring characteristics dataset, using characteristics predict well different MR methods perform dataset, terms maximising power minimising false discovery rates. order run analysis must download RData object contains trained random forests used predict efficacy method. can downloaded : dropbox.com/s/5la7y38od95swcf Caution: large file (approx 167Mb) downloaded, read object use mr_moe() function perform analysis. example shown , estimating causal effect BMI coronary heart disease: function following: Performs MR using 11 MR methods Applies Steiger filtering heterogeneity filtering remove SNPs substantially larger R2 exposure outcome. Note - binary traits ensure number cases, number controls, allele frequencies available SNP. continuous traits make sure p-value sample size available. function infers trait binary continuous based units.exposure units.outcome columns - binary traits must values set ‘log odds’ Performs 14 MR methods using subset SNPs survive Steiger filtering Generates meta data summary data predict reliable 28 methods applied. every exposure / outcome combination dat object, MR-MoE method applied. function returns list long number exposure / outcome combinations. case, length 1, containing result BMI CHD. result object list following elements: estimates (results MR) heterogeneity (results heterogeneity different filtering approaches) directional_pleiotropy (egger intercepts) info (metrics used generate MOE) Looking estimates, see column called MOE predicted AUROC curve performance method.","code":"# Extact instruments for BMI exposure_dat <- extract_instruments(\"ieu-a-2\") # Get corresponding effects for CHD outcome_dat <- extract_outcome_data(exposure_dat$SNP, \"ieu-a-7\") # Harmonise dat <- harmonise_data(exposure_dat, outcome_dat) # Load the downloaded RData object. This loads the rf object load(\"rf.rdata\") # Obtain estimates from all methods, and generate data metrics res_all <- mr_wrapper(dat) # MR-MoE - predict the performance of each method res_moe <- mr_moe(res_all, rf)"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"post-mr-results-management","dir":"Articles","previous_headings":"","what":"Post MR results management","title":"Perform MR","text":"TwoSampleMR package also provides following functions managing editing MR results.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"split-outcome-names","dir":"Articles","previous_headings":"Post MR results management","what":"Split outcome names","title":"Perform MR","text":"outcome column output mr() combines original outcome name outcome trait ID. outcome column can split separate columns id outcome name using split_outcome function:","code":"head(res) #> $result #> id.exposure exposure id.outcome #> 1 ieu-a-299 HDL cholesterol || id:ieu-a-299 ieu-a-7 #> 2 ieu-a-300 LDL cholesterol || id:ieu-a-300 ieu-a-7 #> 3 ieu-a-302 Triglycerides || id:ieu-a-302 ieu-a-7 #> outcome nsnp b se pval #> 1 Coronary heart disease || id:ieu-a-7 79 -0.08919724 0.05970552 1.351879e-01 #> 2 Coronary heart disease || id:ieu-a-7 68 0.37853543 0.04976846 2.828614e-14 #> 3 Coronary heart disease || id:ieu-a-7 42 0.13584165 0.06738291 4.380354e-02 res <- mr(dat) #> Analysing 'ieu-a-2' on 'ieu-a-7' split_outcome(res) #> id.exposure id.outcome outcome exposure #> 1 ieu-a-2 ieu-a-7 Coronary heart disease Body mass index || id:ieu-a-2 #> 2 ieu-a-2 ieu-a-7 Coronary heart disease Body mass index || id:ieu-a-2 #> 3 ieu-a-2 ieu-a-7 Coronary heart disease Body mass index || id:ieu-a-2 #> 4 ieu-a-2 ieu-a-7 Coronary heart disease Body mass index || id:ieu-a-2 #> 5 ieu-a-2 ieu-a-7 Coronary heart disease Body mass index || id:ieu-a-2 #> method nsnp b se pval #> 1 MR Egger 79 0.5024935 0.14396056 8.012590e-04 #> 2 Weighted median 79 0.3870065 0.07717818 5.318417e-07 #> 3 Inverse variance weighted 79 0.4459091 0.05898302 4.032020e-14 #> 4 Simple mode 79 0.3401554 0.15276076 2.885059e-02 #> 5 Weighted mode 79 0.3790910 0.10761091 7.173381e-04"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"split-exposure-names","dir":"Articles","previous_headings":"Post MR results management","what":"Split exposure names","title":"Perform MR","text":"Similarly outcome column, exposure column output mr() combines original exposure name exposure trait ID. can split separate columns id exposure name using split_exposure function.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"generate-odds-ratios-with-95-confidence-intervals","dir":"Articles","previous_headings":"Post MR results management","what":"Generate odds ratios with 95% confidence intervals","title":"Perform MR","text":"Users can convert log odds ratios odds ratios 95% confidence intervals using:","code":"generate_odds_ratios(res) #> id.exposure id.outcome outcome #> 1 ieu-a-2 ieu-a-7 Coronary heart disease || id:ieu-a-7 #> 2 ieu-a-2 ieu-a-7 Coronary heart disease || id:ieu-a-7 #> 3 ieu-a-2 ieu-a-7 Coronary heart disease || id:ieu-a-7 #> 4 ieu-a-2 ieu-a-7 Coronary heart disease || id:ieu-a-7 #> 5 ieu-a-2 ieu-a-7 Coronary heart disease || id:ieu-a-7 #> exposure method nsnp b #> 1 Body mass index || id:ieu-a-2 MR Egger 79 0.5024935 #> 2 Body mass index || id:ieu-a-2 Weighted median 79 0.3870065 #> 3 Body mass index || id:ieu-a-2 Inverse variance weighted 79 0.4459091 #> 4 Body mass index || id:ieu-a-2 Simple mode 79 0.3401554 #> 5 Body mass index || id:ieu-a-2 Weighted mode 79 0.3790910 #> se pval lo_ci up_ci or or_lci95 or_uci95 #> 1 0.14396056 8.012590e-04 0.22033081 0.7846562 1.652838 1.246489 2.191653 #> 2 0.07717818 5.318417e-07 0.23573724 0.5382757 1.472566 1.265842 1.713051 #> 3 0.05898302 4.032020e-14 0.33030238 0.5615158 1.561909 1.391389 1.753328 #> 4 0.15276076 2.885059e-02 0.04074434 0.6395665 1.405166 1.041586 1.895659 #> 5 0.10761091 7.173381e-04 0.16817361 0.5900084 1.460956 1.183142 1.804004"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"subset-on-method","dir":"Articles","previous_headings":"Post MR results management","what":"Subset on method","title":"Perform MR","text":"sometimes useful subset results MR method, one unique result exposure-outcome combination: default subset IVW method >1 SNP available use Wald ratio method single SNP available. Users can specify multi-SNP method subset .","code":"subset_on_method(res) #> id.exposure id.outcome outcome #> 3 ieu-a-2 ieu-a-7 Coronary heart disease || id:ieu-a-7 #> exposure method nsnp b #> 3 Body mass index || id:ieu-a-2 Inverse variance weighted 79 0.4459091 #> se pval #> 3 0.05898302 4.03202e-14"},{"path":"https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html","id":"combine-all-results","dir":"Articles","previous_headings":"Post MR results management","what":"Combine all results","title":"Perform MR","text":"often useful combine results study level characterists single dataframe table, e.g. sharing results collaborators user wishes present results single table figure. can done using combine_all_mrresults() function: combines results mr(), mr_heterogeneity(), mr_pleiotropy_test() mr_singlesnp() single dataframe. also merges results outcome study level characteristics available_outcomes() function, including sample size characteristics. requested, also exponentiates results (e.g. user wants log odds ratio converted odds ratios 95 percent confidence intervals).","code":"res <- mr(dat) het <- mr_heterogeneity(dat) plt <- mr_pleiotropy_test(dat) sin <- mr_singlesnp(dat) all_res <- combine_all_mrresults( res, het, plt, sin, ao_slc = TRUE, Exp = TRUE, split.exposure = FALSE, split.outcome = TRUE ) head(all_res[, c( \"Method\", \"outcome\", \"exposure\", \"nsnp\", \"b\", \"se\", \"pval\", \"intercept\", \"intercept_se\", \"intercept_pval\", \"Q\", \"Q_df\", \"Q_pval\", \"consortium\", \"ncase\", \"ncontrol\", \"pmid\", \"population\" )])"},{"path":[]},{"path":"https://mrcieu.github.io/TwoSampleMR/authors.html","id":null,"dir":"","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Gibran Hemani. Author, maintainer. Philip Haycock. Author. Jie Zheng. Author. Tom Gaunt. Author. Ben Elsworth. Author. Tom Palmer. Author.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/authors.html","id":"citation","dir":"","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"Hemani G, Zheng J, Elsworth B, Wade KH, Baird D, Haberland V, Laurin C, Burgess S, Bowden J, Langdon R, Tan VY, Yarmolinsky J, Shihab HA, Timpson NJ, Evans DM, Relton C, Martin RM, Davey Smith G, Gaunt TR, Haycock PC, MR-Base Collaboration. MR-Base platform supports systematic causal inference across human phenome. eLife 2018;7:e34408. doi: 10.7554/eLife.34408 Hemani G, Tilling K, Davey Smith G (2017) Orienting causal relationship imprecisely measured traits using GWAS summary data. PLOS Genetics 13(11): e1007081. https://doi.org/10.1371/journal.pgen.1007081","code":"@Article{twosamplemr, author = {G. Hemani and J. Zheng and B. Elsworth and K. Wade and D. Baird and V. Haberland and C. Laurin and S. Burgess and J. Bowden and R. Langdon and V.Y. Tan and J. Yarmolinsky and H.A. Shibab and N.J. Timpson and D.M. Evans and C. Relton and R.M. Martin and G. {Davey Smith} and T.R. Gaunt and P.C. Haycock and {The MR-Base Collaboration}}, title = {The MR-Base platform supports systematic causal inference across the human phenome}, year = {2018}, volume = {7}, journal = {eLife}, pages = {e34408}, url = {https://elifesciences.org/articles/34408}, doi = {10.7554/eLife.34408}, } @Article{mrsteiger, author = {G. Hemani and K. Tilling and G. {Davey Smith}}, title = {Orienting the causal relationship between imprecisely measured traits using GWAS summary data}, journal = {PLoS Genetics}, year = {2017}, volume = {13}, number = {11}, pages = {e1007081}, doi = {10.1371/journal.pgen.1007081}, url = {https://doi.org/10.1371/journal.pgen.1007081}, }"},{"path":"https://mrcieu.github.io/TwoSampleMR/index.html","id":"mendelian-randomization-with-gwas-summary-data","dir":"","previous_headings":"","what":"Two Sample MR Functions and Interface to MRC Integrative Epidemiology Unit OpenGWAS Database","title":"Two Sample MR Functions and Interface to MRC Integrative Epidemiology Unit OpenGWAS Database","text":"package performing Mendelian randomization using GWAS summary data. uses IEU OpenGWAS database obtain data automatically, wide range methods run analysis.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/index.html","id":"january-2020-major-update","dir":"","previous_headings":"","what":"January 2020 major update","title":"Two Sample MR Functions and Interface to MRC Integrative Epidemiology Unit OpenGWAS Database","text":"made substantial changes package, database reference panels. full details changes, please visit https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/index.html","id":"installation","dir":"","previous_headings":"","what":"Installation","title":"Two Sample MR Functions and Interface to MRC Integrative Epidemiology Unit OpenGWAS Database","text":"Users running Windows macOS, install latest version TwoSampleMR please install MRC IEU r-universe Users running Linux WebR please see following instructions. update package run command .","code":"install.packages(\"TwoSampleMR\", repos = c(\"https://mrcieu.r-universe.dev\", \"https://cloud.r-project.org\"))"},{"path":"https://mrcieu.github.io/TwoSampleMR/index.html","id":"installing-from-source","dir":"","previous_headings":"Installation","what":"Installing from source","title":"Two Sample MR Functions and Interface to MRC Integrative Epidemiology Unit OpenGWAS Database","text":"update package just run remotes::install_github(\"MRCIEU/TwoSampleMR\") command .","code":"install.packages(\"remotes\") remotes::install_github(\"MRCIEU/TwoSampleMR\")"},{"path":"https://mrcieu.github.io/TwoSampleMR/index.html","id":"docker","dir":"","previous_headings":"","what":"Docker","title":"Two Sample MR Functions and Interface to MRC Integrative Epidemiology Unit OpenGWAS Database","text":"multi-platform docker image containing R TwoSampleMR package pre-installed (x86_64 ARM computers) available : https://hub.docker.com/r/mrcieu/twosamplemr","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/Isq.html","id":null,"dir":"Reference","previous_headings":"","what":"I-squared calculation — Isq","title":"I-squared calculation — Isq","text":"function calculates \\(^2\\) statistic. use \\(^2_{GX}\\) metric ensure effects sign (e.g. abs(y)).","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/Isq.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"I-squared calculation — Isq","text":"","code":"Isq(y, s)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/Isq.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"I-squared calculation — Isq","text":"y Vector effects. s Vector standard errors.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/Isq.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"I-squared calculation — Isq","text":"Isq value","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/TwoSampleMR-package.html","id":null,"dir":"Reference","previous_headings":"","what":"TwoSampleMR: Two Sample MR Functions and Interface to MRC Integrative Epidemiology Unit OpenGWAS Database — TwoSampleMR-package","title":"TwoSampleMR: Two Sample MR Functions and Interface to MRC Integrative Epidemiology Unit OpenGWAS Database — TwoSampleMR-package","text":"package performing Mendelian randomization using GWAS summary data. uses IEU OpenGWAS database https://gwas.mrcieu.ac.uk/ automatically obtain data, wide range methods run analysis.","code":""},{"path":[]},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/TwoSampleMR-package.html","id":"author","dir":"Reference","previous_headings":"","what":"Author","title":"TwoSampleMR: Two Sample MR Functions and Interface to MRC Integrative Epidemiology Unit OpenGWAS Database — TwoSampleMR-package","text":"Maintainer: Gibran Hemani g.hemani@bristol.ac.uk (ORCID) Authors: Philip Haycock philip.haycock@bristol.ac.uk (ORCID) Jie Zheng Jie.Zheng@bristol.ac.uk (ORCID) Tom Gaunt Tom.Gaunt@bristol.ac.uk (ORCID) Ben Elsworth Ben.Elsworth@bristol.ac.uk (ORCID) Tom Palmer tom.palmer@bristol.ac.uk (ORCID)","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/add_metadata.html","id":null,"dir":"Reference","previous_headings":"","what":"Add meta data to extracted data — add_metadata","title":"Add meta data to extracted data — add_metadata","text":"Previously meta data returned alongside association information. mostly unnecessary needlessly repeating information. convenience function reinstates information. Can applied either exposure data, outcome data, harmonised data","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/add_metadata.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Add meta data to extracted data — add_metadata","text":"","code":"add_metadata(dat, cols = c(\"sample_size\", \"ncase\", \"ncontrol\", \"unit\", \"sd\"))"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/add_metadata.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Add meta data to extracted data — add_metadata","text":"dat Either exposure data, outcome data harmonised data cols metadata fields add. Default = c(\"sample_size\", \"ncase\", \"ncontrol\", \"unit\", \"sd\")","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/add_metadata.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Add meta data to extracted data — add_metadata","text":"Data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/add_rsq.html","id":null,"dir":"Reference","previous_headings":"","what":"Estimate r-square of each association — add_rsq","title":"Estimate r-square of each association — add_rsq","text":"Can applied exposure_dat, outcome_dat harmonised_data. Note beneficial circumstances add meta data data object using add_metadata() running function. Also adds effective sample size case control data.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/add_rsq.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Estimate r-square of each association — add_rsq","text":"","code":"add_rsq(dat)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/add_rsq.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Estimate r-square of each association — add_rsq","text":"dat exposure_dat, outcome_dat harmonised_data","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/add_rsq.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Estimate r-square of each association — add_rsq","text":"data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/allele_frequency.html","id":null,"dir":"Reference","previous_headings":"","what":"Estimate allele frequency from SNP — allele_frequency","title":"Estimate allele frequency from SNP — allele_frequency","text":"Estimate allele frequency SNP","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/allele_frequency.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Estimate allele frequency from SNP — allele_frequency","text":"","code":"allele_frequency(g)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/allele_frequency.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Estimate allele frequency from SNP — allele_frequency","text":"g Vector 0/1/2","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/allele_frequency.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Estimate allele frequency from SNP — allele_frequency","text":"Allele frequency","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/available_outcomes.html","id":null,"dir":"Reference","previous_headings":"","what":"Get list of studies with available GWAS summary statistics through API — available_outcomes","title":"Get list of studies with available GWAS summary statistics through API — available_outcomes","text":"Get list studies available GWAS summary statistics API","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/available_outcomes.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get list of studies with available GWAS summary statistics through API — available_outcomes","text":"","code":"available_outcomes(opengwas_jwt = ieugwasr::get_opengwas_jwt())"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/available_outcomes.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get list of studies with available GWAS summary statistics through API — available_outcomes","text":"opengwas_jwt Used authenticate protected endpoints. Login https://api.opengwas.io obtain jwt. Provide jwt string , store .Renviron keyname OPENGWAS_JWT.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/available_outcomes.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get list of studies with available GWAS summary statistics through API — available_outcomes","text":"Dataframe details available studies","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/cleanup_outcome_data.html","id":null,"dir":"Reference","previous_headings":"","what":"Avoid issues in MR by finding impossible vals and setting to NA — cleanup_outcome_data","title":"Avoid issues in MR by finding impossible vals and setting to NA — cleanup_outcome_data","text":"Avoid issues MR finding impossible vals setting NA","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/cleanup_outcome_data.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Avoid issues in MR by finding impossible vals and setting to NA — cleanup_outcome_data","text":"","code":"cleanup_outcome_data(d)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/cleanup_outcome_data.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Avoid issues in MR by finding impossible vals and setting to NA — cleanup_outcome_data","text":"d Data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/cleanup_outcome_data.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Avoid issues in MR by finding impossible vals and setting to NA — cleanup_outcome_data","text":"Cleaned data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/clump_data.html","id":null,"dir":"Reference","previous_headings":"","what":"Perform LD clumping on SNP data — clump_data","title":"Perform LD clumping on SNP data — clump_data","text":"Uses PLINK clumping method, SNPs LD within particular window pruned. SNP lowest p-value retained.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/clump_data.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Perform LD clumping on SNP data — clump_data","text":"","code":"clump_data( dat, clump_kb = 10000, clump_r2 = 0.001, clump_p1 = 1, clump_p2 = 1, pop = \"EUR\", bfile = NULL, plink_bin = NULL )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/clump_data.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Perform LD clumping on SNP data — clump_data","text":"dat Output format_data(). Must SNP name column (SNP), SNP chromosome column (chr_name), SNP position column (chrom_start). id.exposure pval.exposure present generated. clump_kb Clumping window, default 10000. clump_r2 Clumping r2 cutoff. Note default value recently changed 0.01 0.001. clump_p1 Clumping sig level index SNPs, default 1. clump_p2 Clumping sig level secondary SNPs, default 1. pop Super-population use reference panel. Default = \"EUR\". Options \"EUR\", \"SAS\", \"EAS\", \"AFR\", \"AMR\". 'legacy' also available - previously used version EUR panel slightly different set markers bfile provided use API. Default = NULL plink_bin NULL bfile NULL detect packaged plink binary specific OS. Otherwise specify path plink binary. Default = NULL","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/clump_data.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Perform LD clumping on SNP data — clump_data","text":"Data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/clump_data.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Perform LD clumping on SNP data — clump_data","text":"function interacts OpenGWAS API, houses LD reference panels 5 super-populations 1000 genomes reference panel. includes bi-allelic SNPs MAF > 0.01, quite possible variant want include clumping process absent. absent, automatically excluded results. can check variants present LD reference panel using ieugwasr::ld_reflookup(). function put load OpenGWAS servers, makes life difficult users. implemented method made available LD reference panels perform clumping locally, see ieugwasr::ld_clump() related vignettes details.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/combine_all_mrresults.html","id":null,"dir":"Reference","previous_headings":"","what":"Combine all mr results — combine_all_mrresults","title":"Combine all mr results — combine_all_mrresults","text":"function combines results mr(), mr_heterogeneity(), mr_pleiotropy_test() mr_singlesnp() single data frame. also merges results outcome study level characteristics available_outcomes(). desired also exponentiates results (e.g. user wants log odds ratio converted odds ratios 95 percent confidence intervals). exposure outcome columns output mr() contain trait names trait ids. combine_all_mrresults() function splits separate columns default.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/combine_all_mrresults.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Combine all mr results — combine_all_mrresults","text":"","code":"combine_all_mrresults( res, het, plt, sin, ao_slc = TRUE, Exp = FALSE, split.exposure = FALSE, split.outcome = FALSE )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/combine_all_mrresults.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Combine all mr results — combine_all_mrresults","text":"res Results mr(). het Results mr_heterogeneity(). plt Results mr_pleiotropy_test(). sin Results mr_singlesnp(). ao_slc Logical; set TRUE outcome study level characteristics retrieved available_outcomes(). Default TRUE. Exp Logical; set TRUE results exponentiated. Useful user wants log odds ratios expressed odds ratios. Default FALSE. split.exposure Logical; set TRUE exposure column split separate columns exposure name exposure ID. Default FALSE. split.outcome Logical; set TRUE outcome column split separate columns outcome name outcome ID. Default FALSE.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/combine_all_mrresults.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Combine all mr results — combine_all_mrresults","text":"data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/combine_data.html","id":null,"dir":"Reference","previous_headings":"","what":"Combine data — combine_data","title":"Combine data — combine_data","text":"Taking exposure outcome data (returned format_data()) combine multiple datasets together can analysed one batch. Removes duplicate SNPs, preferentially keeping usable MR analysis.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/combine_data.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Combine data — combine_data","text":"","code":"combine_data(x)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/combine_data.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Combine data — combine_data","text":"x List data frames returned format_data().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/combine_data.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Combine data — combine_data","text":"data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/contingency.html","id":null,"dir":"Reference","previous_headings":"","what":"Obtain 2x2 contingency table from marginal parameters and odds ratio — contingency","title":"Obtain 2x2 contingency table from marginal parameters and odds ratio — contingency","text":"Columns case control frequencies. Rows frequencies allele 1 allele 2.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/contingency.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Obtain 2x2 contingency table from marginal parameters and odds ratio — contingency","text":"","code":"contingency(af, prop, odds_ratio, eps = 1e-15)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/contingency.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Obtain 2x2 contingency table from marginal parameters and odds ratio — contingency","text":"af Allele frequency effect allele. prop Proportion cases. odds_ratio Odds ratio. eps tolerance, default 1e-15.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/contingency.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Obtain 2x2 contingency table from marginal parameters and odds ratio — contingency","text":"2x2 contingency table matrix","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/convert_outcome_to_exposure.html","id":null,"dir":"Reference","previous_headings":"","what":"Convert outcome data to exposure data — convert_outcome_to_exposure","title":"Convert outcome data to exposure data — convert_outcome_to_exposure","text":"Helper function convert results extract_outcome_data() exposure_dat format.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/convert_outcome_to_exposure.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Convert outcome data to exposure data — convert_outcome_to_exposure","text":"","code":"convert_outcome_to_exposure(outcome_dat)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/convert_outcome_to_exposure.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Convert outcome data to exposure data — convert_outcome_to_exposure","text":"outcome_dat Output extract_outcome_data().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/convert_outcome_to_exposure.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Convert outcome data to exposure data — convert_outcome_to_exposure","text":"data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/create_label.html","id":null,"dir":"Reference","previous_headings":"","what":"Create fixed width label — create_label","title":"Create fixed width label — create_label","text":"Create fixed width label","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/create_label.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Create fixed width label — create_label","text":"","code":"create_label(n1, nom)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/create_label.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Create fixed width label — create_label","text":"n1 number nom name","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/create_label.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Create fixed width label — create_label","text":"text","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/dat_to_MRInput.html","id":null,"dir":"Reference","previous_headings":"","what":"Convert TwoSampleMR format to MendelianRandomization format — dat_to_MRInput","title":"Convert TwoSampleMR format to MendelianRandomization format — dat_to_MRInput","text":"MendelianRandomization package offers MR methods can used data used TwoSampleMR package. function converts TwoSampleMR format MRInput class.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/dat_to_MRInput.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Convert TwoSampleMR format to MendelianRandomization format — dat_to_MRInput","text":"","code":"dat_to_MRInput(dat, get_correlations = FALSE, pop = \"EUR\")"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/dat_to_MRInput.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Convert TwoSampleMR format to MendelianRandomization format — dat_to_MRInput","text":"dat Output harmonise_data() function. get_correlations Default FALSE. TRUE extract LD matrix SNPs European 1000 genomes data OpenGWAS. pop get_correlations TRUE use following","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/dat_to_MRInput.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Convert TwoSampleMR format to MendelianRandomization format — dat_to_MRInput","text":"List MRInput objects exposure/outcome combination","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/dat_to_RadialMR.html","id":null,"dir":"Reference","previous_headings":"","what":"Convert dat to RadialMR format — dat_to_RadialMR","title":"Convert dat to RadialMR format — dat_to_RadialMR","text":"Creates list RadialMR format datasets exposure-outcome pair.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/dat_to_RadialMR.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Convert dat to RadialMR format — dat_to_RadialMR","text":"","code":"dat_to_RadialMR(dat)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/dat_to_RadialMR.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Convert dat to RadialMR format — dat_to_RadialMR","text":"dat Output harmonise_data().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/dat_to_RadialMR.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Convert dat to RadialMR format — dat_to_RadialMR","text":"List RadialMR format datasets","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/default_parameters.html","id":null,"dir":"Reference","previous_headings":"","what":"List of parameters for use with MR functions — default_parameters","title":"List of parameters for use with MR functions — default_parameters","text":"default list(test_dist = \"z\", nboot = 1000, Cov = 0, penk = 20, phi = 1, alpha = 0.05, Qthresh = 0.05, .dispersion = TRUE, loss.function = \"huber\").","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/default_parameters.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"List of parameters for use with MR functions — default_parameters","text":"","code":"default_parameters()"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/directionality_test.html","id":null,"dir":"Reference","previous_headings":"","what":"Perform MR Steiger test of directionality — directionality_test","title":"Perform MR Steiger test of directionality — directionality_test","text":"statistical test whether assumption exposure causes outcome valid.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/directionality_test.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Perform MR Steiger test of directionality — directionality_test","text":"","code":"directionality_test(dat)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/directionality_test.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Perform MR Steiger test of directionality — directionality_test","text":"dat Harmonised exposure outcome data. Output harmonise_data().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/directionality_test.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Perform MR Steiger test of directionality — directionality_test","text":"List","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/effective_n.html","id":null,"dir":"Reference","previous_headings":"","what":"Estimate the effective sample size in a case control study — effective_n","title":"Estimate the effective sample size in a case control study — effective_n","text":"Taken https://www.nature.com/articles/nprot.2014.071","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/effective_n.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Estimate the effective sample size in a case control study — effective_n","text":"","code":"effective_n(ncase, ncontrol)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/effective_n.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Estimate the effective sample size in a case control study — effective_n","text":"ncase Vector number cases ncontrol Vector number controls","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/effective_n.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Estimate the effective sample size in a case control study — effective_n","text":"Vector effective sample size","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/enrichment.html","id":null,"dir":"Reference","previous_headings":"","what":"Perform enrichment analysis — enrichment","title":"Perform enrichment analysis — enrichment","text":"Perform enrichment analysis","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/enrichment.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Perform enrichment analysis — enrichment","text":"","code":"enrichment(dat, method_list = enrichment_method_list()$obj)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/enrichment.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Perform enrichment analysis — enrichment","text":"dat Harmonised exposure outcome data. Output harmonise_data(). method_list List methods use analysis. Default enrichment_method_list()$obj. See enrichment_method_list() details.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/enrichment.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Perform enrichment analysis — enrichment","text":"data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/enrichment_method_list.html","id":null,"dir":"Reference","previous_headings":"","what":"Get list of available p-value enrichment methods — enrichment_method_list","title":"Get list of available p-value enrichment methods — enrichment_method_list","text":"Get list available p-value enrichment methods","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/enrichment_method_list.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get list of available p-value enrichment methods — enrichment_method_list","text":"","code":"enrichment_method_list()"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/enrichment_method_list.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get list of available p-value enrichment methods — enrichment_method_list","text":"Data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/estimate_trait_sd.html","id":null,"dir":"Reference","previous_headings":"","what":"Estimate trait SD by obtaining beta estimates from z-scores and finding the ratio with original beta values — estimate_trait_sd","title":"Estimate trait SD by obtaining beta estimates from z-scores and finding the ratio with original beta values — estimate_trait_sd","text":"Assumes sample size allele frequency correct SNP, allele frequency gives reasonable estimate variance SNP.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/estimate_trait_sd.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Estimate trait SD by obtaining beta estimates from z-scores and finding the ratio with original beta values — estimate_trait_sd","text":"","code":"estimate_trait_sd(b, se, n, p)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/estimate_trait_sd.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Estimate trait SD by obtaining beta estimates from z-scores and finding the ratio with original beta values — estimate_trait_sd","text":"b vector effect sizes. se vector standard errors. n vector sample sizes. p vector allele frequencies.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/estimate_trait_sd.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Estimate trait SD by obtaining beta estimates from z-scores and finding the ratio with original beta values — estimate_trait_sd","text":"Vector sd estimates association.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/extract_instruments.html","id":null,"dir":"Reference","previous_headings":"","what":"Find instruments for use in MR from the OpenGWAS database — extract_instruments","title":"Find instruments for use in MR from the OpenGWAS database — extract_instruments","text":"function searches GWAS significant SNPs (given p-value) specified set outcomes. performs LD based clumping return independent significant associations.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/extract_instruments.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Find instruments for use in MR from the OpenGWAS database — extract_instruments","text":"","code":"extract_instruments( outcomes, p1 = 5e-08, clump = TRUE, p2 = 5e-08, r2 = 0.001, kb = 10000, opengwas_jwt = ieugwasr::get_opengwas_jwt(), force_server = FALSE )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/extract_instruments.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Find instruments for use in MR from the OpenGWAS database — extract_instruments","text":"outcomes Array outcome IDs (see available_outcomes()). p1 Significance threshold. default 5e-8. clump Logical; whether clump results. default TRUE. p2 Secondary clumping threshold. default 5e-8. r2 Clumping r2 cut . default 0.001. kb Clumping distance cutoff. default 10000. opengwas_jwt Used authenticate protected endpoints. Login https://api.opengwas.io obtain jwt. Provide jwt string , store .Renviron keyname OPENGWAS_JWT. force_server Force analysis extract results server rather MRInstruments package.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/extract_instruments.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Find instruments for use in MR from the OpenGWAS database — extract_instruments","text":"data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/extract_outcome_data.html","id":null,"dir":"Reference","previous_headings":"","what":"Supply the output from read_exposure_data() and all the SNPs therein will be queried against the requested outcomes in remote database using API. — extract_outcome_data","title":"Supply the output from read_exposure_data() and all the SNPs therein will be queried against the requested outcomes in remote database using API. — extract_outcome_data","text":"Supply output read_exposure_data() SNPs therein queried requested outcomes remote database using API.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/extract_outcome_data.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Supply the output from read_exposure_data() and all the SNPs therein will be queried against the requested outcomes in remote database using API. — extract_outcome_data","text":"","code":"extract_outcome_data( snps, outcomes, proxies = TRUE, rsq = 0.8, align_alleles = 1, palindromes = 1, maf_threshold = 0.3, opengwas_jwt = ieugwasr::get_opengwas_jwt(), splitsize = 10000, proxy_splitsize = 500 )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/extract_outcome_data.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Supply the output from read_exposure_data() and all the SNPs therein will be queried against the requested outcomes in remote database using API. — extract_outcome_data","text":"snps Array SNP rs IDs. outcomes Array IDs (see id column output available_outcomes()). proxies Look LD tags? Default TRUE. rsq Minimum LD rsq value (proxies = 1). Default = 0.8. align_alleles Try align tag alleles target alleles (proxies = 1). 1 = yes, 0 = . default 1. palindromes Allow palindromic SNPs (proxies = 1). 1 = yes, 0 = . default 1. maf_threshold MAF threshold try infer palindromic SNPs. default 0.3. opengwas_jwt Used authenticate protected endpoints. Login https://api.opengwas.io obtain jwt. Provide jwt string , store .Renviron keyname OPENGWAS_JWT. splitsize default 10000. proxy_splitsize default 500.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/extract_outcome_data.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Supply the output from read_exposure_data() and all the SNPs therein will be queried against the requested outcomes in remote database using API. — extract_outcome_data","text":"Dataframe summary statistics available outcomes","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/fishers_combined_test.html","id":null,"dir":"Reference","previous_headings":"","what":"Fisher's combined test — fishers_combined_test","title":"Fisher's combined test — fishers_combined_test","text":"Fisher's combined test","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/fishers_combined_test.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Fisher's combined test — fishers_combined_test","text":"","code":"fishers_combined_test(pval)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/fishers_combined_test.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Fisher's combined test — fishers_combined_test","text":"pval Vector outcome p-values","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/fishers_combined_test.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Fisher's combined test — fishers_combined_test","text":"List following elements: b MR estimate se Standard error pval p-value","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/forest_plot.html","id":null,"dir":"Reference","previous_headings":"","what":"Forest plot for multiple exposures and multiple outcomes — forest_plot","title":"Forest plot for multiple exposures and multiple outcomes — forest_plot","text":"Perform MR multiple exposures multiple outcomes. plots results.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/forest_plot.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Forest plot for multiple exposures and multiple outcomes — forest_plot","text":"","code":"forest_plot( mr_res, exponentiate = FALSE, single_snp_method = \"Wald ratio\", multi_snp_method = \"Inverse variance weighted\", group_single_categories = TRUE, by_category = TRUE, in_columns = FALSE, threshold = NULL, xlab = \"\", xlim = NULL, trans = \"identity\", ao_slc = TRUE, priority = \"Cardiometabolic\" )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/forest_plot.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Forest plot for multiple exposures and multiple outcomes — forest_plot","text":"mr_res Results mr(). exponentiate Convert effects ? Default FALSE. single_snp_method single SNP methosd use 1 SNP used estimate causal effect? default \"Wald ratio\". multi_snp_method multi-SNP methods use 1 SNPs used estimate causal effect? default \"Inverse variance weighted\". group_single_categories categories one outcome, group together \"\" group. default TRUE. by_category Separate results sections category? default TRUE. in_columns Separate exposures different columns. default FALSE. threshold p-value threshold use colouring points significance level. NULL (default) colour layer applied. xlab x-axis label. in_columns=TRUE exposure values appended end xlab. e.g. xlab=\"Effect \" x-labels read \"Effect exposure1\", \"Effect exposure2\" etc. Otherwise printed . xlim limit x-axis range. Provide vector length 2, lower upper bounds. default NULL. trans Transformation apply x-axis. e.g. \"identity\", \"log2\", etc. default \"identity\". ao_slc retrieve sample size subcategory available_outcomes(). set FALSE mr_res must contain following additional columns: sample_size subcategory. default behaviour use available_outcomes() retrieve sample size subcategory. priority Name category prioritise top forest plot. default \"Cardiometabolic\".","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/forest_plot.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Forest plot for multiple exposures and multiple outcomes — forest_plot","text":"grid plot object","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/forest_plot_1_to_many.html","id":null,"dir":"Reference","previous_headings":"","what":"1-to-many forest plot — forest_plot_1_to_many","title":"1-to-many forest plot — forest_plot_1_to_many","text":"Plot results analysis multiple exposures single outcome single exposure multiple outcomes. Plots effect estimates 95 percent confidence intervals. ordering results plot determined order supplied user. Users may find sort_1_to_many() helpful sorting results prior using 1--many forest plot. plot function works best 50 results designed handle 100 results.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/forest_plot_1_to_many.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"1-to-many forest plot — forest_plot_1_to_many","text":"","code":"forest_plot_1_to_many( mr_res = \"mr_res\", b = \"b\", se = \"se\", TraitM = \"outcome\", col1_width = 1, col1_title = \"\", exponentiate = FALSE, trans = \"identity\", ao_slc = TRUE, lo = NULL, up = NULL, by = NULL, xlab = \"Effect (95% confidence interval)\", addcols = NULL, addcol_widths = NULL, addcol_titles = \"\", subheading_size = 6, shape_points = 15, colour_scheme = \"black\", col_text_size = 5, weight = NULL )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/forest_plot_1_to_many.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"1-to-many forest plot — forest_plot_1_to_many","text":"mr_res Data frame results supplied user. default \"mr_res\". b Name column specifying effect exposure outcome. default \"b\". se Name column specifying standard error b. default \"se\". TraitM column specifying names traits. Corresponds 'many' 1--many forest plot. default \"outcome\". col1_width Width Y axis label column specified TraitM argument. default 1. col1_title Title column specified TraitM argument. default \"\". exponentiate Convert log odds ratios odds ratios? Default FALSE. trans Specify x-axis scale. e.g. \"identity\", \"log2\", etc. set \"identity\" additive scale used. set log2 x-axis plotted multiplicative / doubling scale (preferable plotting odds ratios). Default \"identity\". ao_slc Logical; retrieve trait subcategory information using available_outcomes(). Default FALSE. lo Lower limit X axis plot. upper limit X axis plot. Name grouping variable stratify results . Default NULL. xlab X-axis label, default \"Effect (95% confidence interval)\". addcols Name additional columns plot. Character vector. default NULL. addcol_widths Widths Y axis labels additional columns specified addcols argument. Numeric vector. default NULL. addcol_titles Titles additional columns specified addcols argument. Character vector. default NULL. subheading_size text size subheadings specified argument. default 6. shape_points shape data points pass ggplot2::geom_point(). Default set 15 (filled square). colour_scheme general colour scheme plot. Default make text data points \"black\". col_text_size default 5. weight default NULL.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/forest_plot_1_to_many.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"1-to-many forest plot — forest_plot_1_to_many","text":"grid plot object","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/forest_plot_basic.html","id":null,"dir":"Reference","previous_headings":"","what":"A basic forest plot — forest_plot_basic","title":"A basic forest plot — forest_plot_basic","text":"function used create basic forest plot. requires output format_mr_results().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/forest_plot_basic.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"A basic forest plot — forest_plot_basic","text":"","code":"forest_plot_basic( dat, section = NULL, colour_group = NULL, colour_group_first = TRUE, xlab = NULL, bottom = TRUE, trans = \"identity\", xlim = NULL, threshold = NULL )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/forest_plot_basic.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"A basic forest plot — forest_plot_basic","text":"dat Output format_mr_results(). section category dat plot. NULL prints everything. colour_group exposure plot. NULL prints everything grouping colour. colour_group_first default TRUE. xlab x-axis label. Default=NULL. bottom Show x-axis? Default=FALSE. trans Transformation x axis. xlim x-axis limits. threshold p-value threshold use colouring points significance level. NULL (default) colour layer applied.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/forest_plot_basic.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"A basic forest plot — forest_plot_basic","text":"ggplot object","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/forest_plot_basic2.html","id":null,"dir":"Reference","previous_headings":"","what":"A basic forest plot — forest_plot_basic2","title":"A basic forest plot — forest_plot_basic2","text":"function used create basic forest plot. requires output format_1_to_many().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/forest_plot_basic2.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"A basic forest plot — forest_plot_basic2","text":"","code":"forest_plot_basic2( dat, section = NULL, colour_group = NULL, colour_group_first = TRUE, xlab = NULL, bottom = TRUE, trans = \"identity\", xlim = NULL, lo = lo, up = up, subheading_size = subheading_size, colour_scheme = \"black\", shape_points = 15 )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/forest_plot_basic2.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"A basic forest plot — forest_plot_basic2","text":"dat Output format_1_to_many() section category dat plot. NULL prints everything. colour_group exposure plot. NULL prints everything grouping colour. colour_group_first default TRUE. xlab x-axis label. Default=NULL. bottom Show x-axis? Default=FALSE. trans x-axis scale. xlim x-axis limits. lo Lower limit x axis. Upper limit x axis. subheading_size text size subheadings. subheadings correspond values section argument. colour_scheme general colour scheme plot. Default make text data points \"black\". shape_points shape data points pass ggplot2::geom_point(). Default set 15 (filled square).","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/forest_plot_basic2.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"A basic forest plot — forest_plot_basic2","text":"ggplot object","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_1_to_many.html","id":null,"dir":"Reference","previous_headings":"","what":"Format MR results for a 1-to-many forest plot — format_1_to_many","title":"Format MR results for a 1-to-many forest plot — format_1_to_many","text":"function formats user-supplied results forest_plot_1_to_many() function. user supplies results form data frame. data frame assumed contain least three columns data: effect estimates, analysis effect exposure outcome; standard errors effect estimates; column trait names, corresponding 'many' 1--many forest plot.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_1_to_many.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Format MR results for a 1-to-many forest plot — format_1_to_many","text":"","code":"format_1_to_many( mr_res, b = \"b\", se = \"se\", exponentiate = FALSE, ao_slc = FALSE, by = NULL, TraitM = \"outcome\", addcols = NULL, weight = NULL )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_1_to_many.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Format MR results for a 1-to-many forest plot — format_1_to_many","text":"mr_res Data frame results supplied user. b Name column specifying effect exposure outcome. Default = \"b\". se Name column specifying standard error b. Default = \"se\". exponentiate Convert log odds ratios odds ratios? Default=FALSE. ao_slc Logical; retrieve trait subcategory information using available_outcomes(). Default=FALSE. Name column indicating grouping variable stratify results . Default=NULL. TraitM column specifying names traits. Corresponds 'many' 1--many forest plot. Default=\"outcome\". addcols Name additional columns add plot. Character vector. default NULL. weight default NULL.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_1_to_many.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Format MR results for a 1-to-many forest plot — format_1_to_many","text":"data frame.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_aries_mqtl.html","id":null,"dir":"Reference","previous_headings":"","what":"Get data from methylation QTL results — format_aries_mqtl","title":"Get data from methylation QTL results — format_aries_mqtl","text":"See format_data().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_aries_mqtl.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get data from methylation QTL results — format_aries_mqtl","text":"","code":"format_aries_mqtl(aries_mqtl_subset, type = \"exposure\")"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_aries_mqtl.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get data from methylation QTL results — format_aries_mqtl","text":"aries_mqtl_subset Selected rows aries_mqtl data loaded MRInstruments package. type data used \"exposure\" \"outcome\"? Default \"exposure\".","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_aries_mqtl.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get data from methylation QTL results — format_aries_mqtl","text":"Data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_d.html","id":null,"dir":"Reference","previous_headings":"","what":"Format the returned table from the MySQL database — format_d","title":"Format the returned table from the MySQL database — format_d","text":"Format returned table MySQL database","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_d.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Format the returned table from the MySQL database — format_d","text":"","code":"format_d(d)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_d.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Format the returned table from the MySQL database — format_d","text":"d Data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_d.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Format the returned table from the MySQL database — format_d","text":"Data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_data.html","id":null,"dir":"Reference","previous_headings":"","what":"Read exposure or outcome data — format_data","title":"Read exposure or outcome data — format_data","text":"Reads exposure data. Checks organises columns use MR enrichment tests. Infers p-values possible beta se.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_data.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Read exposure or outcome data — format_data","text":"","code":"format_data( dat, type = \"exposure\", snps = NULL, header = TRUE, phenotype_col = \"Phenotype\", snp_col = \"SNP\", beta_col = \"beta\", se_col = \"se\", eaf_col = \"eaf\", effect_allele_col = \"effect_allele\", other_allele_col = \"other_allele\", pval_col = \"pval\", units_col = \"units\", ncase_col = \"ncase\", ncontrol_col = \"ncontrol\", samplesize_col = \"samplesize\", gene_col = \"gene\", id_col = \"id\", min_pval = 1e-200, z_col = \"z\", info_col = \"info\", chr_col = \"chr\", pos_col = \"pos\", log_pval = FALSE )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_data.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Read exposure or outcome data — format_data","text":"dat Data frame. Must header least SNP column present. type exposure outcome data read ? default \"exposure\". snps SNPs extract. NULL extract keeps . default NULL. header default TRUE. phenotype_col Optional column name column phenotype name corresponding SNP. present created value \"Outcome\". default \"Phenotype\". snp_col Required name column SNP rs IDs. default \"SNP\". beta_col Required MR. Name column effect sizes. default \"beta\". se_col Required MR. Name column standard errors. default \"se\". eaf_col Required MR. Name column effect allele frequency. default \"eaf\". effect_allele_col Required MR. Name column effect allele. Must contain characters \"\", \"C\", \"T\" \"G\". default \"effect_allele\". other_allele_col Required MR. Name column non effect allele. Must contain characters \"\", \"C\", \"T\" \"G\". default \"other_allele\". pval_col Required enrichment tests. Name column p-value. default \"pval\". units_col Optional column name units. default \"units\". ncase_col Optional column name number cases. default \"ncase\". ncontrol_col Optional column name number controls. default \"ncontrol\". samplesize_col Optional column name sample size. default \"samplesize\". gene_col Optional column name gene name. default \"gene\". id_col default \"id\". min_pval Minimum allowed p-value. default 1e-200. z_col default \"z\". info_col default \"info_col\". chr_col default \"chr_col\". pos_col default \"pos\". log_pval pval -log10(P). default FALSE.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_data.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Read exposure or outcome data — format_data","text":"data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_gtex_eqtl.html","id":null,"dir":"Reference","previous_headings":"","what":"Get data from eQTL catalog into correct format — format_gtex_eqtl","title":"Get data from eQTL catalog into correct format — format_gtex_eqtl","text":"See format_data().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_gtex_eqtl.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get data from eQTL catalog into correct format — format_gtex_eqtl","text":"","code":"format_gtex_eqtl(gtex_eqtl_subset, type = \"exposure\")"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_gtex_eqtl.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get data from eQTL catalog into correct format — format_gtex_eqtl","text":"gtex_eqtl_subset Selected rows gtex_eqtl data loaded MRInstruments package. type data used \"exposure\" \"outcome\"? Default \"exposure\".","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_gtex_eqtl.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get data from eQTL catalog into correct format — format_gtex_eqtl","text":"Data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_gwas_catalog.html","id":null,"dir":"Reference","previous_headings":"","what":"Get data selected from GWAS catalog into correct format — format_gwas_catalog","title":"Get data selected from GWAS catalog into correct format — format_gwas_catalog","text":"DEPRECATED. Please use format_data() instead.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_gwas_catalog.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get data selected from GWAS catalog into correct format — format_gwas_catalog","text":"","code":"format_gwas_catalog(gwas_catalog_subset, type = \"exposure\")"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_gwas_catalog.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get data selected from GWAS catalog into correct format — format_gwas_catalog","text":"gwas_catalog_subset GWAS catalog subset. type default \"exposure\".","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_gwas_catalog.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get data selected from GWAS catalog into correct format — format_gwas_catalog","text":"Data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_gwas_catalog.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Get data selected from GWAS catalog into correct format — format_gwas_catalog","text":"","code":"if (FALSE) { # \\dontrun{ require(MRInstruments) data(gwas_catalog) bmi <- subset(gwas_catalog, Phenotype==\"Body mass index\" & Year==2010 & grepl(\"kg\", Units)) bmi <- format_data(bmi) } # }"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_metab_qtls.html","id":null,"dir":"Reference","previous_headings":"","what":"Get data from metabolomic QTL results — format_metab_qtls","title":"Get data from metabolomic QTL results — format_metab_qtls","text":"See format_data().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_metab_qtls.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get data from metabolomic QTL results — format_metab_qtls","text":"","code":"format_metab_qtls(metab_qtls_subset, type = \"exposure\")"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_metab_qtls.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get data from metabolomic QTL results — format_metab_qtls","text":"metab_qtls_subset Selected rows metab_qtls data loaded MRInstruments package. type data used \"exposure\" \"outcome\"? Default \"exposure\".","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_metab_qtls.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get data from metabolomic QTL results — format_metab_qtls","text":"Data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_mr_results.html","id":null,"dir":"Reference","previous_headings":"","what":"Format MR results for forest plot — format_mr_results","title":"Format MR results for forest plot — format_mr_results","text":"function takes results mr() particularly useful MR applied using multiple exposures multiple outcomes. creates new data frame following: Variables: exposure, outcome, category, outcome sample size, effect, upper ci, lower ci, pval, nsnp one estimate exposure-outcome exponentiated effects required","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_mr_results.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Format MR results for forest plot — format_mr_results","text":"","code":"format_mr_results( mr_res, exponentiate = FALSE, single_snp_method = \"Wald ratio\", multi_snp_method = \"Inverse variance weighted\", ao_slc = TRUE, priority = \"Cardiometabolic\" )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_mr_results.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Format MR results for forest plot — format_mr_results","text":"mr_res Results mr(). exponentiate Convert effects ? default FALSE. single_snp_method single SNP methods use 1 SNP used estimate causal effect? default \"Wald ratio\". multi_snp_method multi-SNP methods use 1 SNPs used estimate causal effect? default \"Inverse variance weighted\". ao_slc Logical; retrieve sample size subcategory using available_outcomes(). set FALSE mr_res must contain following additional columns: subcategory sample_size. priority Name category prioritise top forest plot. default \"Cardiometabolic\".","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_mr_results.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Format MR results for forest plot — format_mr_results","text":"data frame.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_mr_results.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Format MR results for forest plot — format_mr_results","text":"default uses available_outcomes() function retrieve study level characteristics outcome trait, including sample size outcome category. assumes MR analysis performed using outcome GWAS(s) contained OpenGWAS. ao_slc set TRUE user must supply study level characteristics. useful user supplied outcome GWAS results (.e. OpenGWAS).","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_proteomic_qtls.html","id":null,"dir":"Reference","previous_headings":"","what":"Get data from proteomic QTL results — format_proteomic_qtls","title":"Get data from proteomic QTL results — format_proteomic_qtls","text":"See format_data().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_proteomic_qtls.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get data from proteomic QTL results — format_proteomic_qtls","text":"","code":"format_proteomic_qtls(proteomic_qtls_subset, type = \"exposure\")"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_proteomic_qtls.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get data from proteomic QTL results — format_proteomic_qtls","text":"proteomic_qtls_subset Selected rows proteomic_qtls data loaded MRInstruments package. type data used \"exposure\" \"outcome\"? Default \"exposure\".","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/format_proteomic_qtls.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get data from proteomic QTL results — format_proteomic_qtls","text":"Data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/generate_odds_ratios.html","id":null,"dir":"Reference","previous_headings":"","what":"Generate odds ratios — generate_odds_ratios","title":"Generate odds ratios — generate_odds_ratios","text":"function takes b se mr() generates odds ratios 95 percent confidence intervals.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/generate_odds_ratios.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Generate odds ratios — generate_odds_ratios","text":"","code":"generate_odds_ratios(mr_res)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/generate_odds_ratios.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Generate odds ratios — generate_odds_ratios","text":"mr_res Results mr().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/generate_odds_ratios.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Generate odds ratios — generate_odds_ratios","text":"data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_p_from_r2n.html","id":null,"dir":"Reference","previous_headings":"","what":"Calculate p-value from R-squared and sample size — get_p_from_r2n","title":"Calculate p-value from R-squared and sample size — get_p_from_r2n","text":"Calculate p-value R-squared sample size","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_p_from_r2n.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Calculate p-value from R-squared and sample size — get_p_from_r2n","text":"","code":"get_p_from_r2n(r2, n)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_p_from_r2n.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Calculate p-value from R-squared and sample size — get_p_from_r2n","text":"r2 Rsq n Sample size","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_p_from_r2n.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Calculate p-value from R-squared and sample size — get_p_from_r2n","text":"P-value","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_population_allele_frequency.html","id":null,"dir":"Reference","previous_headings":"","what":"Estimate the allele frequency in population from case/control summary data — get_population_allele_frequency","title":"Estimate the allele frequency in population from case/control summary data — get_population_allele_frequency","text":"Estimate allele frequency population case/control summary data","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_population_allele_frequency.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Estimate the allele frequency in population from case/control summary data — get_population_allele_frequency","text":"","code":"get_population_allele_frequency(af, prop, odds_ratio, prevalence)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_population_allele_frequency.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Estimate the allele frequency in population from case/control summary data — get_population_allele_frequency","text":"af Effect allele frequency (MAF) prop Proportion samples cases odds_ratio Odds ratio prevalence Population disease prevalence","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_population_allele_frequency.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Estimate the allele frequency in population from case/control summary data — get_population_allele_frequency","text":"Population allele frequency","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_r_from_bsen.html","id":null,"dir":"Reference","previous_headings":"","what":"Estimate R-squared from beta, standard error and sample size — get_r_from_bsen","title":"Estimate R-squared from beta, standard error and sample size — get_r_from_bsen","text":"Estimate R-squared beta, standard error sample size","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_r_from_bsen.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Estimate R-squared from beta, standard error and sample size — get_r_from_bsen","text":"","code":"get_r_from_bsen(b, se, n)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_r_from_bsen.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Estimate R-squared from beta, standard error and sample size — get_r_from_bsen","text":"b Array effect sizes se Array standard errors n Array (effective) sample sizes","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_r_from_bsen.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Estimate R-squared from beta, standard error and sample size — get_r_from_bsen","text":"Vector signed r values","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_r_from_lor.html","id":null,"dir":"Reference","previous_headings":"","what":"Estimate proportion of variance of liability explained by SNP in general population — get_r_from_lor","title":"Estimate proportion of variance of liability explained by SNP in general population — get_r_from_lor","text":"uses equation 10 Lee et al. Better Coefficient Determination Genetic Profile Analysis. Genetic Epidemiology 36: 214–224 (2012) doi:10.1002/gepi.21614 .","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_r_from_lor.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Estimate proportion of variance of liability explained by SNP in general population — get_r_from_lor","text":"","code":"get_r_from_lor( lor, af, ncase, ncontrol, prevalence, model = \"logit\", correction = FALSE )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_r_from_lor.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Estimate proportion of variance of liability explained by SNP in general population — get_r_from_lor","text":"lor Vector Log odds ratio. af Vector allele frequencies. ncase Vector Number cases. ncontrol Vector Number controls. prevalence Vector Disease prevalence population. model effect size estimated \"logit\" (default) \"probit\" model. correction Scale estimated r correction value. default FALSE.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_r_from_lor.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Estimate proportion of variance of liability explained by SNP in general population — get_r_from_lor","text":"Vector signed r values","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_r_from_pn.html","id":null,"dir":"Reference","previous_headings":"","what":"Calculate variance explained from p-values and sample size — get_r_from_pn","title":"Calculate variance explained from p-values and sample size — get_r_from_pn","text":"method approximation, may numerically unstable. Ideally estimate r directly independent replication samples. Use get_r_from_lor() binary traits.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_r_from_pn.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Calculate variance explained from p-values and sample size — get_r_from_pn","text":"","code":"get_r_from_pn(p, n)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_r_from_pn.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Calculate variance explained from p-values and sample size — get_r_from_pn","text":"p Array pvals n Array sample sizes","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_r_from_pn.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Calculate variance explained from p-values and sample size — get_r_from_pn","text":"Vector r values (arbitrarily positive)","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_se.html","id":null,"dir":"Reference","previous_headings":"","what":"Get SE from effect size and p-value — get_se","title":"Get SE from effect size and p-value — get_se","text":"Get SE effect size p-value","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_se.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get SE from effect size and p-value — get_se","text":"","code":"get_se(eff, pval)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_se.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get SE from effect size and p-value — get_se","text":"eff effect size pval p-values","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/get_se.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get SE from effect size and p-value — get_se","text":"array","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/harmonise_data.html","id":null,"dir":"Reference","previous_headings":"","what":"Harmonise the alleles and effects between the exposure and outcome — harmonise_data","title":"Harmonise the alleles and effects between the exposure and outcome — harmonise_data","text":"order perform MR effect SNP outcome exposure must harmonised relative allele.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/harmonise_data.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Harmonise the alleles and effects between the exposure and outcome — harmonise_data","text":"","code":"harmonise_data(exposure_dat, outcome_dat, action = 2)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/harmonise_data.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Harmonise the alleles and effects between the exposure and outcome — harmonise_data","text":"exposure_dat Output read_exposure_data(). outcome_dat Output extract_outcome_data(). action Level strictness dealing SNPs. action = 1: Assume alleles coded forward strand, .e. attempt flip alleles action = 2: Try infer positive strand alleles, using allele frequencies palindromes (default, conservative); action = 3: Correct strand non-palindromic SNPs, drop palindromic SNPs analysis (conservative). single value passed action applied outcomes. multiple values can supplied vector, element relating different outcome.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/harmonise_data.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Harmonise the alleles and effects between the exposure and outcome — harmonise_data","text":"Data frame harmonised effects alleles","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/harmonise_data.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Harmonise the alleles and effects between the exposure and outcome — harmonise_data","text":"Expects data format generated read_exposure_data() extract_outcome_data(). means inputs must dataframes following columns: outcome_dat: SNP beta.outcome se.outcome effect_allele.outcome other_allele.outcome eaf.outcome outcome exposure_dat: SNP beta.exposure se.exposure effect_allele.exposure other_allele.exposure eaf.exposure function tries harmonise INDELs. coded sequence strings things work smoothly. coded D/one dataset try convert sequences dataset adequate information. coded D/one dataset variant equal length INDEL alleles , variant dropped. one datasets one allele (.e. effect allele) harmonisation naturally going ambiguous variants dropped.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/harmonise_ld_dat.html","id":null,"dir":"Reference","previous_headings":"","what":"Harmonise LD matrix against summary data — harmonise_ld_dat","title":"Harmonise LD matrix against summary data — harmonise_ld_dat","text":"LD matrix returns rsid_ea_oa identifiers. Make sure oriented effect allele summary dataset. Summary dataset can exposure dataset harmonised dartaset.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/harmonise_ld_dat.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Harmonise LD matrix against summary data — harmonise_ld_dat","text":"","code":"harmonise_ld_dat(x, ld)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/harmonise_ld_dat.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Harmonise LD matrix against summary data — harmonise_ld_dat","text":"x Exposure dataset harmonised dataset ld Output ld_matrix()","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/harmonise_ld_dat.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Harmonise LD matrix against summary data — harmonise_ld_dat","text":"List exposure dataset harmonised LD matrix","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/knit_report.html","id":null,"dir":"Reference","previous_headings":"","what":"Knit report using working environment — knit_report","title":"Knit report using working environment — knit_report","text":"Warning: quite likely called within Rmd file implying recursive call knit(). generate \"duplicate label\" errors unlabelled chunks. avoid , code chunks Rmd file named. Supposedly error can also avoided setting following option: options(knitr.duplicate.label = 'allow'). tried seem help.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/knit_report.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Knit report using working environment — knit_report","text":"","code":"knit_report(input_filename, output_filename, ...)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/knit_report.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Knit report using working environment — knit_report","text":"input_filename Rmd file. output_filename Markdown HTML output file. HTML file specified using .htm, .html, .HTM .HTML file extension. html specified, similarly named markdown file also generated. output files including cache figures appear folder output_filename. ... Arguments passed knitr::knit()","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ld_matrix.html","id":null,"dir":"Reference","previous_headings":"","what":"Get LD matrix for list of SNPs — ld_matrix","title":"Get LD matrix for list of SNPs — ld_matrix","text":"function takes list SNPs searches specified super-population 1000 Genomes phase 3 reference panel. creates LD matrix r values (signed, squared). LD values respect major alleles 1000G dataset. can specify whether allele names displayed.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ld_matrix.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get LD matrix for list of SNPs — ld_matrix","text":"","code":"ld_matrix(snps, with_alleles = TRUE, pop = \"EUR\")"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ld_matrix.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get LD matrix for list of SNPs — ld_matrix","text":"snps List SNPs. with_alleles Whether append allele names SNP names. default TRUE. pop Super-population use reference panel. Default = \"EUR\". Options \"EUR\", \"SAS\", \"EAS\", \"AFR\", \"AMR\". 'legacy' also available - previously used version EUR panel slightly different set markers.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ld_matrix.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get LD matrix for list of SNPs — ld_matrix","text":"Matrix LD r values","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ld_matrix.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Get LD matrix for list of SNPs — ld_matrix","text":"data used generating LD matrix includes bi-allelic SNPs MAF > 0.01, quite possible variant want include absent. absent, automatically excluded results. can check variants present LD reference panel using ieugwasr::ld_reflookup(). function put load OpenGWAS servers, makes life difficult users, limited analyse 500 variants time. implemented method made available LD reference panels perform operation locally, see ieugwasr::ld_matrix() related vignettes details.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ldsc_h2.html","id":null,"dir":"Reference","previous_headings":"","what":"Univariate LDSC — ldsc_h2","title":"Univariate LDSC — ldsc_h2","text":"Imported help estimate sample overlap studies","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ldsc_h2.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Univariate LDSC — ldsc_h2","text":"","code":"ldsc_h2(id, ancestry = \"infer\", snpinfo = NULL, splitsize = 20000)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ldsc_h2.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Univariate LDSC — ldsc_h2","text":"id ID analyse ancestry ancestry traits 1 2 (AFR, AMR, EAS, EUR, SAS) 'infer' (default) case try guess based allele frequencies snpinfo Output ieugwasr::afl2_list(\"hapmap3\"), NULL done automatically splitsize many SNPs extract one time. Default=20000","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ldsc_h2.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Univariate LDSC — ldsc_h2","text":"model fit","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ldsc_h2.html","id":"references","dir":"Reference","previous_headings":"","what":"References","title":"Univariate LDSC — ldsc_h2","text":"Bulik-Sullivan,B.K. et al. (2015) atlas genetic correlations across human diseases traits. Nat. Genet. 47, 1236–1241. Guo,B. Wu,B. (2018) Principal component based adaptive association test multiple traits using GWAS summary statistics. bioRxiv 269597; doi: 10.1101/269597 Gua,B. Wu,B. (2019) Integrate multiple traits detect novel trait-gene association using GWAS summary data adaptive test approach. Bioinformatics. 2019 Jul 1;35(13):2251-2257. doi: 10.1093/bioinformatics/bty961. https://github.com/baolinwu/MTAR","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ldsc_h2_internal.html","id":null,"dir":"Reference","previous_headings":"","what":"Univariate LDSC — ldsc_h2_internal","title":"Univariate LDSC — ldsc_h2_internal","text":"Imported help estimate sample overlap studies","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ldsc_h2_internal.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Univariate LDSC — ldsc_h2_internal","text":"","code":"ldsc_h2_internal(Z, r2, N, W = NULL)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ldsc_h2_internal.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Univariate LDSC — ldsc_h2_internal","text":"Z summary Z-statistics M variants r2 average reference LD scores M variants N GWAS sample size variant (different across variants) W variant weight","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ldsc_h2_internal.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Univariate LDSC — ldsc_h2_internal","text":"model fit","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ldsc_rg.html","id":null,"dir":"Reference","previous_headings":"","what":"Bivariate LDSC — ldsc_rg","title":"Bivariate LDSC — ldsc_rg","text":"Imported help estimate sample overlap studies","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ldsc_rg.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Bivariate LDSC — ldsc_rg","text":"","code":"ldsc_rg(id1, id2, ancestry = \"infer\", snpinfo = NULL, splitsize = 20000)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ldsc_rg.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Bivariate LDSC — ldsc_rg","text":"id1 ID 1 analyse id2 ID 2 analyse ancestry ancestry traits 1 2 (AFR, AMR, EAS, EUR, SAS) 'infer' (default) case try guess based allele frequencies snpinfo Output ieugwasr::afl2_list(\"hapmap3\"), NULL done automatically splitsize many SNPs extract one time. Default=20000","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ldsc_rg.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Bivariate LDSC — ldsc_rg","text":"model fit","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ldsc_rg_internal.html","id":null,"dir":"Reference","previous_headings":"","what":"Bivariate LDSC — ldsc_rg_internal","title":"Bivariate LDSC — ldsc_rg_internal","text":"Imported help estimate sample overlap studies","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ldsc_rg_internal.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Bivariate LDSC — ldsc_rg_internal","text":"","code":"ldsc_rg_internal(Zs, r2, h1, h2, N1, N2, Nc = 0, W = NULL)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ldsc_rg_internal.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Bivariate LDSC — ldsc_rg_internal","text":"Zs Mx2 matrix summary Z-statistics M variants two GWAS r2 average reference LD scores M variants h1 hsq trait 1 h2 hsq trait 2 N1 sample size 1st GWAS N2 sample size 2nd GWAS Nc overlapped sample size two GWAS W variant weight","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ldsc_rg_internal.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Bivariate LDSC — ldsc_rg_internal","text":"List models","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/ldsc_rg_internal.html","id":"references","dir":"Reference","previous_headings":"","what":"References","title":"Bivariate LDSC — ldsc_rg_internal","text":"Bulik-Sullivan,B.K. et al. (2015) atlas genetic correlations across human diseases traits. Nat. Genet. 47, 1236–1241. Guo,B. Wu,B. (2018) Principal component based adaptive association test multiple traits using GWAS summary statistics. bioRxiv 269597; doi: 10.1101/269597 Gua,B. Wu,B. (2019) Integrate multiple traits detect novel trait-gene association using GWAS summary data adaptive test approach. Bioinformatics. 2019 Jul 1;35(13):2251-2257. doi: 10.1093/bioinformatics/bty961. https://github.com/baolinwu/MTAR","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/make_dat.html","id":null,"dir":"Reference","previous_headings":"","what":"Convenient function to create a harmonised dataset — make_dat","title":"Convenient function to create a harmonised dataset — make_dat","text":"Convenient function create harmonised dataset.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/make_dat.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Convenient function to create a harmonised dataset — make_dat","text":"","code":"make_dat( exposures = c(\"ieu-a-2\", \"ieu-a-301\"), outcomes = c(\"ieu-a-7\", \"ieu-a-1001\"), proxies = TRUE )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/make_dat.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Convenient function to create a harmonised dataset — make_dat","text":"exposures default c(\"ieu--2\", \"ieu--301\") (BMI LDL). outcomes default c(\"ieu--7\", \"ieu--1001\") (CHD EDU). proxies Look proxies? Default = TRUE","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/make_dat.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Convenient function to create a harmonised dataset — make_dat","text":"Harmonised data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr.html","id":null,"dir":"Reference","previous_headings":"","what":"Perform all Mendelian randomization tests — mr","title":"Perform all Mendelian randomization tests — mr","text":"Perform Mendelian randomization tests","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Perform all Mendelian randomization tests — mr","text":"","code":"mr( dat, parameters = default_parameters(), method_list = subset(mr_method_list(), use_by_default)$obj )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Perform all Mendelian randomization tests — mr","text":"dat Harmonised exposure outcome data. Output harmonise_data(). parameters Parameters used various MR methods. Default output default_parameters(). method_list List methods use analysis. See mr_method_list() details.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Perform all Mendelian randomization tests — mr","text":"List following elements: mr Table MR results extra Table extra results","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_density_plot.html","id":null,"dir":"Reference","previous_headings":"","what":"Density plot — mr_density_plot","title":"Density plot — mr_density_plot","text":"Density plot","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_density_plot.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Density plot — mr_density_plot","text":"","code":"mr_density_plot( singlesnp_results, mr_results, exponentiate = FALSE, bandwidth = \"nrd0\" )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_density_plot.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Density plot — mr_density_plot","text":"singlesnp_results mr_singlesnp(). mr_results Results mr(). exponentiate Plot exponentiated scale. default FALSE. bandwidth Density bandwidth parameter.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_density_plot.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Density plot — mr_density_plot","text":"List plots","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_egger_regression.html","id":null,"dir":"Reference","previous_headings":"","what":"Egger's regression for Mendelian randomization — mr_egger_regression","title":"Egger's regression for Mendelian randomization — mr_egger_regression","text":"Egger's regression Mendelian randomization","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_egger_regression.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Egger's regression for Mendelian randomization — mr_egger_regression","text":"","code":"mr_egger_regression(b_exp, b_out, se_exp, se_out, parameters)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_egger_regression.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Egger's regression for Mendelian randomization — mr_egger_regression","text":"b_exp Vector genetic effects exposure. b_out Vector genetic effects outcome. se_exp Standard errors genetic effects exposure. se_out Standard errors genetic effects outcome. parameters List parameters.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_egger_regression.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Egger's regression for Mendelian randomization — mr_egger_regression","text":"List following elements: b MR estimate se Standard error MR estimate pval p-value MR estimate b_i Estimate horizontal pleiotropy (intercept) se_i Standard error intercept pval_i p-value intercept Q, Q_df, Q_pval Heterogeneity stats mod Summary regression dat Original data used MR Egger regression","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_egger_regression_bootstrap.html","id":null,"dir":"Reference","previous_headings":"","what":"Run bootstrap to generate standard errors for MR — mr_egger_regression_bootstrap","title":"Run bootstrap to generate standard errors for MR — mr_egger_regression_bootstrap","text":"Run bootstrap generate standard errors MR","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_egger_regression_bootstrap.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Run bootstrap to generate standard errors for MR — mr_egger_regression_bootstrap","text":"","code":"mr_egger_regression_bootstrap(b_exp, b_out, se_exp, se_out, parameters)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_egger_regression_bootstrap.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Run bootstrap to generate standard errors for MR — mr_egger_regression_bootstrap","text":"b_exp Vector genetic effects exposure. b_out Vector genetic effects outcome. se_exp Standard errors genetic effects exposure. se_out Standard errors genetic effects outcome. parameters List parameters. Specifically, nboot parameter can specified number bootstrap replications. default parameters=list(nboot=1000).","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_egger_regression_bootstrap.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Run bootstrap to generate standard errors for MR — mr_egger_regression_bootstrap","text":"List following elements: b MR estimate se Standard error MR estimate pval p-value MR estimate b_i Estimate horizontal pleiotropy (intercept) se_i Standard error intercept pval_i p-value intercept mod Summary regression dat Original data used MR Egger regression","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_forest_plot.html","id":null,"dir":"Reference","previous_headings":"","what":"Forest plot — mr_forest_plot","title":"Forest plot — mr_forest_plot","text":"Forest plot","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_forest_plot.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Forest plot — mr_forest_plot","text":"","code":"mr_forest_plot(singlesnp_results, exponentiate = FALSE)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_forest_plot.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Forest plot — mr_forest_plot","text":"singlesnp_results mr_singlesnp(). exponentiate Plot exponential scale. default FALSE.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_forest_plot.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Forest plot — mr_forest_plot","text":"List plots","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_forest_plot_grouped.html","id":null,"dir":"Reference","previous_headings":"","what":"Grouped forest plot — mr_forest_plot_grouped","title":"Grouped forest plot — mr_forest_plot_grouped","text":"Grouped forest plot","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_forest_plot_grouped.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Grouped forest plot — mr_forest_plot_grouped","text":"","code":"mr_forest_plot_grouped( name, eff_Col = \"b\", exposure_Name = \"exposure\", outcome_Name = \"outcome\", forest_Title = \"\", outfile_Name = \"annot_FP.pdf\", left_Col_Names = c(\"Exposure\", \"Outcome\"), left_Col_Titles = NULL, right_Col_Names = c(\"p\", \"Outcome.n.case\", \"Outcome.n.control\", \"Outcome.sample.size\"), right_Col_Titles = NULL, debug = FALSE, log_ES = FALSE, decrease = TRUE, returnRobj = TRUE, se_Col = \"se\" )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_forest_plot_grouped.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Grouped forest plot — mr_forest_plot_grouped","text":"name (character) name delimited file containing results first sheet (needs headers), r object. eff_Col (character) name column delimited file contains effect sizes. exposure_Name (character) name column delimited file containing types studies. outcome_Name (character) name column delimited file containing names study. forest_Title (character) title used forest plot. outfile_Name (character) name used output file (.pdf) (.wmf). left_Col_Names (character vector) vector containing names left-hand-side annotation columns delimited file. left_Col_Titles (character vector) vector containing titles left-hand-side annotation column. right_Col_Names (character vector) vector containing names right-hand-side annotation columns delimited file. right_Col_Titles (character vector) vector containing titles right-hand-side annotation column. debug (logical) show warnings TRUE/FALSE? log_ES (logical) perform natural log transform effect sizes confidence bounds TRUE/FALSE? decrease (logical) sort studies decreasing effect sizes TRUE/FALSE? returnRobj (logical) return graph internal R object TRUE/FALSE? se_Col (character) name column giving standard error effect sizes.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_forest_plot_grouped.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Grouped forest plot — mr_forest_plot_grouped","text":"grid object giving forest plot (plot pdf)","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_funnel_plot.html","id":null,"dir":"Reference","previous_headings":"","what":"Funnel plot — mr_funnel_plot","title":"Funnel plot — mr_funnel_plot","text":"Create funnel plot single SNP analyses.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_funnel_plot.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Funnel plot — mr_funnel_plot","text":"","code":"mr_funnel_plot(singlesnp_results)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_funnel_plot.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Funnel plot — mr_funnel_plot","text":"singlesnp_results mr_singlesnp().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_funnel_plot.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Funnel plot — mr_funnel_plot","text":"List plots","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_heterogeneity.html","id":null,"dir":"Reference","previous_headings":"","what":"Get heterogeneity statistics — mr_heterogeneity","title":"Get heterogeneity statistics — mr_heterogeneity","text":"Get heterogeneity statistics.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_heterogeneity.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get heterogeneity statistics — mr_heterogeneity","text":"","code":"mr_heterogeneity( dat, parameters = default_parameters(), method_list = subset(mr_method_list(), heterogeneity_test & use_by_default)$obj )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_heterogeneity.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get heterogeneity statistics — mr_heterogeneity","text":"dat Harmonised exposure outcome data. Output harmonise_data(). parameters Parameters used various MR methods. Default output default_parameters(). method_list List methods use analysis. See mr_method_list() details.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_heterogeneity.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get heterogeneity statistics — mr_heterogeneity","text":"Data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw.html","id":null,"dir":"Reference","previous_headings":"","what":"Inverse variance weighted regression — mr_ivw","title":"Inverse variance weighted regression — mr_ivw","text":"default multiplicative random effects IVW estimate. standard error corrected dispersion Use mr_ivw_mre() function estimates correct dispersion.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Inverse variance weighted regression — mr_ivw","text":"","code":"mr_ivw(b_exp, b_out, se_exp, se_out, parameters = default_parameters())"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Inverse variance weighted regression — mr_ivw","text":"b_exp Vector genetic effects exposure. b_out Vector genetic effects outcome. se_exp Standard errors genetic effects exposure. se_out Standard errors genetic effects outcome. parameters List parameters.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Inverse variance weighted regression — mr_ivw","text":"List following elements: b MR estimate se Standard error pval p-value Q, Q_df, Q_pval Heterogeneity stats","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw_fe.html","id":null,"dir":"Reference","previous_headings":"","what":"Inverse variance weighted regression (fixed effects) — mr_ivw_fe","title":"Inverse variance weighted regression (fixed effects) — mr_ivw_fe","text":"Inverse variance weighted regression (fixed effects)","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw_fe.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Inverse variance weighted regression (fixed effects) — mr_ivw_fe","text":"","code":"mr_ivw_fe(b_exp, b_out, se_exp, se_out, parameters = default_parameters())"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw_fe.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Inverse variance weighted regression (fixed effects) — mr_ivw_fe","text":"b_exp Vector genetic effects exposure. b_out Vector genetic effects outcome. se_exp Standard errors genetic effects exposure. se_out Standard errors genetic effects outcome. parameters List parameters.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw_fe.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Inverse variance weighted regression (fixed effects) — mr_ivw_fe","text":"List following elements: b MR estimate se Standard error pval p-value Q, Q_df, Q_pval Heterogeneity stats","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw_mre.html","id":null,"dir":"Reference","previous_headings":"","what":"Inverse variance weighted regression (multiplicative random effects model) — mr_ivw_mre","title":"Inverse variance weighted regression (multiplicative random effects model) — mr_ivw_mre","text":"mr_ivw() correction dispersion.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw_mre.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Inverse variance weighted regression (multiplicative random effects model) — mr_ivw_mre","text":"","code":"mr_ivw_mre(b_exp, b_out, se_exp, se_out, parameters = default_parameters())"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw_mre.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Inverse variance weighted regression (multiplicative random effects model) — mr_ivw_mre","text":"b_exp Vector genetic effects exposure. b_out Vector genetic effects outcome. se_exp Standard errors genetic effects exposure. se_out Standard errors genetic effects outcome. parameters List parameters.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw_mre.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Inverse variance weighted regression (multiplicative random effects model) — mr_ivw_mre","text":"List following elements: b MR estimate se Standard error pval p-value Q, Q_df, Q_pval Heterogeneity stats","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw_radial.html","id":null,"dir":"Reference","previous_headings":"","what":"Radial IVW analysis — mr_ivw_radial","title":"Radial IVW analysis — mr_ivw_radial","text":"Radial IVW analysis","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw_radial.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Radial IVW analysis — mr_ivw_radial","text":"","code":"mr_ivw_radial(b_exp, b_out, se_exp, se_out, parameters = default_parameters())"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw_radial.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Radial IVW analysis — mr_ivw_radial","text":"b_exp Vector genetic effects exposure. b_out Vector genetic effects outcome. se_exp Standard errors genetic effects exposure. se_out Standard errors genetic effects outcome. parameters List parameters.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw_radial.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Radial IVW analysis — mr_ivw_radial","text":"List following elements: b causal effect estimate se standard error pval p-value","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_leaveoneout.html","id":null,"dir":"Reference","previous_headings":"","what":"Leave one out sensitivity analysis — mr_leaveoneout","title":"Leave one out sensitivity analysis — mr_leaveoneout","text":"Leave one sensitivity analysis","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_leaveoneout.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Leave one out sensitivity analysis — mr_leaveoneout","text":"","code":"mr_leaveoneout(dat, parameters = default_parameters(), method = mr_ivw)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_leaveoneout.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Leave one out sensitivity analysis — mr_leaveoneout","text":"dat Output harmonise_data(). parameters List parameters. method Choose method use. default mr_ivw.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_leaveoneout.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Leave one out sensitivity analysis — mr_leaveoneout","text":"List data frames","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_leaveoneout_plot.html","id":null,"dir":"Reference","previous_headings":"","what":"Plot results from leaveoneout analysis — mr_leaveoneout_plot","title":"Plot results from leaveoneout analysis — mr_leaveoneout_plot","text":"Plot results leaveoneout analysis.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_leaveoneout_plot.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Plot results from leaveoneout analysis — mr_leaveoneout_plot","text":"","code":"mr_leaveoneout_plot(leaveoneout_results)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_leaveoneout_plot.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Plot results from leaveoneout analysis — mr_leaveoneout_plot","text":"leaveoneout_results Output mr_leaveoneout().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_leaveoneout_plot.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Plot results from leaveoneout analysis — mr_leaveoneout_plot","text":"List plots","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_median.html","id":null,"dir":"Reference","previous_headings":"","what":"MR median estimators — mr_median","title":"MR median estimators — mr_median","text":"MR median estimators","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_median.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"MR median estimators — mr_median","text":"","code":"mr_median(dat, parameters = default_parameters())"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_median.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"MR median estimators — mr_median","text":"dat Output harmonise_data(). parameters List parameters. default default_parameters().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_median.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"MR median estimators — mr_median","text":"data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_meta_fixed.html","id":null,"dir":"Reference","previous_headings":"","what":"Perform 2 sample IV using fixed effects meta analysis and delta method for standard errors — mr_meta_fixed","title":"Perform 2 sample IV using fixed effects meta analysis and delta method for standard errors — mr_meta_fixed","text":"Perform 2 sample IV using fixed effects meta analysis delta method standard errors","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_meta_fixed.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Perform 2 sample IV using fixed effects meta analysis and delta method for standard errors — mr_meta_fixed","text":"","code":"mr_meta_fixed(b_exp, b_out, se_exp, se_out, parameters)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_meta_fixed.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Perform 2 sample IV using fixed effects meta analysis and delta method for standard errors — mr_meta_fixed","text":"b_exp Vector genetic effects exposure. b_out Vector genetic effects outcome. se_exp Standard errors genetic effects exposure. se_out Standard errors genetic effects outcome. parameters List parameters.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_meta_fixed.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Perform 2 sample IV using fixed effects meta analysis and delta method for standard errors — mr_meta_fixed","text":"List following elements: b causal effect estimate se standard error pval p-value Q, Q_df, Q_pval Heterogeneity stats","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_meta_fixed_simple.html","id":null,"dir":"Reference","previous_headings":"","what":"Perform 2 sample IV using simple standard error — mr_meta_fixed_simple","title":"Perform 2 sample IV using simple standard error — mr_meta_fixed_simple","text":"Perform 2 sample IV using simple standard error","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_meta_fixed_simple.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Perform 2 sample IV using simple standard error — mr_meta_fixed_simple","text":"","code":"mr_meta_fixed_simple(b_exp, b_out, se_exp, se_out, parameters)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_meta_fixed_simple.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Perform 2 sample IV using simple standard error — mr_meta_fixed_simple","text":"b_exp Vector genetic effects exposure. b_out Vector genetic effects outcome. se_exp Standard errors genetic effects exposure. se_out Standard errors genetic effects outcome. parameters List parameters.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_meta_fixed_simple.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Perform 2 sample IV using simple standard error — mr_meta_fixed_simple","text":"List following elements: b causal effect estimate se standard error pval p-value","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_meta_random.html","id":null,"dir":"Reference","previous_headings":"","what":"Perform 2 sample IV using random effects meta analysis and delta method for standard errors — mr_meta_random","title":"Perform 2 sample IV using random effects meta analysis and delta method for standard errors — mr_meta_random","text":"Perform 2 sample IV using random effects meta analysis delta method standard errors","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_meta_random.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Perform 2 sample IV using random effects meta analysis and delta method for standard errors — mr_meta_random","text":"","code":"mr_meta_random(b_exp, b_out, se_exp, se_out, parameters)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_meta_random.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Perform 2 sample IV using random effects meta analysis and delta method for standard errors — mr_meta_random","text":"b_exp Vector genetic effects exposure. b_out Vector genetic effects outcome. se_exp Standard errors genetic effects exposure. se_out Standard errors genetic effects outcome. parameters List parameters.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_meta_random.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Perform 2 sample IV using random effects meta analysis and delta method for standard errors — mr_meta_random","text":"List following elements: b causal effect estimate se standard error pval p-value Q, Q_df, Q_pval Heterogeneity stats","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_method_list.html","id":null,"dir":"Reference","previous_headings":"","what":"Get list of available MR methods — mr_method_list","title":"Get list of available MR methods — mr_method_list","text":"Get list available MR methods","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_method_list.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get list of available MR methods — mr_method_list","text":"","code":"mr_method_list()"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_method_list.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get list of available MR methods — mr_method_list","text":"character vector method names","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_mode.html","id":null,"dir":"Reference","previous_headings":"","what":"MR mode estimators — mr_mode","title":"MR mode estimators — mr_mode","text":"Perform simple, weighted, penalised modes, well versions use NOME assumption.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_mode.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"MR mode estimators — mr_mode","text":"","code":"mr_mode(dat, parameters = default_parameters(), mode_method = \"all\")"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_mode.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"MR mode estimators — mr_mode","text":"dat Output harmonise_data(). parameters List parameters. default default_parameters(). mode_method default \"\". choices 'Simple mode', 'Weighted mode', 'Penalised mode', 'Simple mode (NOME)', 'Weighted mode (NOME)'.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_mode.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"MR mode estimators — mr_mode","text":"data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_moe.html","id":null,"dir":"Reference","previous_headings":"","what":"Mixture of experts — mr_moe","title":"Mixture of experts — mr_moe","text":"Based method described https://www.biorxiv.org/content/10.1101/173682v2. MR methods applied summary set, can use mixture experts predict method likely accurate.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_moe.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Mixture of experts — mr_moe","text":"","code":"mr_moe(res, rf)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_moe.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Mixture of experts — mr_moe","text":"res Output mr_wrapper(). rf trained random forest methods. available download https://www.dropbox.com/s/5la7y38od95swcf/rf.rdata?dl=0.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_moe.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Mixture of experts — mr_moe","text":"List","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_moe.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Mixture of experts — mr_moe","text":"mr_moe() function modifies estimates item list results mr_wrapper() function. three things: Adds MOE column, predictor method well performs terms high power low type 1 error (scaled 0-1, 1 best performance). renames methods estimating method + instrument selection method. 4 instrument selection methods: Tophits (.e. filtering), directional filtering (DF, unthresholded version Steiger filtering), heterogeneity filtering (HF, removing instruments make substantial (p < 0.05) contributions Cochran's Q statistic), DF + HF DF applied HF applied top . orders table order best performing method. Note mixture experts trained datasets least 5 SNPs. dataset fewer 5 SNPs function might return errors.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_moe.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Mixture of experts — mr_moe","text":"","code":"if (FALSE) { # \\dontrun{ # Example of body mass index on coronary heart disease # Extract and harmonise data a <- extract_instruments(\"ieu-a-2\") b <- extract_outcome_data(a$SNP, 7) dat <- harmonise_data(a, b) # Apply all MR methods r <- mr_wrapper(dat) # Load the rf object containing the trained models load(\"rf.rdata\") # Update the results with mixture of experts r <- mr_moe(r, rf) # Now you can view the estimates, and see that they have # been sorted in order from most likely to least likely to # be accurate, based on MOE prediction r[[1]]$estimates } # }"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_penalised_weighted_median.html","id":null,"dir":"Reference","previous_headings":"","what":"Penalised weighted median MR — mr_penalised_weighted_median","title":"Penalised weighted median MR — mr_penalised_weighted_median","text":"Modification standard weighted median MR Updated based Burgess 2016 \"Robust instrumental variable methods using multiple candidate instruments application Mendelian randomization\"","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_penalised_weighted_median.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Penalised weighted median MR — mr_penalised_weighted_median","text":"","code":"mr_penalised_weighted_median( b_exp, b_out, se_exp, se_out, parameters = default_parameters() )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_penalised_weighted_median.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Penalised weighted median MR — mr_penalised_weighted_median","text":"b_exp Vector genetic effects exposure b_out Vector genetic effects outcome se_exp Standard errors genetic effects exposure se_out Standard errors genetic effects outcome parameters List containing penk - Constant term penalisation, nboot - number bootstrap replications calculate SE. default_parameters() sets parameters=list(penk=20, nboot=1000).","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_penalised_weighted_median.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Penalised weighted median MR — mr_penalised_weighted_median","text":"List following elements: b MR estimate se Standard error pval p-value","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_pleiotropy_test.html","id":null,"dir":"Reference","previous_headings":"","what":"Test for horizontal pleiotropy in MR analysis — mr_pleiotropy_test","title":"Test for horizontal pleiotropy in MR analysis — mr_pleiotropy_test","text":"Performs MR Egger returns intercept values.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_pleiotropy_test.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Test for horizontal pleiotropy in MR analysis — mr_pleiotropy_test","text":"","code":"mr_pleiotropy_test(dat)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_pleiotropy_test.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Test for horizontal pleiotropy in MR analysis — mr_pleiotropy_test","text":"dat Harmonised exposure outcome data. Output harmonise_data().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_pleiotropy_test.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Test for horizontal pleiotropy in MR analysis — mr_pleiotropy_test","text":"data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_raps.html","id":null,"dir":"Reference","previous_headings":"","what":"Robust adjusted profile score — mr_raps","title":"Robust adjusted profile score — mr_raps","text":"Robust adjusted profile score","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_raps.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Robust adjusted profile score — mr_raps","text":"","code":"mr_raps(b_exp, b_out, se_exp, se_out, parameters = default_parameters())"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_raps.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Robust adjusted profile score — mr_raps","text":"b_exp Vector genetic effects exposure. b_out Vector genetic effects outcome. se_exp Standard errors genetic effects exposure. se_out Standard errors genetic effects outcome. parameters list parameters. Specifically, .dispersion loss.function. .dispersion logical concerning model consider overdispersion (systematic pleiotropy). loss.function allows using either squared error loss (\"l2\") robust loss functions/scores (\"huber\" \"tukey\"). default parameters=list(overdispersion = TRUE, loss.function = \"tukey\").","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_raps.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Robust adjusted profile score — mr_raps","text":"List following elements: b MR estimate se Standard error pval p-value nsnp Number SNPs","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_raps.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Robust adjusted profile score — mr_raps","text":"function calls mr.raps package. Please refer documentation package detail.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_raps.html","id":"references","dir":"Reference","previous_headings":"","what":"References","title":"Robust adjusted profile score — mr_raps","text":"Qingyuan Zhao, Jingshu Wang, Jack Bowden, Dylan S. Small. Statistical inference two-sample summary-data Mendelian randomization using robust adjusted profile score. Forthcoming.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_report.html","id":null,"dir":"Reference","previous_headings":"","what":"Generate MR report — mr_report","title":"Generate MR report — mr_report","text":"Using output mr() function report generate report containing tables graphs summarising results. separate report produced exposure - outcome pair analysed.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_report.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Generate MR report — mr_report","text":"","code":"mr_report( dat, output_path = \".\", output_type = \"html\", author = \"Analyst\", study = \"Two Sample MR\", path = system.file(\"reports\", package = \"TwoSampleMR\"), ... )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_report.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Generate MR report — mr_report","text":"dat Output harmonise_data() output_path Directory reports saved. output_type Choose \"html\" \"md\". Default \"html\". output files including cache figures appear folder specified output_path. author Author name. study Study title. path filepath report template. ... Extra options passed knitr::knit().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker.html","id":null,"dir":"Reference","previous_headings":"","what":"MR Rucker framework — mr_rucker","title":"MR Rucker framework — mr_rucker","text":"MR Rucker framework.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"MR Rucker framework — mr_rucker","text":"","code":"mr_rucker(dat, parameters = default_parameters())"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"MR Rucker framework — mr_rucker","text":"dat Output harmonise_data(). parameters List Qthresh determining transition models, alpha values calculating confidence intervals. Defaults 0.05 default_parameters().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"MR Rucker framework — mr_rucker","text":"list","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker_bootstrap.html","id":null,"dir":"Reference","previous_headings":"","what":"Run rucker with bootstrap estimates — mr_rucker_bootstrap","title":"Run rucker with bootstrap estimates — mr_rucker_bootstrap","text":"Run Rucker bootstrap estimates.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker_bootstrap.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Run rucker with bootstrap estimates — mr_rucker_bootstrap","text":"","code":"mr_rucker_bootstrap(dat, parameters = default_parameters())"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker_bootstrap.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Run rucker with bootstrap estimates — mr_rucker_bootstrap","text":"dat Output harmonise_data(). parameters List parameters. default default_parameters().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker_bootstrap.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Run rucker with bootstrap estimates — mr_rucker_bootstrap","text":"List","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker_cooksdistance.html","id":null,"dir":"Reference","previous_headings":"","what":"MR Rucker with outliers automatically detected and removed — mr_rucker_cooksdistance","title":"MR Rucker with outliers automatically detected and removed — mr_rucker_cooksdistance","text":"Uses Cook's distance D > 4/nsnp iteratively remove outliers.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker_cooksdistance.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"MR Rucker with outliers automatically detected and removed — mr_rucker_cooksdistance","text":"","code":"mr_rucker_cooksdistance(dat, parameters = default_parameters())"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker_cooksdistance.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"MR Rucker with outliers automatically detected and removed — mr_rucker_cooksdistance","text":"dat Output harmonise_data(). parameters List parameters. default default_parameters().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker_cooksdistance.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"MR Rucker with outliers automatically detected and removed — mr_rucker_cooksdistance","text":"List","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker_jackknife.html","id":null,"dir":"Reference","previous_headings":"","what":"Run rucker with jackknife estimates — mr_rucker_jackknife","title":"Run rucker with jackknife estimates — mr_rucker_jackknife","text":"Run rucker jackknife estimates.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker_jackknife.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Run rucker with jackknife estimates — mr_rucker_jackknife","text":"","code":"mr_rucker_jackknife(dat, parameters = default_parameters())"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker_jackknife.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Run rucker with jackknife estimates — mr_rucker_jackknife","text":"dat Output harmonise_data. parameters List parameters. default default_parameters().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker_jackknife.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Run rucker with jackknife estimates — mr_rucker_jackknife","text":"List","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_scatter_plot.html","id":null,"dir":"Reference","previous_headings":"","what":"Create scatter plot with lines showing the causal estimate for different MR tests — mr_scatter_plot","title":"Create scatter plot with lines showing the causal estimate for different MR tests — mr_scatter_plot","text":"Requires dev version ggplot2","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_scatter_plot.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Create scatter plot with lines showing the causal estimate for different MR tests — mr_scatter_plot","text":"","code":"mr_scatter_plot(mr_results, dat)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_scatter_plot.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Create scatter plot with lines showing the causal estimate for different MR tests — mr_scatter_plot","text":"mr_results Output mr(). dat Output harmonise_data().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_scatter_plot.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Create scatter plot with lines showing the causal estimate for different MR tests — mr_scatter_plot","text":"List plots","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_sign.html","id":null,"dir":"Reference","previous_headings":"","what":"MR sign test — mr_sign","title":"MR sign test — mr_sign","text":"Tests often SNP-exposure SNP-outcome signs concordant. avoid problem averaging SNPs, can suffer bias due outliers strong effects; avoid excluding SNPs implicit median mode based estimators. effect estimate interpreted effect size - proportion SNP-exposure SNP-outcome effects concordant signs. e.g. +1 means sign, -1 means opposite signs, 0 means equal number concordant discordant signs. Restricted work 6 valid SNPs.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_sign.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"MR sign test — mr_sign","text":"","code":"mr_sign(b_exp, b_out, se_exp = NULL, se_out = NULL, parameters = NULL)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_sign.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"MR sign test — mr_sign","text":"b_exp Vector genetic effects exposure b_out Vector genetic effects outcome se_exp required se_out required parameters required","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_sign.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"MR sign test — mr_sign","text":"List following elements: b Concordance (see description) se NA pval p-value nsnp Number SNPs (excludes NAs effect estimates 0)","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_simple_median.html","id":null,"dir":"Reference","previous_headings":"","what":"Simple median method — mr_simple_median","title":"Simple median method — mr_simple_median","text":"Perform MR using summary statistics. Bootstraps used calculate standard error.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_simple_median.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Simple median method — mr_simple_median","text":"","code":"mr_simple_median( b_exp, b_out, se_exp, se_out, parameters = default_parameters() )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_simple_median.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Simple median method — mr_simple_median","text":"b_exp Vector genetic effects exposure. b_out Vector genetic effects outcome. se_exp Standard errors genetic effects exposure. se_out Standard errors genetic effects outcome. parameters number bootstrap replications used calculate SE can set parameters=list(nboot = 1000). default list(nboot=1000).","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_simple_median.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Simple median method — mr_simple_median","text":"List following elements: b MR estimate se Standard error pval p-value nsnp number SNPs","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_simple_mode.html","id":null,"dir":"Reference","previous_headings":"","what":"MR simple mode estimator — mr_simple_mode","title":"MR simple mode estimator — mr_simple_mode","text":"MR simple mode estimator","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_simple_mode.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"MR simple mode estimator — mr_simple_mode","text":"","code":"mr_simple_mode(b_exp, b_out, se_exp, se_out, parameters = default_parameters())"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_simple_mode.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"MR simple mode estimator — mr_simple_mode","text":"b_exp Vector genetic effects exposure b_out Vector genetic effects outcome se_exp Standard errors genetic effects exposure se_out Standard errors genetic effects outcome parameters List containing phi - Bandwidth parameter, nboot - number bootstraps calculate SE. default_parameters() sets list(phi=1, nboot=1000).","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_simple_mode.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"MR simple mode estimator — mr_simple_mode","text":"List following elements: b MR estimate se Standard error pval p-value","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_simple_mode_nome.html","id":null,"dir":"Reference","previous_headings":"","what":"MR simple mode estimator (NOME) — mr_simple_mode_nome","title":"MR simple mode estimator (NOME) — mr_simple_mode_nome","text":"MR simple mode estimator (NOME).","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_simple_mode_nome.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"MR simple mode estimator (NOME) — mr_simple_mode_nome","text":"","code":"mr_simple_mode_nome( b_exp, b_out, se_exp, se_out, parameters = default_parameters() )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_simple_mode_nome.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"MR simple mode estimator (NOME) — mr_simple_mode_nome","text":"b_exp Vector genetic effects exposure b_out Vector genetic effects outcome se_exp Standard errors genetic effects exposure se_out Standard errors genetic effects outcome parameters List containing phi - Bandwidth parameter, nboot - number bootstraps calculate SE. default_parameters() sets list(phi=1, nboot=1000).","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_simple_mode_nome.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"MR simple mode estimator (NOME) — mr_simple_mode_nome","text":"List following elements: b MR estimate se Standard error pval p-value","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_singlesnp.html","id":null,"dir":"Reference","previous_headings":"","what":"Perform 2 sample MR on each SNP individually — mr_singlesnp","title":"Perform 2 sample MR on each SNP individually — mr_singlesnp","text":"Perform 2 sample MR SNP individually","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_singlesnp.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Perform 2 sample MR on each SNP individually — mr_singlesnp","text":"","code":"mr_singlesnp( dat, parameters = default_parameters(), single_method = \"mr_wald_ratio\", all_method = c(\"mr_ivw\", \"mr_egger_regression\") )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_singlesnp.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Perform 2 sample MR on each SNP individually — mr_singlesnp","text":"dat Output harmonise_data(). parameters List parameters. default default_parameters(). single_method Function use MR analysis. default \"mr_wald_ratio\". all_method Functions use MR analysis. default c(\"mr_ivw\", \"mr_egger_regression\").","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_singlesnp.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Perform 2 sample MR on each SNP individually — mr_singlesnp","text":"List data frames","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_steiger.html","id":null,"dir":"Reference","previous_headings":"","what":"MR Steiger test of directionality — mr_steiger","title":"MR Steiger test of directionality — mr_steiger","text":"statistical test whether assumption exposure causes outcome valid","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_steiger.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"MR Steiger test of directionality — mr_steiger","text":"","code":"mr_steiger(p_exp, p_out, n_exp, n_out, r_exp, r_out, r_xxo = 1, r_yyo = 1, ...)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_steiger.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"MR Steiger test of directionality — mr_steiger","text":"p_exp Vector p-values SNP-exposure p_out Vector p-values SNP-outcome n_exp Sample sizes p_exp n_out Sample sizes p_out r_exp Vector absolute correlations SNP-exposure r_out Vector absolute correlations SNP-outcome r_xxo Measurememt precision exposure r_yyo Measurement precision outcome ... arguments passed lattice::wireframe()","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_steiger.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"MR Steiger test of directionality — mr_steiger","text":"List following elements: r2_exp Estimated variance explained x r2_out Estimated variance explained y r2_exp_adj Predicted variance explained x accounting estimated measurement error r2_out_adj Predicted variance explained y accounting estimated measurement error correct_causal_direction TRUE/FALSE steiger_test p-value inference direction correct_causal_direction_adj TRUE/FALSE, direction causality given measurement error parameters steiger_test_adj p-value inference direction causality given measurement error parameters vz Total volume error parameter space vz0 Volume parameter space gives incorrect answer vz1 Volume paramtere space gives correct answer sensitivity_ratio Ratio vz1/vz0. Higher means inferred direction less susceptible measurement error sensitivity_plot Plot parameter space causal directions measurement error","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_steiger2.html","id":null,"dir":"Reference","previous_headings":"","what":"MR Steiger test of directionality — mr_steiger2","title":"MR Steiger test of directionality — mr_steiger2","text":"statistical test whether assumption exposure causes outcome valid","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_steiger2.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"MR Steiger test of directionality — mr_steiger2","text":"","code":"mr_steiger2(r_exp, r_out, n_exp, n_out, r_xxo = 1, r_yyo = 1, ...)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_steiger2.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"MR Steiger test of directionality — mr_steiger2","text":"r_exp Vector correlations SNP-exposure r_out Vector correlations SNP-outcome n_exp Sample sizes p_exp n_out Sample sizes p_out r_xxo Measurememt precision exposure r_yyo Measurement precision outcome ... arguments passed lattice::wireframe()","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_steiger2.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"MR Steiger test of directionality — mr_steiger2","text":"List following elements: r2_exp Estimated variance explained x r2_out Estimated variance explained y r2_exp_adj Predicted variance explained x accounting estimated measurement error r2_out_adj Predicted variance explained y accounting estimated measurement error correct_causal_direction TRUE/FALSE steiger_test p-value inference direction correct_causal_direction_adj TRUE/FALSE, direction causality given measurement error parameters steiger_test_adj p-value inference direction causality given measurement error parameters vz Total volume error parameter space vz0 Volume parameter space gives incorrect answer vz1 Volume paramtere space gives correct answer sensitivity_ratio Ratio vz1/vz0. Higher means inferred direction less susceptible measurement error sensitivity_plot Plot parameter space causal directions measurement error","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_two_sample_ml.html","id":null,"dir":"Reference","previous_headings":"","what":"Maximum likelihood MR method — mr_two_sample_ml","title":"Maximum likelihood MR method — mr_two_sample_ml","text":"Maximum likelihood MR method","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_two_sample_ml.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Maximum likelihood MR method — mr_two_sample_ml","text":"","code":"mr_two_sample_ml(b_exp, b_out, se_exp, se_out, parameters)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_two_sample_ml.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Maximum likelihood MR method — mr_two_sample_ml","text":"b_exp Vector genetic effects exposure. b_out Vector genetic effects outcome. se_exp Standard errors genetic effects exposure. se_out Standard errors genetic effects outcome. parameters List parameters.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_two_sample_ml.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Maximum likelihood MR method — mr_two_sample_ml","text":"List following elements: b causal effect estimate se standard error pval p-value Q, Q_df, Q_pval Heterogeneity stats","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_uwr.html","id":null,"dir":"Reference","previous_headings":"","what":"Unweighted regression — mr_uwr","title":"Unweighted regression — mr_uwr","text":"default multiplicative random effects IVW estimate. standard error corrected dispersion Use mr_ivw_mre() function estimates correct dispersion.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_uwr.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Unweighted regression — mr_uwr","text":"","code":"mr_uwr(b_exp, b_out, se_exp, se_out, parameters = default_parameters())"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_uwr.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Unweighted regression — mr_uwr","text":"b_exp Vector genetic effects exposure. b_out Vector genetic effects outcome. se_exp Standard errors genetic effects exposure. se_out Standard errors genetic effects outcome. parameters List parameters. default default_parameters().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_uwr.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Unweighted regression — mr_uwr","text":"List following elements: b MR estimate se Standard error pval p-value Q, Q_df, Q_pval Heterogeneity stats","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_wald_ratio.html","id":null,"dir":"Reference","previous_headings":"","what":"Perform 2 sample IV using Wald ratio. — mr_wald_ratio","title":"Perform 2 sample IV using Wald ratio. — mr_wald_ratio","text":"Perform 2 sample IV using Wald ratio.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_wald_ratio.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Perform 2 sample IV using Wald ratio. — mr_wald_ratio","text":"","code":"mr_wald_ratio(b_exp, b_out, se_exp, se_out, parameters)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_wald_ratio.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Perform 2 sample IV using Wald ratio. — mr_wald_ratio","text":"b_exp Vector genetic effects exposure. b_out Vector genetic effects outcome. se_exp Standard errors genetic effects exposure. se_out Standard errors genetic effects outcome. parameters List parameters.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_wald_ratio.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Perform 2 sample IV using Wald ratio. — mr_wald_ratio","text":"List following elements: b causal effect estimate se standard error pval p-value nsnp 1","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_weighted_median.html","id":null,"dir":"Reference","previous_headings":"","what":"Weighted median method — mr_weighted_median","title":"Weighted median method — mr_weighted_median","text":"Perform MR using summary statistics. Bootstraps used calculate standard error.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_weighted_median.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Weighted median method — mr_weighted_median","text":"","code":"mr_weighted_median( b_exp, b_out, se_exp, se_out, parameters = default_parameters() )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_weighted_median.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Weighted median method — mr_weighted_median","text":"b_exp Vector genetic effects exposure. b_out Vector genetic effects outcome. se_exp Standard errors genetic effects exposure. se_out Standard errors genetic effects outcome. parameters default default_parameters(). Specify number bootstrap replications calculate SE nboot. default list(nboot=1000).","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_weighted_median.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Weighted median method — mr_weighted_median","text":"List following elements: b MR estimate se Standard error pval p-value","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_weighted_mode.html","id":null,"dir":"Reference","previous_headings":"","what":"MR weighted mode estimator — mr_weighted_mode","title":"MR weighted mode estimator — mr_weighted_mode","text":"MR weighted mode estimator","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_weighted_mode.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"MR weighted mode estimator — mr_weighted_mode","text":"","code":"mr_weighted_mode( b_exp, b_out, se_exp, se_out, parameters = default_parameters() )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_weighted_mode.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"MR weighted mode estimator — mr_weighted_mode","text":"b_exp Vector genetic effects exposure b_out Vector genetic effects outcome se_exp Standard errors genetic effects exposure se_out Standard errors genetic effects outcome parameters List containing phi - Bandwidth parameter, nboot - number bootstraps calculate SE. default_parameters() sets list(phi=1, nboot=1000).","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_weighted_mode.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"MR weighted mode estimator — mr_weighted_mode","text":"List following elements: b MR estimate se Standard error pval p-value","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_weighted_mode_nome.html","id":null,"dir":"Reference","previous_headings":"","what":"MR weighted mode estimator (NOME) — mr_weighted_mode_nome","title":"MR weighted mode estimator (NOME) — mr_weighted_mode_nome","text":"Weighted mode estimator","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_weighted_mode_nome.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"MR weighted mode estimator (NOME) — mr_weighted_mode_nome","text":"","code":"mr_weighted_mode_nome( b_exp, b_out, se_exp, se_out, parameters = default_parameters() )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_weighted_mode_nome.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"MR weighted mode estimator (NOME) — mr_weighted_mode_nome","text":"b_exp Vector genetic effects exposure b_out Vector genetic effects outcome se_exp Standard errors genetic effects exposure se_out Standard errors genetic effects outcome parameters List containing phi - Bandwidth parameter, nboot - number bootstraps calculate SE. default_parameters() sets list(phi=1, nboot=1000).","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_weighted_mode_nome.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"MR weighted mode estimator (NOME) — mr_weighted_mode_nome","text":"List following elements: b MR estimate se Standard error pval p-value","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_wrapper.html","id":null,"dir":"Reference","previous_headings":"","what":"Perform full set of MR analyses — mr_wrapper","title":"Perform full set of MR analyses — mr_wrapper","text":"Perform full set MR analyses","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_wrapper.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Perform full set of MR analyses — mr_wrapper","text":"","code":"mr_wrapper(dat, parameters = default_parameters())"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_wrapper.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Perform full set of MR analyses — mr_wrapper","text":"dat Output harmonise_data(). parameters Parameters pass MR functions. Output default_parameters() used default.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mr_wrapper.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Perform full set of MR analyses — mr_wrapper","text":"list","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_basic.html","id":null,"dir":"Reference","previous_headings":"","what":"Perform basic multivariable MR — mv_basic","title":"Perform basic multivariable MR — mv_basic","text":"Performs initial multivariable MR analysis Burgess et al 2015. exposure outcome residualised exposures, unweighted regression applied.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_basic.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Perform basic multivariable MR — mv_basic","text":"","code":"mv_basic(mvdat, pval_threshold = 5e-08)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_basic.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Perform basic multivariable MR — mv_basic","text":"mvdat Output mv_harmonise_data(). pval_threshold P-value threshold include instruments. default 5e-8.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_basic.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Perform basic multivariable MR — mv_basic","text":"List results","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_extract_exposures.html","id":null,"dir":"Reference","previous_headings":"","what":"Extract exposure variables for multivariable MR — mv_extract_exposures","title":"Extract exposure variables for multivariable MR — mv_extract_exposures","text":"Requires list IDs available_outcomes. ID, extracts instruments. , gets full list instruments extracts SNPs every exposure. Finally, keeps SNPs ) independent b) present exposures, harmonises strand.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_extract_exposures.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Extract exposure variables for multivariable MR — mv_extract_exposures","text":"","code":"mv_extract_exposures( id_exposure, clump_r2 = 0.001, clump_kb = 10000, harmonise_strictness = 2, opengwas_jwt = ieugwasr::get_opengwas_jwt(), find_proxies = TRUE, force_server = FALSE, pval_threshold = 5e-08, pop = \"EUR\", plink_bin = NULL, bfile = NULL )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_extract_exposures.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Extract exposure variables for multivariable MR — mv_extract_exposures","text":"id_exposure Array IDs (e.g. c(299, 300, 302) HDL, LDL, trigs) clump_r2 default 0.01. clump_kb default 10000. harmonise_strictness See action option harmonise_data(). default 2. opengwas_jwt Used authenticate protected endpoints. Login https://api.opengwas.io obtain jwt. Provide jwt string , store .Renviron keyname OPENGWAS_JWT. find_proxies Look proxies? slows everything accurate. default TRUE. force_server Whether search pre-clumped dataset re-extract clump directly server. default FALSE. pval_threshold Instrument detection p-value threshold. Default = 5e-8 pop 1000 genomes super population use clumping using server plink_bin NULL bfile NULL detect packaged plink binary specific OS. Otherwise specify path plink binary. Default = NULL bfile provided use API. Default = NULL","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_extract_exposures.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Extract exposure variables for multivariable MR — mv_extract_exposures","text":"data frame exposure_dat format","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_extract_exposures_local.html","id":null,"dir":"Reference","previous_headings":"","what":"Attempt to perform MVMR using local data — mv_extract_exposures_local","title":"Attempt to perform MVMR using local data — mv_extract_exposures_local","text":"Allows read summary data text files format multivariable exposure dataset.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_extract_exposures_local.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Attempt to perform MVMR using local data — mv_extract_exposures_local","text":"","code":"mv_extract_exposures_local( filenames_exposure, sep = \" \", phenotype_col = \"Phenotype\", snp_col = \"SNP\", beta_col = \"beta\", se_col = \"se\", eaf_col = \"eaf\", effect_allele_col = \"effect_allele\", other_allele_col = \"other_allele\", pval_col = \"pval\", units_col = \"units\", ncase_col = \"ncase\", ncontrol_col = \"ncontrol\", samplesize_col = \"samplesize\", gene_col = \"gene\", id_col = \"id\", min_pval = 1e-200, log_pval = FALSE, pval_threshold = 5e-08, plink_bin = NULL, bfile = NULL, clump_r2 = 0.001, clump_kb = 10000, pop = \"EUR\", harmonise_strictness = 2 )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_extract_exposures_local.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Attempt to perform MVMR using local data — mv_extract_exposures_local","text":"filenames_exposure Filenames exposure dataset. Must header least SNP column present. Following arguments used determining read filename clumping etc. sep Specify delimeter file. default space, .e. sep=\" \". length 1 use sep value exposure dataset. can provide vector values, one exposure dataset, values different across datasets. applies dataset-formatting options listed . phenotype_col Optional column name column phenotype name corresponding SNP. present created value \"Outcome\". Default \"Phenotype\". snp_col Required name column SNP rs IDs. default \"SNP\". beta_col Required MR. Name column effect sizes. default \"beta\". se_col Required MR. Name column standard errors. default \"se\". eaf_col Required MR. Name column effect allele frequency. default \"eaf\". effect_allele_col Required MR. Name column effect allele. Must \"\", \"C\", \"T\" \"G\". default \"effect_allele\". other_allele_col Required MR. Name column non effect allele. Must \"\", \"C\", \"T\" \"G\". default \"other_allele\". pval_col Required enrichment tests. Name column p-value. default \"pval\". units_col Optional column name units. default \"units\". ncase_col Optional column name number cases. default \"ncase\". ncontrol_col Optional column name number controls. default \"ncontrol\". samplesize_col Optional column name sample size. default \"samplesize\". gene_col Optional column name gene name. default \"gene\". id_col Optional column name give dataset ID. generated automatically provided every trait / unit combination. default \"id\". min_pval Minimum allowed p-value. default 1e-200. log_pval pval -log10(P). default FALSE. pval_threshold Default=5e-8 clumping plink_bin NULL bfile NULL detect packaged plink binary specific OS. Otherwise specify path plink binary. Default = NULL bfile provided use API. Default = NULL clump_r2 Default=0.001 clumping clump_kb Default=10000 clumping pop 1000 genomes super population use clumping using server harmonise_strictness See action argument harmonise_data(). Default=2","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_extract_exposures_local.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Attempt to perform MVMR using local data — mv_extract_exposures_local","text":"List","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_extract_exposures_local.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Attempt to perform MVMR using local data — mv_extract_exposures_local","text":"Note can provide array column names column, length filenames_exposure","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_harmonise_data.html","id":null,"dir":"Reference","previous_headings":"","what":"Harmonise exposure and outcome for multivariable MR — mv_harmonise_data","title":"Harmonise exposure and outcome for multivariable MR — mv_harmonise_data","text":"Harmonise exposure outcome multivariable MR","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_harmonise_data.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Harmonise exposure and outcome for multivariable MR — mv_harmonise_data","text":"","code":"mv_harmonise_data(exposure_dat, outcome_dat, harmonise_strictness = 2)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_harmonise_data.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Harmonise exposure and outcome for multivariable MR — mv_harmonise_data","text":"exposure_dat Output mv_extract_exposures(). outcome_dat Output extract_outcome_data(exposure_dat$SNP, id_output). harmonise_strictness See action option harmonise_data(). default 2.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_harmonise_data.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Harmonise exposure and outcome for multivariable MR — mv_harmonise_data","text":"List vectors matrices required mv analysis. exposure_beta matrix beta coefficients, rows correspond SNPs columns correspond exposures. exposure_se exposure_beta, standard errors. exposure_pval exposure_beta, p-values. expname data frame two variables, id.exposure exposure character strings. outcome_beta array effects outcome, corresponding SNPs exposure_beta. outcome_se array standard errors outcome. outcome_pval array p-values outcome. outname data frame two variables, id.outcome outcome character strings.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_ivw.html","id":null,"dir":"Reference","previous_headings":"","what":"Perform IVW multivariable MR — mv_ivw","title":"Perform IVW multivariable MR — mv_ivw","text":"Performs modified multivariable MR analysis. exposure instruments selected exposures SNPs regressed outcome together, weighting inverse variance outcome.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_ivw.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Perform IVW multivariable MR — mv_ivw","text":"","code":"mv_ivw(mvdat, pval_threshold = 5e-08)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_ivw.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Perform IVW multivariable MR — mv_ivw","text":"mvdat Output mv_harmonise_data(). pval_threshold P-value threshold include instruments. default 5e-8.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_ivw.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Perform IVW multivariable MR — mv_ivw","text":"List results","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_lasso_feature_selection.html","id":null,"dir":"Reference","previous_headings":"","what":"Apply LASSO feature selection to mvdat object — mv_lasso_feature_selection","title":"Apply LASSO feature selection to mvdat object — mv_lasso_feature_selection","text":"Apply LASSO feature selection mvdat object","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_lasso_feature_selection.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Apply LASSO feature selection to mvdat object — mv_lasso_feature_selection","text":"","code":"mv_lasso_feature_selection(mvdat)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_lasso_feature_selection.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Apply LASSO feature selection to mvdat object — mv_lasso_feature_selection","text":"mvdat Output mv_harmonise_data().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_lasso_feature_selection.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Apply LASSO feature selection to mvdat object — mv_lasso_feature_selection","text":"data frame retained features","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_multiple.html","id":null,"dir":"Reference","previous_headings":"","what":"Perform IVW multivariable MR — mv_multiple","title":"Perform IVW multivariable MR — mv_multiple","text":"Performs modified multivariable MR analysis. exposure instruments selected exposures SNPs regressed outcome together, weighting inverse variance outcome.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_multiple.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Perform IVW multivariable MR — mv_multiple","text":"","code":"mv_multiple( mvdat, intercept = FALSE, instrument_specific = FALSE, pval_threshold = 5e-08, plots = FALSE )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_multiple.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Perform IVW multivariable MR — mv_multiple","text":"mvdat Output mv_harmonise_data(). intercept intercept estimated (TRUE) force line origin (FALSE, default). instrument_specific estimate exposure obtained using instruments exposures (FALSE, default) using instruments specific exposure (TRUE). pval_threshold P-value threshold include instruments. default 5e-8. plots Create plots? default FALSE.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_multiple.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Perform IVW multivariable MR — mv_multiple","text":"List results","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_residual.html","id":null,"dir":"Reference","previous_headings":"","what":"Perform basic multivariable MR — mv_residual","title":"Perform basic multivariable MR — mv_residual","text":"Performs initial multivariable MR analysis Burgess et al 2015. exposure outcome residualised exposures, unweighted regression applied.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_residual.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Perform basic multivariable MR — mv_residual","text":"","code":"mv_residual( mvdat, intercept = FALSE, instrument_specific = FALSE, pval_threshold = 5e-08, plots = FALSE )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_residual.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Perform basic multivariable MR — mv_residual","text":"mvdat Output mv_harmonise_data(). intercept intercept estimated (TRUE) force line origin (FALSE, default). instrument_specific estimate exposure obtained using instruments exposures (FALSE, default) using instruments specific exposure (TRUE). pval_threshold P-value threshold include instruments. default 5e-8. plots Create plots? default FALSE.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_residual.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Perform basic multivariable MR — mv_residual","text":"List results","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_subset.html","id":null,"dir":"Reference","previous_headings":"","what":"Perform multivariable MR on subset of features — mv_subset","title":"Perform multivariable MR on subset of features — mv_subset","text":"function proceeds follows: Select features (default done using LASSO feature selection). Subset mvdat retain relevant features instruments. Perform MVMR remaining data.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_subset.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Perform multivariable MR on subset of features — mv_subset","text":"","code":"mv_subset( mvdat, features = mv_lasso_feature_selection(mvdat), intercept = FALSE, instrument_specific = FALSE, pval_threshold = 5e-08, plots = FALSE )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_subset.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Perform multivariable MR on subset of features — mv_subset","text":"mvdat Output mv_harmonise_data(). features Dataframe features retain, must column name 'exposure' list exposures retain mvdat. default mvdat_lasso_feature_selection(mvdat). intercept intercept estimated (TRUE) force line origin (FALSE, default). instrument_specific estimate exposure obtained using instruments exposures (FALSE, default) using instruments specific exposure (TRUE). pval_threshold P-value threshold include instruments. default 5e-8. plots Create plots? default FALSE.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/mv_subset.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Perform multivariable MR on subset of features — mv_subset","text":"List results","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/pipe.html","id":null,"dir":"Reference","previous_headings":"","what":"Pipe operator — %>%","title":"Pipe operator — %>%","text":"See magrittr::%>% details.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/pipe.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Pipe operator — %>%","text":"","code":"lhs %>% rhs"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/power_prune.html","id":null,"dir":"Reference","previous_headings":"","what":"Power prune — power_prune","title":"Power prune — power_prune","text":"duplicate summary sets particular exposure-outcome combination, function keeps exposure-outcome summary set highest expected statistical power. can done dropping duplicate summary sets smaller sample sizes. Alternatively, pruning procedure can take account instrument strength outcome sample size. latter useful, example, considerable variation SNP coverage duplicate summary sets (e.g. studies used targeted fine mapping arrays). large number SNPs available instrument exposure, outcome GWAS better SNP coverage may provide better power outcome GWAS larger sample size.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/power_prune.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Power prune — power_prune","text":"","code":"power_prune(dat, method = 1, dist.outcome = \"binary\")"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/power_prune.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Power prune — power_prune","text":"dat Results harmonise_data(). method duplicate summary sets pruned basis sample size alone (method = 1) combination instrument strength sample size (method = 2)? Default set 1. set 1, duplicate summary sets first dropped basis outcome sample size (smaller duplicates dropped). duplicates still present, remaining duplicates dropped basis exposure sample size (smaller duplicates dropped). method set 2, duplicates dropped basis instrument strength (amount variation explained exposure instrumental SNPs) sample size, assumes SNP-exposure effects correspond continuous trait normal distribution (.e. exposure binary). SNP-outcome effects can correspond either binary continuous trait. exposure binary method=1 used. dist.outcome distribution outcome. Can either \"binary\" \"continuous\". Default set \"binary\".","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/power_prune.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Power prune — power_prune","text":"data.frame duplicate summary sets removed","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/read_exposure_data.html","id":null,"dir":"Reference","previous_headings":"","what":"Read exposure data — read_exposure_data","title":"Read exposure data — read_exposure_data","text":"Reads exposure data. Checks organises columns use MR enrichment tests. Infers p-values possible beta se.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/read_exposure_data.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Read exposure data — read_exposure_data","text":"","code":"read_exposure_data( filename, clump = FALSE, sep = \" \", phenotype_col = \"Phenotype\", snp_col = \"SNP\", beta_col = \"beta\", se_col = \"se\", eaf_col = \"eaf\", effect_allele_col = \"effect_allele\", other_allele_col = \"other_allele\", pval_col = \"pval\", units_col = \"units\", ncase_col = \"ncase\", ncontrol_col = \"ncontrol\", samplesize_col = \"samplesize\", gene_col = \"gene\", id_col = \"id\", min_pval = 1e-200, log_pval = FALSE, chr_col = \"chr\", pos_col = \"pos\" )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/read_exposure_data.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Read exposure data — read_exposure_data","text":"filename Filename. Must header least SNP column present. clump Whether perform LD clumping clump_data() exposure data. default FALSE. sep Specify delimeter file. default space, .e. \" \". phenotype_col Optional column name column phenotype name corresponding SNP. present created value \"Outcome\". default \"Phenotype\". snp_col Required name column SNP rs IDs. default \"SNP\". beta_col Required MR. Name column effect sizes. default \"beta\". se_col Required MR. Name column standard errors. default \"se\". eaf_col Required MR. Name column effect allele frequency. default \"eaf\". effect_allele_col Required MR. Name column effect allele. Must \"\", \"C\", \"T\" \"G\". default \"effect_allele\". other_allele_col Required MR. Name column non effect allele. Must \"\", \"C\", \"T\" \"G\". default \"other_allele\". pval_col Required enrichment tests. Name column p-value. default \"pval\". units_col Optional column name units. default \"units\". ncase_col Optional column name number cases. default \"ncase\". ncontrol_col Optional column name number controls. default \"ncontrol\". samplesize_col Optional column name sample size. default \"samplesize\". gene_col Optional column name gene name. default \"gene\". id_col Optional column name give dataset ID. generated automatically provided every trait / unit combination. default \"id\". min_pval Minimum allowed p-value. default 1e-200. log_pval p-value -log10(P). default FALSE. chr_col Optional column name chromosome. Default \"chr\". pos_col Optional column name genetic position Default \"pos\".","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/read_exposure_data.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Read exposure data — read_exposure_data","text":"data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/read_outcome_data.html","id":null,"dir":"Reference","previous_headings":"","what":"Read outcome data — read_outcome_data","title":"Read outcome data — read_outcome_data","text":"Reads outcome data. Checks organises columns use MR enrichment tests. Infers p-values possible beta se.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/read_outcome_data.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Read outcome data — read_outcome_data","text":"","code":"read_outcome_data( filename, snps = NULL, sep = \" \", phenotype_col = \"Phenotype\", snp_col = \"SNP\", beta_col = \"beta\", se_col = \"se\", eaf_col = \"eaf\", effect_allele_col = \"effect_allele\", other_allele_col = \"other_allele\", pval_col = \"pval\", units_col = \"units\", ncase_col = \"ncase\", ncontrol_col = \"ncontrol\", samplesize_col = \"samplesize\", gene_col = \"gene\", id_col = \"id\", min_pval = 1e-200, log_pval = FALSE, chr_col = \"chr\", pos_col = \"pos\" )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/read_outcome_data.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Read outcome data — read_outcome_data","text":"filename Filename. Must header least SNP column present. snps SNPs extract. NULL, default, extract keeps . sep Specify delimeter file. default space, .e. sep=\" \". phenotype_col Optional column name column phenotype name corresponding SNP. present created value \"Outcome\". Default \"Phenotype\". snp_col Required name column SNP rs IDs. default \"SNP\". beta_col Required MR. Name column effect sizes. default \"beta\". se_col Required MR. Name column standard errors. default \"se\". eaf_col Required MR. Name column effect allele frequency. default \"eaf\". effect_allele_col Required MR. Name column effect allele. Must \"\", \"C\", \"T\" \"G\". default \"effect_allele\". other_allele_col Required MR. Name column non effect allele. Must \"\", \"C\", \"T\" \"G\". default \"other_allele\". pval_col Required enrichment tests. Name column p-value. default \"pval\". units_col Optional column name units. default \"units\". ncase_col Optional column name number cases. default \"ncase\". ncontrol_col Optional column name number controls. default \"ncontrol\". samplesize_col Optional column name sample size. default \"samplesize\". gene_col Optional column name gene name. default \"gene\". id_col Optional column name give dataset ID. generated automatically provided every trait / unit combination. default \"id\". min_pval Minimum allowed p-value. default 1e-200. log_pval pval -log10(P). default FALSE. chr_col Optional column name chromosome. Default \"chr\". pos_col Optional column name genetic position Default \"pos\".","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/read_outcome_data.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Read outcome data — read_outcome_data","text":"data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/run_mr_presso.html","id":null,"dir":"Reference","previous_headings":"","what":"Wrapper for MR-PRESSO — run_mr_presso","title":"Wrapper for MR-PRESSO — run_mr_presso","text":"See https://github.com/rondolab/MR-PRESSO details.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/run_mr_presso.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Wrapper for MR-PRESSO — run_mr_presso","text":"","code":"run_mr_presso(dat, NbDistribution = 1000, SignifThreshold = 0.05)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/run_mr_presso.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Wrapper for MR-PRESSO — run_mr_presso","text":"dat Output harmonise_data(). NbDistribution Number bootstrap replications. default 1000. SignifThreshold Outlier significance threshold. default 0.05.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/run_mr_presso.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Wrapper for MR-PRESSO — run_mr_presso","text":"List results every exposure/outcome combination","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/run_mrmix.html","id":null,"dir":"Reference","previous_headings":"","what":"Perform MRMix analysis on harmonised dat object — run_mrmix","title":"Perform MRMix analysis on harmonised dat object — run_mrmix","text":"See https://github.com/gqi/MRMix details.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/run_mrmix.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Perform MRMix analysis on harmonised dat object — run_mrmix","text":"","code":"run_mrmix(dat)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/run_mrmix.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Perform MRMix analysis on harmonised dat object — run_mrmix","text":"dat Output harmonise_data(). Ensures eaf.exposure values missing.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/run_mrmix.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Perform MRMix analysis on harmonised dat object — run_mrmix","text":"List results, one list item every exposure/outcome pair dat object","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/simple_cap.html","id":null,"dir":"Reference","previous_headings":"","what":"Simple attempt at correcting string case — simple_cap","title":"Simple attempt at correcting string case — simple_cap","text":"Simple attempt correcting string case","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/simple_cap.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Simple attempt at correcting string case — simple_cap","text":"","code":"simple_cap(x)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/simple_cap.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Simple attempt at correcting string case — simple_cap","text":"x Character array character","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/simple_cap.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Simple attempt at correcting string case — simple_cap","text":"Character array character","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/size.prune.html","id":null,"dir":"Reference","previous_headings":"","what":"Size prune — size.prune","title":"Size prune — size.prune","text":"Whens duplicate summary sets particular exposure-outcome combination, function drops duplicates smaller total sample size (binary outcomes, number cases used instead total sample size).","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/size.prune.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Size prune — size.prune","text":"","code":"size.prune(dat)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/size.prune.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Size prune — size.prune","text":"dat Results harmonise_data().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/size.prune.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Size prune — size.prune","text":"data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/sort_1_to_many.html","id":null,"dir":"Reference","previous_headings":"","what":"Sort results for 1-to-many forest plot — sort_1_to_many","title":"Sort results for 1-to-many forest plot — sort_1_to_many","text":"function sorts user-supplied results forest_plot_1_to_many() function. user supplies results form data frame.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/sort_1_to_many.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Sort results for 1-to-many forest plot — sort_1_to_many","text":"","code":"sort_1_to_many( mr_res, b = \"b\", trait_m = \"outcome\", sort_action = 4, group = NULL, priority = NULL )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/sort_1_to_many.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Sort results for 1-to-many forest plot — sort_1_to_many","text":"mr_res Data frame results supplied user. b Name column specifying effect exposure outcome. default \"b\". trait_m column specifying names traits. Corresponds 'many' 1--many forest plot. default \"outcome\". sort_action Choose sort results. sort_action = 1: sort results effect size within groups. Use group order supplied user. sort_action = 2: sort results effect size group. Overides group ordering supplied user. sort_action = 3: group results trait together (e.g. multiple results trait different MR methods). sort_action = 4: sort decreasing effect size (largest effect size top smallest bottom). sort_action = 5: sort increasing effect size (smallest effect size top largest bottom). group Name grouping variable mr_res. priority sort_action = 3, choose value trait_m variable given priority go trait_m values. trait largest effect size prioritised group go top plot.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/sort_1_to_many.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Sort results for 1-to-many forest plot — sort_1_to_many","text":"data frame.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/split_exposure.html","id":null,"dir":"Reference","previous_headings":"","what":"Split exposure column — split_exposure","title":"Split exposure column — split_exposure","text":"function takes exposure column results generated mr() splits separate columns 'exposure name' 'id'.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/split_exposure.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Split exposure column — split_exposure","text":"","code":"split_exposure(mr_res)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/split_exposure.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Split exposure column — split_exposure","text":"mr_res Results mr().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/split_exposure.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Split exposure column — split_exposure","text":"data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/split_outcome.html","id":null,"dir":"Reference","previous_headings":"","what":"Split outcome column — split_outcome","title":"Split outcome column — split_outcome","text":"function takes outcome column results generated mr() splits separate columns 'outcome name' 'id'.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/split_outcome.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Split outcome column — split_outcome","text":"","code":"split_outcome(mr_res)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/split_outcome.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Split outcome column — split_outcome","text":"mr_res Results mr().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/split_outcome.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Split outcome column — split_outcome","text":"data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/standardise_units.html","id":null,"dir":"Reference","previous_headings":"","what":"Try to standardise continuous traits to be in standard deviation units — standardise_units","title":"Try to standardise continuous traits to be in standard deviation units — standardise_units","text":"Uses estimate_trait_sd().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/standardise_units.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Try to standardise continuous traits to be in standard deviation units — standardise_units","text":"","code":"standardise_units(dat)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/standardise_units.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Try to standardise continuous traits to be in standard deviation units — standardise_units","text":"dat Output harmonise_data().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/standardise_units.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Try to standardise continuous traits to be in standard deviation units — standardise_units","text":"Data frame","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/steiger_filtering.html","id":null,"dir":"Reference","previous_headings":"","what":"Steiger filtering function — steiger_filtering","title":"Steiger filtering function — steiger_filtering","text":"function takes object harmonise_data() following: rsq.exposure rsq.outcome column try estimate . done differently traits \"log odds\" units. estimate rsq quantitative traits must either p-values sample sizes SNP, effect sizes standard errors units SD units (column must contain \"SD\"). estimate rsq binary traits units must called \"log odds\" must beta.exposure, eaf.exposure, ncase.exposure, ncontrol.exposure, prevalence.exposure. principles apply calculating rsq outcome trait, except column names beta.outcome etc. prevalence supplied uses 0.1 default.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/steiger_filtering.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Steiger filtering function — steiger_filtering","text":"","code":"steiger_filtering(dat)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/steiger_filtering.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Steiger filtering function — steiger_filtering","text":"dat Output harmonise_data().","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/steiger_filtering.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Steiger filtering function — steiger_filtering","text":"harmonise_data() style data frame additional columns rsq.exposure, rsq.outcome, steiger_dir (TRUE rsq.exposure larger rsq.outcome) steiger_pval test see rsq.exposure significantly larger rsq.outcome.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/steiger_filtering.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Steiger filtering function — steiger_filtering","text":"rsq calculated exposure outcome, perform Steiger test SNP see rsq exposure larger rsq outcome. Note Steiger filtering, useful, pitfalls. Try use replication effect estimates exposure (biased winner's curse), note strong antagonistic confounding differential measurement error exposure outcome causal directions inferred incorrectly.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/steiger_sensitivity.html","id":null,"dir":"Reference","previous_headings":"","what":"Evaluate the Steiger test's sensitivity to measurement error — steiger_sensitivity","title":"Evaluate the Steiger test's sensitivity to measurement error — steiger_sensitivity","text":"Evaluate Steiger test's sensitivity measurement error","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/steiger_sensitivity.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Evaluate the Steiger test's sensitivity to measurement error — steiger_sensitivity","text":"","code":"steiger_sensitivity(rgx_o, rgy_o, ...)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/steiger_sensitivity.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Evaluate the Steiger test's sensitivity to measurement error — steiger_sensitivity","text":"rgx_o Observed variance exposure explained SNPs rgy_o Observed variance outcome explained SNPs ... arguments passed lattice::wireframe()","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/steiger_sensitivity.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Evaluate the Steiger test's sensitivity to measurement error — steiger_sensitivity","text":"List following elements: vz Total volume error parameter space vz0 Volume parameter space gives incorrect answer vz1 Volume paramtere space gives correct answer sensitivity_ratio Ratio vz1/vz0. Higher means inferred direction less susceptible measurement error pl plot parameter space","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/subset_on_method.html","id":null,"dir":"Reference","previous_headings":"","what":"Subset MR-results on method — subset_on_method","title":"Subset MR-results on method — subset_on_method","text":"function takes MR results mr() restricts single method per exposure x disease combination.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/subset_on_method.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Subset MR-results on method — subset_on_method","text":"","code":"subset_on_method( mr_res, single_snp_method = \"Wald ratio\", multi_snp_method = \"Inverse variance weighted\" )"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/subset_on_method.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Subset MR-results on method — subset_on_method","text":"mr_res Results mr(). single_snp_method single SNP methods use 1 SNP used estimate causal effect? default \"Wald ratio\". multi_snp_method multi-SNP methods use 1 SNPs used estimate causal effect? default \"Inverse variance weighted\".","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/subset_on_method.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Subset MR-results on method — subset_on_method","text":"data frame.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/trim.html","id":null,"dir":"Reference","previous_headings":"","what":"Trim function to remove leading and trailing blank spaces — trim","title":"Trim function to remove leading and trailing blank spaces — trim","text":"Trim function remove leading trailing blank spaces","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/trim.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Trim function to remove leading and trailing blank spaces — trim","text":"","code":"trim(x)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/trim.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Trim function to remove leading and trailing blank spaces — trim","text":"x Character array character","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/trim.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Trim function to remove leading and trailing blank spaces — trim","text":"Character array character","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/weighted_median.html","id":null,"dir":"Reference","previous_headings":"","what":"Weighted median method — weighted_median","title":"Weighted median method — weighted_median","text":"New method Jack","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/weighted_median.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Weighted median method — weighted_median","text":"","code":"weighted_median(b_iv, weights)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/weighted_median.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Weighted median method — weighted_median","text":"b_iv Wald ratios weights Weights SNP","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/weighted_median.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Weighted median method — weighted_median","text":"MR estimate","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/weighted_median_bootstrap.html","id":null,"dir":"Reference","previous_headings":"","what":"Calculate standard errors for weighted median method using bootstrap — weighted_median_bootstrap","title":"Calculate standard errors for weighted median method using bootstrap — weighted_median_bootstrap","text":"Based new script weighted median confidence interval, update 31 July 2015.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/weighted_median_bootstrap.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Calculate standard errors for weighted median method using bootstrap — weighted_median_bootstrap","text":"","code":"weighted_median_bootstrap(b_exp, b_out, se_exp, se_out, weights, nboot)"},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/weighted_median_bootstrap.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Calculate standard errors for weighted median method using bootstrap — weighted_median_bootstrap","text":"b_exp Vector genetic effects exposure. b_out Vector genetic effects outcome. se_exp Standard errors genetic effects exposure. se_out Standard errors genetic effects outcome. weights Weights apply SNP. nboot Number bootstrap replications. default 1000.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/reference/weighted_median_bootstrap.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Calculate standard errors for weighted median method using bootstrap — weighted_median_bootstrap","text":"Empirical standard error","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v069","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.6.9","title":"TwoSampleMR v0.6.9","text":"(Release date 2025-02-05) Fixed bug format_data() log_pval argument set TRUE. specified p-value column now used (thanks @luddeluddis) Amend references MR-Base OpenGWAS","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v068","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.6.8","title":"TwoSampleMR v0.6.8","text":"(Release date 2024-09-06) Replaced unique() calls power_prune() mean() ensure scalar iv.se values (thanks @phageghost) Slightly improved formatting code base","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v067","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.6.7","title":"TwoSampleMR v0.6.7","text":"(Release date 2024-08-21) Update OpenGWAS API URLs Minor tweak R CMD check GitHub Actions due rjson hard dependency MendelianRandomization package now requiring R >= 4.4.0 Add dark mode pkgdown site","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v066","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.6.6","title":"TwoSampleMR v0.6.6","text":"(Release date 2024-07-06) Improve test Improve permissions GitHub Actions workflows Bump minimum required version ieugwasr 1.0.1 Made amends code bring line lintr recommendations Added omitted tidyr soft dependency","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v065","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.6.5","title":"TwoSampleMR v0.6.5","text":"(Release date: 2024-06-30) Bumped version roxygen2 creating package documentation Update earliest version R R CMD check GitHub Actions workflow 4.3.2. meta dependency depends lme4, recent 1.1-35.4 release lme4 requires Matrix 1.6-2 released days R 4.3.2. Made package tests robust non-response OpenGWAS API","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v064","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.6.4","title":"TwoSampleMR v0.6.4","text":"(Release date: 2024-06-05) Update installation instructions README.md Fixed bug wrong indels recoding function called (thanks @ruochiz)","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v063","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.6.3","title":"TwoSampleMR v0.6.3","text":"(Release date: 2024-05-23) Update package startup message","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v062","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.6.2","title":"TwoSampleMR v0.6.2","text":"(Release date: 2024-05-09) format_data() now errors detects dat object class 'data.table' issues message informing user make dat object simply 'data.frame' (thanks Si Fang @sifang1678)","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v061","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.6.1","title":"TwoSampleMR v0.6.1","text":"(Release date: 2024-04-30) MendelianRandomization package moved hard dependency soft dependency. dependency package Matrix now requires R >= 4.4.0. Making MendelianRandomization soft dependency means don’t need make TwoSampleMR requirement.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v060","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.6.0","title":"TwoSampleMR v0.6.0","text":"(Release date: 2024-04-22) TwoSampleMR now uses CRAN version ieugwasr package. Importantly includes new authentication system OpenGWAS API. Please see https://mrcieu.github.io/ieugwasr/articles/guide.html#authentication information set .","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v0511","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.5.11","title":"TwoSampleMR v0.5.11","text":"(Release date: 2024-03-21) mr_leaveoneout_plot() mr_forest_plot() amended size argument linewidth per ggplot2 version 3.4.0. Add datasets tests, continuous integration services, creation vignettes don’t rely availability OpenGWAS server. Various improvements helpfiles.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v0510","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.5.10","title":"TwoSampleMR v0.5.10","text":"(Release date: 2024-02-20) Added bfile plink_bin arguments clump_data() Improvements file reading dataset formatting capabilities mv_extract_exposures_local() create multiple exposure dataset","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v059","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.5.9","title":"TwoSampleMR v0.5.9","text":"(Release date: 2024-02-01) Fixed minor issue dat_to_RadialMR() Minor improvements make_dat() default arguments helpfile Minor improvements package tests Amendments GitHub Actions workflows Updated several URLs changed","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v058","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.5.8","title":"TwoSampleMR v0.5.8","text":"(Release date: 2023-11-16) Improved speed harmonisation using data.table functions (thanks @nicksunderland) Updated URL R-CMD-check README badge Updates GitHub Actions workflows","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v057","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.5.7","title":"TwoSampleMR v0.5.7","text":"(Release date: 2023-05-29) Move car package Suggests allow TwoSampleMR install R versions 4.0.0 4.1.0 DESCRIPTION use pkgdepends syntax MRPRESSO package due repository name different package name installing TwoSampleMR pak continues work Various minor code tweaks fix 2 R CMD check notes Add Cairo package Suggests list (thanks @hdraisma) Fix error outcome data vignette (thanks @hdraisma) p-values ~0 stored 1 elasticsearch database. now fixed datasets clumped re-define tophits. full list affected GWAS available : https://github.com/MRCIEU/opengwas-infpval-fix Updated steiger filtering use effective sample size case control studies (thanks @niekverw) Fixed issue tri-allelic SNPs harmonisation. Credit Clare Horscroft (@chorscroft) spotting error fixing Fixed issue experimental version local multivariable MR method. Credit Mischa Lundberg (@MischaLundberg). Catching edge cases retrieving sample size meta data Updating default rsq estimation function use beta standard error instead p-value, improve numerical stability Allow chr pos read local summary data files reading local data without p-values, editing inferred p-value method two-sided images vignettes (hence also rendered pkgdown website) now accompanying alt text descriptions accompanying website package now uses Bootstrap 5, means search facility enabled NAMESPACE simplified, hence package load time slightly improved","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v056","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.5.6","title":"TwoSampleMR v0.5.6","text":"(Release date: 2021-03-25) Fix scatter plot (thanks Yossi Farjoun @yfarjoun) Update mr.raps parameters (thanks Qingyuan Zhao @qingyuanzhao) Bug fix MVMR (thanks Conor Judge @conorjudge) Fix harmonise_data (thanks Leland Taylor @letaylor) Documentation (thanks @jinghuazhao)","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v055","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.5.5","title":"TwoSampleMR v0.5.5","text":"(Release date: 2020-08-09) Updating clump_data function operate outcome datasets way operates exposure datasets. Credit goes Marina Vabistsevits spotting suggesting solution. Removing ios function, now moved mr.ios package : https://github.com/universe77/mr.ios ieu--756 ieu--757 ieu--758 ieu--759 ieu--760 ieu--761 ieu--762 ieu--763 ieu--764 ieu--765 ieu--766 ieu--767 ieu--768 ieu--769 ieu--770 ieu--771 ieu--772 ieu--773 ieu--774 ieu--775 ieu--776 ieu--777 ieu--778 ieu--779 bbj--64 bbj--65 bbj--66 bbj--67 bbj--68 bbj--69 ebi--GCST004364 ebi--GCST005215 ebi--GCST005216 ebi--GCST005221 ebi--GCST005222 ieu--1086 ieu--761 ieu--762 ieu--763 ieu--767 ieu--777 ieu--779","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v054","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.5.4","title":"TwoSampleMR v0.5.4","text":"(Release date: 2020-05-10) datasets now re-instated Added options different populations LD operations converting MRInput format supplying LD matrix, possible multi-allelic variants represented differently GWAS LD reference panel. Ambiguous alignments removed, now fixed. Credit goes Mona Almramhi spotting fixing issue.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v053","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.5.3","title":"TwoSampleMR v0.5.3","text":"(Release date: 2020-04-02) converting MRInput format supplying LD matrix, LD matrix SNP order matching summary data order. Credit goes Mona Almramhi spotting fixing issue. Reinstating datasets previously disabled (ukb-, ukb-d, ubm-) Fixed bug mr_wrapper. Thanks Gunn-Helen Moen .","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v052","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.5.2","title":"TwoSampleMR v0.5.2","text":"(Release date: 2020-03-11) longer marking LD functions deprecated now. Thanks Jonas Bovijn discussions . Various fixes R CMD check warnings notes.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v051","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.5.1","title":"TwoSampleMR v0.5.1","text":"(Release date: 2020-02-14) number datasets found issues since 0.5.0. include: minority non-effect alleles incorrect ieu-batch. consequence harmonisation may thrown SNPs due harmonisation mismatches. Error arose 0.5.0 now fixed p-value issues ubm-batch. led fewer top-hits identified . Error arose 0.5.0 currently disabled Effect allele frequency issues ukb-batch, potentially due misreported effect alleles. Error arose 0.5.0 currently disabled","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v050","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.5.0","title":"TwoSampleMR v0.5.0","text":"(Release date: 2020-01-01) Major update, details : https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v0426","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.4.26","title":"TwoSampleMR v0.4.26","text":"(Release date: 2019-12-01) Improved precision low p-values steiger tests. Thanks Hannah V Meyer Tom Palmer . Improved instrument extraction new datasets","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v0425","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.4.25","title":"TwoSampleMR v0.4.25","text":"(Release date: 2019-09-12) Changes googleAuthR package break authentication. Added interception install older version fixed. Please use devtools::install_github(\"MarkEdmondson1234/googleAuthR@v0.8.1\")","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v0424","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.4.24","title":"TwoSampleMR v0.4.24","text":"(Release date: 2019-09-10) Bug found extract_instruments requesting non-default parameters. Thanks Shantanu Bafna pointing .","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v0423","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.4.23","title":"TwoSampleMR v0.4.23","text":"(Release date: 2019-08-12) Forcing server extract_instruments pre-computed outcomes present default. old behaviour still possible setting extract_instruments(force_server_if_empty=FALSE)","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v0422","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.4.22","title":"TwoSampleMR v0.4.22","text":"(Release date: 2019-02-22) Changing default API address preparation moving version 0.5.0 use new API","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v0421","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.4.21","title":"TwoSampleMR v0.4.21","text":"(Release date: 2019-02-19) Updated mixture experts","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v0420","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.4.20","title":"TwoSampleMR v0.4.20","text":"(Release date: 2019-01-31) harmonise function now returns summary harmonisation procedure e.g. number SNPs removed etc. Access via attr(obj, “log”) Note tested shown give results previously chance might lead slightly different behaviour. Please install previous version prefer avoid possibilities changed behaviour - devtools::install_github(“MRCIEU/TwoSampleMR@0.4.18”)","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v0419","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.4.19","title":"TwoSampleMR v0.4.19","text":"(Release date: 2019-01-31) Fixed bug mr_heterogeneity impacted minority cases. method list specified order results didn’t always match method (MR Egger IVW mixed ). affect default usage. Thanks Anna Guyatt pointing . Added index suspicion functionality, penalised mode estimator Added transformation function scale effect estimate units SD scale Starting write change log !","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v0418","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.4.18","title":"TwoSampleMR v0.4.18","text":"(Release date: 2018-12-03) Improved performance harmonisation","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v0417","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.4.17","title":"TwoSampleMR v0.4.17","text":"(Release date: 2018-12-03) Added facility harmonise indels Documentation options added multivariable MR","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v034","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.3.4","title":"TwoSampleMR v0.3.4","text":"(Release date: 2017-11-30) Moving elastic search database request batching changing 50 SNPs per chunk 10000. can modified extract_outcome_data(splitsize=50) Changing harmonise_data behaviour - now discard bad SNPs retains mr_keep column indicating whether used mr analysis functions Fixed issue oauth token Updated scatter plot register mr_keep column.","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v033","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.3.3","title":"TwoSampleMR v0.3.3","text":"(Release date: 2017-11-23) Fixed bug singlesnp leaveoneout analyses","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v032","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.3.2","title":"TwoSampleMR v0.3.2","text":"(Release date: 2017-11-22) Added function check latest version package load","code":""},{"path":"https://mrcieu.github.io/TwoSampleMR/news/index.html","id":"twosamplemr-v031","dir":"Changelog","previous_headings":"","what":"TwoSampleMR v0.3.1","title":"TwoSampleMR v0.3.1","text":"(Release date: 2017-11-22) One external packages TwoSampleMR depends upon changed, making authorisation behaviour change. authorisation timing hour refreshing timeout. now fixed - authorisation token refresh hour. authorisation token used stored hidden file called .httr-oauth. now changed - stored visible file called ‘mrbase.oauth’.","code":""}] diff --git a/docs/site.webmanifest b/docs/site.webmanifest new file mode 100644 index 00000000..4ebda26b --- /dev/null +++ b/docs/site.webmanifest @@ -0,0 +1,21 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "/web-app-manifest-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/web-app-manifest-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} \ No newline at end of file diff --git a/docs/sitemap.xml b/docs/sitemap.xml new file mode 100644 index 00000000..e74deb97 --- /dev/null +++ b/docs/sitemap.xml @@ -0,0 +1,141 @@ + +https://mrcieu.github.io/TwoSampleMR/404.html +https://mrcieu.github.io/TwoSampleMR/LICENSE-text.html +https://mrcieu.github.io/TwoSampleMR/LICENSE.html +https://mrcieu.github.io/TwoSampleMR/articles/exposure.html +https://mrcieu.github.io/TwoSampleMR/articles/gwas2020.html +https://mrcieu.github.io/TwoSampleMR/articles/harmonise.html +https://mrcieu.github.io/TwoSampleMR/articles/index.html +https://mrcieu.github.io/TwoSampleMR/articles/introduction.html +https://mrcieu.github.io/TwoSampleMR/articles/outcome.html +https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html +https://mrcieu.github.io/TwoSampleMR/authors.html +https://mrcieu.github.io/TwoSampleMR/index.html +https://mrcieu.github.io/TwoSampleMR/news/index.html +https://mrcieu.github.io/TwoSampleMR/reference/Isq.html +https://mrcieu.github.io/TwoSampleMR/reference/TwoSampleMR-package.html +https://mrcieu.github.io/TwoSampleMR/reference/add_metadata.html +https://mrcieu.github.io/TwoSampleMR/reference/add_rsq.html +https://mrcieu.github.io/TwoSampleMR/reference/allele_frequency.html +https://mrcieu.github.io/TwoSampleMR/reference/available_outcomes.html +https://mrcieu.github.io/TwoSampleMR/reference/cleanup_outcome_data.html +https://mrcieu.github.io/TwoSampleMR/reference/clump_data.html +https://mrcieu.github.io/TwoSampleMR/reference/combine_all_mrresults.html +https://mrcieu.github.io/TwoSampleMR/reference/combine_data.html +https://mrcieu.github.io/TwoSampleMR/reference/contingency.html +https://mrcieu.github.io/TwoSampleMR/reference/convert_outcome_to_exposure.html +https://mrcieu.github.io/TwoSampleMR/reference/create_label.html +https://mrcieu.github.io/TwoSampleMR/reference/dat_to_MRInput.html +https://mrcieu.github.io/TwoSampleMR/reference/dat_to_RadialMR.html +https://mrcieu.github.io/TwoSampleMR/reference/default_parameters.html +https://mrcieu.github.io/TwoSampleMR/reference/directionality_test.html +https://mrcieu.github.io/TwoSampleMR/reference/effective_n.html +https://mrcieu.github.io/TwoSampleMR/reference/enrichment.html +https://mrcieu.github.io/TwoSampleMR/reference/enrichment_method_list.html +https://mrcieu.github.io/TwoSampleMR/reference/estimate_trait_sd.html +https://mrcieu.github.io/TwoSampleMR/reference/extract_instruments.html +https://mrcieu.github.io/TwoSampleMR/reference/extract_outcome_data.html +https://mrcieu.github.io/TwoSampleMR/reference/fishers_combined_test.html +https://mrcieu.github.io/TwoSampleMR/reference/forest_plot.html +https://mrcieu.github.io/TwoSampleMR/reference/forest_plot_1_to_many.html +https://mrcieu.github.io/TwoSampleMR/reference/forest_plot_basic.html +https://mrcieu.github.io/TwoSampleMR/reference/forest_plot_basic2.html +https://mrcieu.github.io/TwoSampleMR/reference/format_1_to_many.html +https://mrcieu.github.io/TwoSampleMR/reference/format_aries_mqtl.html +https://mrcieu.github.io/TwoSampleMR/reference/format_d.html +https://mrcieu.github.io/TwoSampleMR/reference/format_data.html +https://mrcieu.github.io/TwoSampleMR/reference/format_gtex_eqtl.html +https://mrcieu.github.io/TwoSampleMR/reference/format_gwas_catalog.html +https://mrcieu.github.io/TwoSampleMR/reference/format_metab_qtls.html +https://mrcieu.github.io/TwoSampleMR/reference/format_mr_results.html +https://mrcieu.github.io/TwoSampleMR/reference/format_proteomic_qtls.html +https://mrcieu.github.io/TwoSampleMR/reference/generate_odds_ratios.html +https://mrcieu.github.io/TwoSampleMR/reference/get_p_from_r2n.html +https://mrcieu.github.io/TwoSampleMR/reference/get_population_allele_frequency.html +https://mrcieu.github.io/TwoSampleMR/reference/get_r_from_bsen.html +https://mrcieu.github.io/TwoSampleMR/reference/get_r_from_lor.html +https://mrcieu.github.io/TwoSampleMR/reference/get_r_from_pn.html +https://mrcieu.github.io/TwoSampleMR/reference/get_se.html +https://mrcieu.github.io/TwoSampleMR/reference/harmonise_data.html +https://mrcieu.github.io/TwoSampleMR/reference/harmonise_ld_dat.html +https://mrcieu.github.io/TwoSampleMR/reference/index.html +https://mrcieu.github.io/TwoSampleMR/reference/knit_report.html +https://mrcieu.github.io/TwoSampleMR/reference/ld_matrix.html +https://mrcieu.github.io/TwoSampleMR/reference/ldsc_h2.html +https://mrcieu.github.io/TwoSampleMR/reference/ldsc_h2_internal.html +https://mrcieu.github.io/TwoSampleMR/reference/ldsc_rg.html +https://mrcieu.github.io/TwoSampleMR/reference/ldsc_rg_internal.html +https://mrcieu.github.io/TwoSampleMR/reference/make_dat.html +https://mrcieu.github.io/TwoSampleMR/reference/mr.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_density_plot.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_egger_regression.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_egger_regression_bootstrap.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_forest_plot.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_forest_plot_grouped.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_funnel_plot.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_heterogeneity.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw_fe.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw_mre.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_ivw_radial.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_leaveoneout.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_leaveoneout_plot.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_median.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_meta_fixed.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_meta_fixed_simple.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_meta_random.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_method_list.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_mode.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_moe.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_penalised_weighted_median.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_pleiotropy_test.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_raps.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_report.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker_bootstrap.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker_cooksdistance.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_rucker_jackknife.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_scatter_plot.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_sign.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_simple_median.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_simple_mode.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_simple_mode_nome.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_singlesnp.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_steiger.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_steiger2.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_two_sample_ml.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_uwr.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_wald_ratio.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_weighted_median.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_weighted_mode.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_weighted_mode_nome.html +https://mrcieu.github.io/TwoSampleMR/reference/mr_wrapper.html +https://mrcieu.github.io/TwoSampleMR/reference/mv_basic.html +https://mrcieu.github.io/TwoSampleMR/reference/mv_extract_exposures.html +https://mrcieu.github.io/TwoSampleMR/reference/mv_extract_exposures_local.html +https://mrcieu.github.io/TwoSampleMR/reference/mv_harmonise_data.html +https://mrcieu.github.io/TwoSampleMR/reference/mv_ivw.html +https://mrcieu.github.io/TwoSampleMR/reference/mv_lasso_feature_selection.html +https://mrcieu.github.io/TwoSampleMR/reference/mv_multiple.html +https://mrcieu.github.io/TwoSampleMR/reference/mv_residual.html +https://mrcieu.github.io/TwoSampleMR/reference/mv_subset.html +https://mrcieu.github.io/TwoSampleMR/reference/pipe.html +https://mrcieu.github.io/TwoSampleMR/reference/power_prune.html +https://mrcieu.github.io/TwoSampleMR/reference/read_exposure_data.html +https://mrcieu.github.io/TwoSampleMR/reference/read_outcome_data.html +https://mrcieu.github.io/TwoSampleMR/reference/run_mr_presso.html +https://mrcieu.github.io/TwoSampleMR/reference/run_mrmix.html +https://mrcieu.github.io/TwoSampleMR/reference/simple_cap.html +https://mrcieu.github.io/TwoSampleMR/reference/size.prune.html +https://mrcieu.github.io/TwoSampleMR/reference/sort_1_to_many.html +https://mrcieu.github.io/TwoSampleMR/reference/split_exposure.html +https://mrcieu.github.io/TwoSampleMR/reference/split_outcome.html +https://mrcieu.github.io/TwoSampleMR/reference/standardise_units.html +https://mrcieu.github.io/TwoSampleMR/reference/steiger_filtering.html +https://mrcieu.github.io/TwoSampleMR/reference/steiger_sensitivity.html +https://mrcieu.github.io/TwoSampleMR/reference/subset_on_method.html +https://mrcieu.github.io/TwoSampleMR/reference/trim.html +https://mrcieu.github.io/TwoSampleMR/reference/weighted_median.html +https://mrcieu.github.io/TwoSampleMR/reference/weighted_median_bootstrap.html + + diff --git a/docs/web-app-manifest-192x192.png b/docs/web-app-manifest-192x192.png new file mode 100644 index 00000000..0454711c Binary files /dev/null and b/docs/web-app-manifest-192x192.png differ diff --git a/docs/web-app-manifest-512x512.png b/docs/web-app-manifest-512x512.png new file mode 100644 index 00000000..e8f09ec0 Binary files /dev/null and b/docs/web-app-manifest-512x512.png differ diff --git a/man/figures/logo.svg b/man/figures/logo.svg new file mode 100644 index 00000000..7eaa8b84 --- /dev/null +++ b/man/figures/logo.svg @@ -0,0 +1,36 @@ + + + + + G + + + + X + + + + Y + + + + + + + + + + + + + + + + + + + + β₁ + β₂ + β₃ + diff --git a/pkgdown/favicon/apple-touch-icon.png b/pkgdown/favicon/apple-touch-icon.png new file mode 100644 index 00000000..e9a3df21 Binary files /dev/null and b/pkgdown/favicon/apple-touch-icon.png differ diff --git a/pkgdown/favicon/favicon-96x96.png b/pkgdown/favicon/favicon-96x96.png new file mode 100644 index 00000000..68143314 Binary files /dev/null and b/pkgdown/favicon/favicon-96x96.png differ diff --git a/pkgdown/favicon/favicon.ico b/pkgdown/favicon/favicon.ico new file mode 100644 index 00000000..95686d84 Binary files /dev/null and b/pkgdown/favicon/favicon.ico differ diff --git a/pkgdown/favicon/favicon.svg b/pkgdown/favicon/favicon.svg new file mode 100644 index 00000000..884dc0b6 --- /dev/null +++ b/pkgdown/favicon/favicon.svg @@ -0,0 +1,38 @@ + + + + + G + + + + X + + + + Y + + + + + + + + + + + + + + + + + + + + β₁ + β₂ + β₃ + \ No newline at end of file diff --git a/pkgdown/favicon/site.webmanifest b/pkgdown/favicon/site.webmanifest new file mode 100644 index 00000000..4ebda26b --- /dev/null +++ b/pkgdown/favicon/site.webmanifest @@ -0,0 +1,21 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "/web-app-manifest-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/web-app-manifest-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} \ No newline at end of file diff --git a/pkgdown/favicon/web-app-manifest-192x192.png b/pkgdown/favicon/web-app-manifest-192x192.png new file mode 100644 index 00000000..0454711c Binary files /dev/null and b/pkgdown/favicon/web-app-manifest-192x192.png differ diff --git a/pkgdown/favicon/web-app-manifest-512x512.png b/pkgdown/favicon/web-app-manifest-512x512.png new file mode 100644 index 00000000..e8f09ec0 Binary files /dev/null and b/pkgdown/favicon/web-app-manifest-512x512.png differ diff --git a/pkgdown/index.md b/pkgdown/index.md new file mode 100644 index 00000000..940e9e48 --- /dev/null +++ b/pkgdown/index.md @@ -0,0 +1,39 @@ +# Mendelian randomization with GWAS summary data + + +[![R-CMD-check](https://github.com/MRCIEU/TwoSampleMR/actions/workflows/check-full.yaml/badge.svg)](https://github.com/MRCIEU/TwoSampleMR/actions/workflows/check-full.yaml) +[![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html) [![DOI](https://zenodo.org/badge/49515156.svg)](https://zenodo.org/badge/latestdoi/49515156) +[![Codecov test coverage](https://codecov.io/gh/MRCIEU/TwoSampleMR/branch/master/graph/badge.svg)](https://app.codecov.io/gh/MRCIEU/TwoSampleMR?branch=master) +[![TwoSampleMR status badge](https://mrcieu.r-universe.dev/badges/TwoSampleMR)](https://mrcieu.r-universe.dev/TwoSampleMR) + + +A package for performing Mendelian randomization using GWAS summary data. It uses the [IEU OpenGWAS database](https://gwas.mrcieu.ac.uk/) to obtain data automatically, and a wide range of methods to run the analysis. + +## January 2020 major update + +**We have made substantial changes to the package, database and reference panels.** For full details of the changes, please visit + +## Installation + +Users running Windows and macOS, to install the latest version of TwoSampleMR please install from our MRC IEU r-universe + +```r +install.packages("TwoSampleMR", repos = c("https://mrcieu.r-universe.dev", "https://cloud.r-project.org")) +``` + +Users running Linux or WebR please see the [following instructions](https://github.com/MRCIEU/mrcieu.r-universe.dev#readme). + +To update the package run the same command again. + +### Installing from source + +``` r +install.packages("remotes") +remotes::install_github("MRCIEU/TwoSampleMR") +``` + +To update the package just run the `remotes::install_github("MRCIEU/TwoSampleMR")` command again. + +## Docker + +A multi-platform docker image containing R with the TwoSampleMR package pre-installed (for both x86_64 and ARM computers) is available here: https://hub.docker.com/r/mrcieu/twosamplemr