diff --git a/2024-privacy-by-design/2024-privacy-by-design.html b/2024-privacy-by-design/2024-privacy-by-design.html new file mode 100644 index 0000000..d7e1989 --- /dev/null +++ b/2024-privacy-by-design/2024-privacy-by-design.html @@ -0,0 +1,3370 @@ + + + + + + + + + + + + + + + Privacy by Design in the machine learning pipeline + + + + + + + + + + + + + + + +
+
+ +
+

Privacy by Design
in the machine learning pipeline

+


Workshop, University of Venice

+ +
+
+
+Zak Varty +
+
+
+ +

2024-11-01

+
+
+

Hello! Who am I?

+
+
+
    +
  • Statistician by training, got to where I am through medical, environmental and industrial applications.

  • +
  • Teaching Fellow at Imperial College London

    +
      +
    • Data Science, Data Ethics
    • +
  • +
  • Privacy, fairness and explainability in ML.

    +
      +
    • Capable enthusiast, realist / pessimist
    • +
  • +
+

Really it all comes down to doing good statistics well.

+
+


+
+
+
+
+

+
+
+
+
+
+
+
+
+

Why do we care about privacy?

+
+
    +
  1. Protecting Sensitive Data: ML models often train on personal or confidential data (health records, financial info), and safeguarding this data is essential to prevent misuse or unauthorized access.

  2. +
  3. Compliance with Regulations: Laws like GDPR require organisations to protect user privacy, impacting how data is collected, stored, and used in ML.

  4. +
  5. Preventing Data Leakage Models can unintentionally expose sensitive information from their training data, risking user privacy if someone exploits the model’s outputs.

  6. +
  7. Building Trust: Privacy-conscious ML practices foster trust among users, making them more willing to share data and participate in systems that use ML.

  8. +
  9. Avoiding Discrimination: Privacy techniques can reduce bias and discrimination risks, ensuring the ML model treats users fairly without targeting sensitive attributes.

  10. +
+
+
+
+

“If you have nothing to hide, you have nothing to fear”

+ +
+ +
+
+

“The benefits outweight the costs”

+ +
+
+

Machine Learning Pipeline

+ +
+
+

Machine Learning Pipeline Life Cycle

+ +
+

Reality is much messier. See Gelman and Loken (2013) for a discussion of the implications.

+ +
+
+
+

This workshop

+
+
+
+
    +
  • Work through the ML life cycle
  • +
  • How could and have things gone wrong
  • +
+
+


+
+
    +
  • What tools do we have?
  • +
  • What are their limitations?
  • +
+
+


+
+
    +
  • Interactive bits, every now and then
  • +
+
+
+ +
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+

1. Data Collection

+ +
+
+

Collecting Appropriate Data - GDPR

+
+
+
    +
  • Collect only necessary data, purpose clear at time of collection
  • +
  • Data subject has right to +
      +
    • access
    • +
    • rectify
    • +
    • erase
    • +
    • object
    • +
  • +
  • Consequences both financial and reputational
  • +
+
+ +
+
+ +
+
+

Collecting Data - Hard-to-Reach Groups

+

Standard ML assumes that data are cheap and easy to collect.

+

Assumption that data are cheap and easy to collect. Out of the box model fitting assumes we are working with big, representative and independent samples.

+
+
    +
  • Applications of ML to social science to study hard-to-reach populations: persecuted groups, stigmatised behaviours.

  • +
  • Standard study designs and analysis techniques will fail.

  • +
+
+
+
+

Snowball Sampling - Hidden Network

+ +
+
+

Snowball Sampling - Initial Recruitment

+ +
+
+

Snowball Sampling - Referral Round 1

+ +
+
+

Snowball Sampling - Referral Round 2

+ +
+
+

Snowball Sampling - Referral Round 3

+ +
+
+

Snowball Sampling

+
+
+

By using subject-driven sampling design, we can better explore the hard to reach target population while preserving the privacy of data subjects who do not want to be included in the study.

+
+
    +
  • Bonus: Also allows us to study community (network) structure if we are interested in that.
  • +
+
+
+
    +
  • Drawbacks: +
      +
    • “isolated” nodes,
    • +
    • partitioned graphs,
    • +
    • adapting model fitting to non-uniform sampling.
    • +
  • +
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+

Collecting Data - Asking Difficult Questions

+

Even if data subjects are easy to access and sample from, they may not wish to answer honestly.

+

Can you give me some examples?

+
+
+
    +
  • cheated on an exam?
  • +
  • cheated on a romantic / sexual partner?
  • +
  • experienced suicidal ideation?
  • +
  • killed another person?
  • +
+
+
+
+

Dishonest answers will bias any subsequent analysis, leading us to underestimate the prevalence of an “undesirable outcome”.

+
+
+

(Interesting intersection with survey design and psychology. The order and way that you ask questions can influence responses but we will focus on a single question here.)

+
+
+
+

Direct Response Survey

+

\[\Pr(Y_i = 1) = \theta \quad \text{and} \quad \Pr(Y_i = 0) = 1 - \theta.\] Method of Moments Estimator: (General dataset)

+

\[ \hat \Theta = \hat\Pr(Y_i = 1)\]

+
+

\[ \hat \Theta = \frac{1}{n}\sum_{i=1}^n \mathbb{I}(Y_i = 1) = \bar Y = \frac{\#\{yes\}}{\#\{subjects\}}.\]

+
+
+

Method of Moments Estimate: (Specific dataset) \[ \hat \theta = \frac{1}{n}\sum_{i=1}^n \mathbb{I}(y_i = 1) = \bar y.\]

+
+
+
+

MoM Example

+

Suppose I ask 100 people whether they have ever been unfaithful in a romantic relationship and 24 people respond “Yes”.

+


+

What is your best guess of the proportion of all people who have been unfaithful?

+
+

\(\hat\theta = \bar y = \frac{24}{100}\)

+


+

How confident are you about that guess?

+

Would that change if I had 1 person responding “Yes”?

+

Would that change if I had 99 people responding “Yes”?

+
+
+
+

MoM - Nice Properties

+

Over lots of samples we get it right on average:

+

\(\mathbb{E}_Y[\hat\Theta] = \mathbb{E}_Y\left[\frac{1}{n}\sum_{i=1}^n \mathbb{I}(Y_i = 1)\right] = \frac{1}{n}\sum_{i=1}^n \mathbb{E}_Y\left[ \mathbb{I}(Y_i = 1)\right] = \frac{n \theta}{n} = \theta\)

+
+

As the number of samples gets large, we get more confident and therefore recover the truth

+

\[\begin{align*} +\text{Var}_Y[\hat\Theta] +&= \text{Var}_Y\left[\frac{1}{n}\sum_{i=1}^n \mathbb{I}(Y_i = 1)\right] \\ +&= \frac{1}{n^2}\sum_{i=1}^n\text{Var}_Y\left[\mathbb{I}(Y_i = 1)\right] \\ +&= \frac{1}{n^2}\sum_{i=1}^n p(1-p) \\ +&= \frac{n p (1-p)}{n^2} \\ +&= \frac{p (1-p)}{n} \rightarrow 0 +\end{align*}\]

+
+
+
+

Adding Privacy - Randomised Response

+
    +
  • Mathematically nice but in reality people lie.

  • +
  • Our estimator worked “best” for central values of \(\theta\), unlikely for stigmatised events.

  • +
  • Add random element to survey to provide plausible deniability.

    +
      +
    • Flip a fair coin. If heads, switch your answer.
    • +
  • +
  • MoM estimation: Equate probabilities and proportions.

  • +
+
+
+

Estimation from Randomised Response Data

+
+
+

Consider using a weighted coin, probability \(p\) of telling truth. Derive an expression for the probability of answering “Yes”.

+
+

\[\begin{align*} +\Pr(\text{Yes}) &= \theta p + (1 - \theta)(1 - p) \\ +& \approx \frac{\#\{yes\}}{\#\{subjects\}} \\ +&= \bar y +\end{align*}\]

+
+
+

Rearrange this expression to get a formula for \(\hat \theta\).

+
+
+

\[\hat \theta = \frac{\bar y - 1 + p}{2p -1}.\]

+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+

Randomised Response Activities

+

\[ \hat \theta = \frac{\bar y - 1 + p}{2p -1}.\]

+
    +
  • Direct response is a special case of randomised response. How can we use that to check our working?
  • +
+
+
    +
  • If our previous survey results came from this randomised response survey design with \(p = 0.25\), what is your best guess of the proportion of people who have been unfaithful?
  • +
+
+
+
    +
  • Are you more or less confident in this estimate than previously, when we had the same data but from a direct response design?
  • +
+
+
+
    +
  • What does your confidence depend on? And which of those factors do you have knowledge of / control over?
  • +
+
+
+
    +
  • When would this estimation procedure break and why? How could we fix that?
  • +
+
+
+
+

Randomised Response - Privacy Schematic

+ +
+
+

Randomised Response

+
    +
  • Approach to privacy for single, binary response.

  • +
  • Issues with applying to multiple questions, e.g. surveys with follow on questions.

  • +
  • Extensions to categorical and continuous responses and predictors

  • +
  • General principle of adding noise

    +
      +
    • Need to make observations indistinguishable
    • +
    • Need to preserve important aspects of “signal”
    • +
  • +
+
+
+

Data Collection Summary

+
    +
  • Collect what you need and use that information only for its intended purpose.

  • +
  • Targeting hard-to-reach populations can be challenging but possible by combining survey design and specific learning approaches. Keeps statisticians in a job!

  • +
  • Asking difficult questions can lead to biased responses. Plausible deniability through randomised response designs can help.

  • +
+
+
+
+

2. Data Storage

+ +
+
+

Encryption

+

Once we have gone to the effort of collecting data we don’t want to just leave it lying around for anyone to access.

+
+
+


\[ \text{Plain text} \overset{f}{\rightarrow} \text{Cipher Text}\]
\[ \text{Cipher text} \overset{f^{-1}}{\rightarrow} \text{Plain Text}\]
\[ f(\text{data}, \text{key})\] Many encryption schemes depending on the data to be encrypted and how the key is to be distributed.

+
+
+
+
+
+

+
+
+
+
+
+
+
+
+

Caesar Cipher

+ +
+

Have a go at decrypting the encrypted message f(?, 2 ) = JGNNQ YQTNF.

+
+
+

What are some benefits and drawbacks of this encryption scheme?

+
+
+
+

K-anonymity

+

What happens if someone gets access to the data?

+


+
    +
  • \(k\)-anonymity is a measure of privacy within a dataset.

  • +
  • Given a set of predictor-outcome responses, each unique combination forms an equivalence class.

  • +
  • The smallest equivalence class of a \(k\)-anonymous dataset is of size \(k\).

  • +
  • Equivalently, each individual is indistinguishable from at least \(k-1\) others.

  • +
+
+
+

K-anonymity Example

+ +
+
+

K-anonymity Worked Example

+ +
+
+

K-anonymity Your Turn

+

I asked ChatGPT to generate 4-anonymous datasets but it hasn’t done a good job.

+
    +
  • Establish the true value of k for your dataset.

  • +
  • Use pseudonymisation, aggregation, redaction and partial-redaction to make your dataset 4-anonymous.

  • +
+
+
+

K-anonymity Feedback

+
    +
  • How did ChatGPT do?
  • +
  • How did you alter the anonymity level of your dataset?
  • +
  • What did you have to consider as you were doing this?
  • +
+
+
+

K-anonymity Drawbacks

+

What do you think some of the limitations of \(k\)-anonymity might be?

+
+
    +
  • Knowing what is important before analysis.
  • +
  • Publishing multiple versions of the dataset.
  • +
  • Can be checked easily but not implemented algorithmically.
  • +
  • External data attacks; Jane Doe, Latanya Sweeney
  • +
+
+
+
+

Data Storage - Summary

+
    +
  • Don’t leave important data lying around unprotected.

  • +
  • Choose a level of security appropriate to the sensitivity of the data.

  • +
  • Consider the consequences of someone gaining access to the data.

  • +
  • Remember that your data does not live in isolation.

  • +
  • K-anonymity not a good measure of privacy but an accessible starting point.

  • +
+
+
+
+

3. Data Analytics

+ +
+
+

Federated Computation and Analytics

+
    +
  • Data can be vulnerable while in transport

  • +
  • Might be too risky to send individual data items

  • +
  • Summary Statistics are often sufficient

  • +
  • These can be transmitted from individual data centres (clients), e.g. hospitals within a local authority (server).

  • +
+
+
+

What is Federation?

+


+

Federated data is decentralised - it is not all stored in one place.

+
+
+
+


+

Federated Computing

+


+

Federated Analytics

+


+

Federated Learning

+


+

Federated Validation

+
+

Two common examples: where data remains with client

+




+
    +
  • Mobile data (Text suggestions)
  • +
  • Medical data (Healthcare Monitoring)
  • +
+
+
+
+
+
+

Federation Networks

+


+

We can formalise how information sources are connected as a graph structure known as an empirical graph.

+


+

Nodes represent users or data sources, while edges represent data sharing capabilities.

+
+
+

Centralised Federation

+ + +
+
+

Clustered Federated Learning

+ + +
+
+

Personalised Federated Learning

+ + +
+
+

Directions of Federation

+


+
+
+

Horizontal Federation

+

+
+ +
+

Vertical Federation

+

+
+
+ +
+
+

Why bother with Federated Learning?

+
+
+



+

✅ Easy to explain

+


+

✅ No loss of information

+


+

✅ Lower computational costs

+
+ +
+



+

❌ Client or individual information still vulnerable

+


+

❌ Combining local information is hard

+


+

❌ Exacerbates existing modelling issues

+
+
+ +
+
+

Encryption

+

Pass data \(x\) through some function \(E\) with inverse \(E^{-1}=D\):

+
    +
  • Inversion easy with some extra information available to trusted individuals
  • +
  • Inversion very difficult otherwise.
  • +
+
+

Pros

+
    +
  • Data security when in storage or transit.
  • +
  • Reduce associated costs.
  • +
+
+
+

Cons

+
    +
  • Can’t compute on \(x\) without first decrypting.
  • +
+
+
+
+

Malleability

+
+

\[f(E[x]) = E[f(x)]\]

+
+
+

This need not literally be the same function: \[g(E[x]) = E[f(x)].\]

+
+
+
    +
  • Predictable modification without decryption (+/-)
  • +
  • Outsource computation with our compromising security / privacy +
      +
    • company can keep model private from hosting service
    • +
    • customer can keep data private from host and provider
    • +
    • still vulnerable to repeated query attacks.
    • +
  • +
+
+
+
+

Fully Homomorphic Encryption

+

(Fully) Homomorphic encryption is an emerging technology in private ML.

+


+

Homomorphic encryption schemes allow \(f\) to be addition:

+

\[E[x] \oplus E[y]= E[x + y].\] Fully homomorphic encryption schemes additionally allow \(f\) multiplication:

+

\[E[x] \otimes E[y]= E[x \times y].\]

+

This allows us to construct polynomial approximations to ML models.

+
+
    +
  • How closely can our model be approximated by a polynomial?
  • +
  • Practical issues with imperfect data storage and large number of compositions.
  • +
+
+
+
+
+

4. Modelling

+ +
+
+

Privacy through modelling constraints

+

The core idea of differential privacy is that we want to ensure that no individual data point influences the model “too much”.

+
+
+
+

Strategies:

+
    +
  • Add noise to individual data entries or summary statistics. Similar to robust regression (median modelling, heavy-tailed noise)

  • +
  • Combine goodness of fit and sensitivity penalty in loss function. Similar to penalised regression.

  • +
+

\[ L(\theta, x; \lambda) = \underset{\text{likelihood /} \\ \text{model fit}}{\underbrace{\ell(\theta, x)}} - \lambda \underset{\text{sensitivity} \\ \text{penality}}{\underbrace{h(\theta, x)}}\]

+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+

Federated Learning

+

Similar idea to federated analytics but communicating e.g. gradient of loss function using local data.

+


+
+
+
    +
  • This means that data stays with user, only partial model updates are transmitted.

  • +
  • Strong links to distributed computing and this is how Apple (and others) collect performance data from phones.

  • +
+

Have to take care with non-responses so as not to bias the model.

+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+

5. Going into Production

+ +
+
+

Privacy of the model

+

Putting a model into production exposes a whole range of adversarial circumstances. Two of the most common would be:

+
+
+
    +
  • Attacks aiming to recover model structure +
      +
    • to reproduce the model
    • +
    • to exploit weaknesses
    • +
  • +
  • Attacks aiming to recover individual training data
  • +
  • Examples would be financial decision making and LLMs.
  • +
+
+
+
+
+
+

+
+
+
+
+

Rigaki, M. & Garcia, S. (2020). “A Survey of Privacy Attacks in Machine Learning”. ArXiv preprint.

+
+
+
+
+
+

Wrapping up

+ +
+
+

Summary

+

Three things to remember from this workshop

+


+
    +
  1. Privacy can become compromised at all stages of the ML pipeline.
  2. +
+


+
    +
  1. Core methods rely on some combination of localisation, encryption and noise.
  2. +
+


+
    +
  1. As in life, you can’t do anything useful without risk but you can minimise those risks.
  2. +
+
+
+

Learning More

+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+

Build Information

+
+
+

R version 4.3.3 (2024-02-29)

+

Platform: x86_64-apple-darwin20 (64-bit)

+

locale: en_US.UTF-8||en_US.UTF-8||en_US.UTF-8||C||en_US.UTF-8||en_US.UTF-8

+

attached base packages: stats, graphics, grDevices, utils, datasets, methods and base

+

loaded via a namespace (and not attached): gtable(v.0.3.5), jsonlite(v.1.8.8), dplyr(v.1.1.4), compiler(v.4.3.3), crayon(v.1.5.3), Rcpp(v.1.0.12), tidyselect(v.1.2.1), stringr(v.1.5.1), showtext(v.0.9-7), zvplot(v.0.0.0.9000), assertthat(v.0.2.1), scales(v.1.3.0), png(v.0.1-8), yaml(v.2.3.8), fastmap(v.1.1.1), ggplot2(v.3.5.1), R6(v.2.5.1), generics(v.0.1.3), showtextdb(v.3.0), knitr(v.1.45), tibble(v.3.2.1), pander(v.0.6.5), munsell(v.0.5.1), lubridate(v.1.9.3), pillar(v.1.9.0), rlang(v.1.1.4), utf8(v.1.2.4), stringi(v.1.8.4), xfun(v.0.43), timechange(v.0.3.0), cli(v.3.6.3), magrittr(v.2.0.3), digest(v.0.6.35), grid(v.4.3.3), rstudioapi(v.0.16.0), lifecycle(v.1.0.4), sysfonts(v.0.8.9), vctrs(v.0.6.5), evaluate(v.0.23), glue(v.1.8.0), emo(v.0.0.0.9000), fansi(v.1.0.6), colorspace(v.2.1-1), rmarkdown(v.2.26), purrr(v.1.0.2), jpeg(v.0.1-10), tools(v.4.3.3), pkgconfig(v.2.0.3) and htmltools(v.0.5.8.1)

+
+
+
+
+

References

+
+

+ +
+
+
+Gelman, Andrew, and Eric Loken. 2013. “The Garden of Forking Paths: Why Multiple Comparisons Can Be a Problem, Even When There Is No ‘Fishing Expedition’ or ‘p-Hacking’ and the Research Hypothesis Was Posited Ahead of Time.” Department of Statistics, Columbia University 348 (1-17): 3. +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/2024-privacy-by-design/2024-privacy-by-design.qmd b/2024-privacy-by-design/2024-privacy-by-design.qmd new file mode 100644 index 0000000..fef70f8 --- /dev/null +++ b/2024-privacy-by-design/2024-privacy-by-design.qmd @@ -0,0 +1,924 @@ +--- +title: "Privacy by Design
in the machine learning pipeline" +subtitle: "
Workshop, University of Venice" +author: Zak Varty +date: "November, 2024" +editor: source +format: + revealjs: + theme: assets/zv-slides-theme.scss + logo: assets/zv-logo-192x192.png + bibliography: ../zv-talk-refs.bib + footer: "Privacy by Design - November 2024 - Zak Varty" + menu: true + slide-number: true + show-slide-number: all # (all / print / speaker) + self-contained: true # (set to true before publishing html to web) + width: 1600 # default is 1050 + height: 900 # default is 850 + incremental: false +title-slide-attributes: + data-background-color: "#555555" +--- + +## Hello! Who am I? + +:::{.columns} +:::{.column width="50%"} +- Statistician by training, got to where I am through medical, environmental and industrial applications. + +- Teaching Fellow at Imperial College London + - Data Science, Data Ethics + +- Privacy, fairness and explainability in ML. + - Capable enthusiast, realist / pessimist + +Really it all comes down to doing good statistics well. +::: +:::{.column width="50%"} +
+```{r who-am-i} +#| echo: false +#| fig-align: center +#| out-width: 50% +knitr::include_graphics("images/zv_c.jpg") +``` +::: +:::: + +## Why do we care about privacy? + +. . . + +1. **Protecting Sensitive Data:** ML models often train on personal or confidential data (health records, financial info), and safeguarding this data is essential to prevent misuse or unauthorized access. + +2. **Compliance with Regulations:** Laws like GDPR require organisations to protect user privacy, impacting how data is collected, stored, and used in ML. + +3. **Preventing Data Leakage** Models can unintentionally expose sensitive information from their training data, risking user privacy if someone exploits the model’s outputs. + +4. **Building Trust:** Privacy-conscious ML practices foster trust among users, making them more willing to share data and participate in systems that use ML. + +5. **Avoiding Discrimination:** Privacy techniques can reduce bias and discrimination risks, ensuring the ML model treats users fairly without targeting sensitive attributes. + + +# "If you have nothing to hide, you have nothing to fear" + +:::{.notes} +- Assumes everyone has an equal tolerance for information exposure +- Assumes that what needs to be private does not change over time or space +::: + +# "The benefits outweight the costs" + +:::{.notes} +- subjective decision +- have to draw the line somewhere +- how do we ensure that line is not crossed? +- what can we do without crossing that line? +::: + +## Machine Learning Pipeline + +```{r ml-pipeline} +#| echo: false +#| fig-align: center +knitr::include_graphics("images/private-ml-piepline.png") +``` + +## Machine Learning ~~Pipeline~~ Life Cycle + +```{r ml-lifecycle} +#| echo: false +#| fig-align: center +knitr::include_graphics("images/private-ml-cycle.png") +``` + +. . . + +Reality is much messier. See @gelman2013garden for a discussion of the implications. + +:::{.notes} +- describe each stage +- not recall linear, iterative process +- reality much messier + - presents issues for valid inference + - see garden of forking paths for more +::: + +## This workshop + +::::{.columns} +:::{.column width="45%"} +:::{.fragment} +- Work through the ML life cycle +- How could and have things gone wrong +::: + +
+ +:::{.fragment} +- What tools do we have? +- What are their limitations? +::: + +
+ +:::{.fragment} +- Interactive bits, every now and then +::: +::: +:::{.column width="10%"} +::: +:::{.column width="45%"} +```{r ml-lifecycle-2} +#| echo: false +#| fig-align: center +#| out-width: 75% +knitr::include_graphics("images/private-ml-cycle.png") +``` +::: +:::: + +# 1. Data Collection {background-color="#555555"} + +## Collecting Appropriate Data - GDPR + +::::{.columns} +:::{.column width="60%"} +- Collect only necessary data, purpose clear at time of collection +- Data subject has right to + - access + - rectify + - erase + - object +- Consequences both financial and reputational + +::: +:::{.column width="40%"} +```{r gdpr-screenshot} +#| echo: false +#| fig-align: center +# knitr::include_graphics() +# GDPR screenshot +``` +::: +:::: + +:::{.notes} +- Only collect necessary information +- Purpose clear at time of collection + - hypothetical example: BMI study to H & M +- Data subject has right to access, rectify erase and object +- huge financial and reputational consequences + - recently LLM integration +::: + +## Collecting Data - Hard-to-Reach Groups + +Standard ML assumes that data are cheap and easy to collect. + +Assumption that data are cheap and easy to collect. Out of the box model fitting +assumes we are working with big, representative and independent samples. + +. . . + +- Applications of ML to social science to study hard-to-reach populations: persecuted groups, stigmatised behaviours. + +- Standard study designs and analysis techniques will fail. + + +## Snowball Sampling - Hidden Network + +```{r snowball-1} +#| echo: false +#| fig-align: center +knitr::include_graphics("images/snowball-1.png") +``` + +## Snowball Sampling - Initial Recruitment + +```{r snowball-2} +#| echo: false +#| fig-align: center +knitr::include_graphics("images/snowball-2.png") +``` + +## Snowball Sampling - Referral Round 1 + +```{r snowball-3} +#| echo: false +#| fig-align: center +knitr::include_graphics("images/snowball-3.png") +``` + +## Snowball Sampling - Referral Round 2 + +```{r snowball-4} +#| echo: false +#| fig-align: center +knitr::include_graphics("images/snowball-4.png") +``` + +## Snowball Sampling - Referral Round 3 + +```{r snowball-5} +#| echo: false +#| fig-align: center +knitr::include_graphics("images/snowball-5.png") +``` + +## Snowball Sampling + +::::{.columns} + +:::{.column width="50%"} +By using subject-driven sampling design, we can better explore the hard to reach target population while preserving the privacy of data subjects who _do not_ want to be included in the study. + +:::{.fragment} +- Bonus: Also allows us to study community (network) structure if we are interested in that. +::: + +:::{.fragment} +- Drawbacks: + - "isolated" nodes, + - partitioned graphs, + - adapting model fitting to non-uniform sampling. +::: +::: +:::{.column width="50%"} +```{r snowball-final} +#| echo: false +#| fig-align: center +#| out-width: "70%" +knitr::include_graphics("images/snowball-5.png") +``` +::: +:::: + + +## Collecting Data - Asking Difficult Questions + +Even if data subjects are easy to access and sample from, they may not wish to answer honestly. + +_Can you give me some examples?_ + +. . . + +:::{.incremental} +- cheated on an exam? +- cheated on a romantic / sexual partner? +- experienced suicidal ideation? +- killed another person? +::: + +. . . + +Dishonest answers will _bias_ any subsequent analysis, leading us to underestimate the prevalence of an "undesirable outcome". + +. . . + +(Interesting intersection with survey design and psychology. The order and way that you ask questions can influence responses but we will focus on a single question here.) + +## Direct Response Survey + +$$\Pr(Y_i = 1) = \theta \quad \text{and} \quad \Pr(Y_i = 0) = 1 - \theta.$$ +Method of Moments Estimator: (General dataset) + +$$ \hat \Theta = \hat\Pr(Y_i = 1)$$ + +. . . + +$$ \hat \Theta = \frac{1}{n}\sum_{i=1}^n \mathbb{I}(Y_i = 1) = \bar Y = \frac{\#\{yes\}}{\#\{subjects\}}.$$ + +. . . + +Method of Moments Estimate: (Specific dataset) +$$ \hat \theta = \frac{1}{n}\sum_{i=1}^n \mathbb{I}(y_i = 1) = \bar y.$$ + +## MoM Example + +Suppose I ask 100 people whether they have ever been unfaithful in a romantic relationship and 24 people respond "Yes". + +
+ +What is your best guess of the proportion of all people who have been unfaithful? + +. . . + +$\hat\theta = \bar y = \frac{24}{100}$ + +
+ +How confident are you about that guess? + +Would that change if I had 1 person responding "Yes"? + +Would that change if I had 99 people responding "Yes"? + + +## MoM - Nice Properties + +Over lots of samples we get it right on average: + +$\mathbb{E}_Y[\hat\Theta] = \mathbb{E}_Y\left[\frac{1}{n}\sum_{i=1}^n \mathbb{I}(Y_i = 1)\right] = \frac{1}{n}\sum_{i=1}^n \mathbb{E}_Y\left[ \mathbb{I}(Y_i = 1)\right] = \frac{n \theta}{n} = \theta$ + +. . . + +As the number of samples gets large, we get more confident and therefore recover the truth + +\begin{align*} +\text{Var}_Y[\hat\Theta] +&= \text{Var}_Y\left[\frac{1}{n}\sum_{i=1}^n \mathbb{I}(Y_i = 1)\right] \\ +&= \frac{1}{n^2}\sum_{i=1}^n\text{Var}_Y\left[\mathbb{I}(Y_i = 1)\right] \\ +&= \frac{1}{n^2}\sum_{i=1}^n p(1-p) \\ +&= \frac{n p (1-p)}{n^2} \\ +&= \frac{p (1-p)}{n} \rightarrow 0 +\end{align*} + +## Adding Privacy - Randomised Response + +- Mathematically nice but in reality people lie. + +- Our estimator worked "best" for central values of $\theta$, unlikely for stigmatised events. + +- Add random element to survey to provide plausible deniability. + - Flip a fair coin. If heads, switch your answer. + +- MoM estimation: Equate probabilities and proportions. + +## Estimation from Randomised Response Data + +::::{.columns} +:::{.column width="50%"} + +Consider using a weighted coin, probability $p$ of telling truth. Derive an expression for the probability of answering "Yes". + +:::{.fragment} +\begin{align*} +\Pr(\text{Yes}) &= \theta p + (1 - \theta)(1 - p) \\ +& \approx \frac{\#\{yes\}}{\#\{subjects\}} \\ +&= \bar y +\end{align*} +::: +:::{.fragment} +Rearrange this expression to get a formula for $\hat \theta$. +::: +:::{.fragment} +$$\hat \theta = \frac{\bar y - 1 + p}{2p -1}.$$ +::: +::: +:::{.column width="50%"} +```{r randomised-response-tree} +#| echo: false +#| fig-align: center +#| out-width: "60%" +knitr::include_graphics("images/randomised-response-tree.png") +``` +::: +:::: + +## Randomised Response Activities + +$$ \hat \theta = \frac{\bar y - 1 + p}{2p -1}.$$ + +- Direct response is a special case of randomised response. How can we use that to check our working? + +. . . + +- If our previous survey results came from this randomised response survey design with $p = 0.25$, what is your best guess of the proportion of people who have been unfaithful? + +. . . + +- Are you more or less confident in this estimate than previously, when we had the same data but from a direct response design? + +. . . + +- What does your confidence depend on? And which of those factors do you have knowledge of / control over? + +. . . + +- When would this estimation procedure break and why? How could we fix that? + +## Randomised Response - Privacy Schematic + +```{r randomised-response-privacy} +#| echo: false +#| fig-align: center +#| out-width: "100%" +knitr::include_graphics("images/randomised-response-privacy.png") +``` + +## Randomised Response + +- Approach to privacy for single, binary response. + +- Issues with applying to multiple questions, e.g. surveys with follow on questions. + +- Extensions to categorical and continuous responses and predictors + +- General principle of adding noise + - Need to make observations indistinguishable + - Need to preserve important aspects of "signal" + +## Data Collection Summary + +- _Collect what you need_ and use that information only for its intended purpose. + +- _Targeting hard-to-reach populations can be challenging_ but possible by combining survey design and specific learning approaches. Keeps statisticians in a job! + +- _Asking difficult questions_ can lead to biased responses. Plausible deniability through randomised response designs can help. + +# 2. Data Storage {background-color="#555555"} + +## Encryption + +Once we have gone to the effort of collecting data we don't want to just leave it lying around for anyone to access. + +::::{.columns} +:::{.column width="50%"} +
+$$ \text{Plain text} \overset{f}{\rightarrow} \text{Cipher Text}$$ +
+$$ \text{Cipher text} \overset{f^{-1}}{\rightarrow} \text{Plain Text}$$ +
+$$ f(\text{data}, \text{key})$$ +Many encryption schemes depending on the data to be encrypted and how the key is to be distributed. +::: +:::{.column width="50%"} +```{r encryption} +#| echo: false +#| fig-align: center +#| out-width: "80%" +knitr::include_graphics("images/encryption.png") +``` +::: +:::: + +## Caesar Cipher + +```{r caesar} +#| echo: false +#| fig-align: center +#| out-width: "70%" +knitr::include_graphics("images/caesar-cipher-zak.png") +``` + +. . . + +Have a go at decrypting the encrypted message f(?, 2 ) = JGNNQ YQTNF. + +. . . + +What are some benefits and drawbacks of this encryption scheme? + + +## K-anonymity {.incremental} + +What happens if someone gets access to the data? + +
+ +- $k$-anonymity is a measure of privacy within a dataset. + +- Given a set of predictor-outcome responses, each unique combination forms an _equivalence class_. + +- The smallest equivalence class of a $k$-anonymous dataset is of size $k$. + +- Equivalently, each individual is indistinguishable from at least $k-1$ others. + +## K-anonymity Example + +```{r k-anon-survey} +#| echo: false +#| fig-align: center +#| out-width: "100%" +knitr::include_graphics("images/k-anon-survey.png") +``` + +## K-anonymity Worked Example + +```{r k-anon-example} +#| echo: false +#| fig-align: center +knitr::include_graphics("images/k-anon-example.png") +``` + +## K-anonymity Your Turn + +I asked ChatGPT to generate 4-anonymous datasets but it hasn't done a good job. + +- Establish the true value of k for your dataset. + +- Use pseudonymisation, aggregation, redaction and partial-redaction to make your dataset 4-anonymous. + +## K-anonymity Feedback + +- How did ChatGPT do? +- How did you alter the anonymity level of your dataset? +- What did you have to consider as you were doing this? + +## K-anonymity Drawbacks + +What do you think some of the limitations of $k$-anonymity might be? + +. . . + +- Knowing what is important before analysis. +- Publishing multiple versions of the dataset. +- Can be checked easily but not implemented algorithmically. +- External data attacks; Jane Doe, Latanya Sweeney + +## Data Storage - Summary + +- Don't leave important data lying around unprotected. +- Choose a level of security appropriate to the sensitivity of the data. + +- Consider the consequences of someone gaining access to the data. +- Remember that your data does not live in isolation. + +- K-anonymity not a good measure of privacy but an accessible starting point. + +# 3. Data Analytics {background-color="#555555"} + +## Federated Computation and Analytics + +- Data can be vulnerable while in transport + +- Might be too risky to send individual data items + +- Summary Statistics are often sufficient + +- These can be transmitted from individual data centres (clients), e.g. hospitals within a local authority (server). + + +## What is Federation? + +
+ +Federated data is _decentralised_ - it is not all stored in one place. + +. . . + +::::{.columns} +:::{.column width="60%"} +
+ +Federated _Computing_ + +
+ +Federated _Analytics_ + +
+ +Federated _Learning_ + +
+ +Federated _Validation_ +::: +:::{.column width="40%"} +Two common examples: where data remains with client + +


+ +- Mobile data (Text suggestions) +- Medical data (Healthcare Monitoring) +::: +:::: + + +## Federation Networks + +
+ +We can formalise how information sources are connected as a graph structure known as an empirical graph. + +
+ +Nodes represent users or data sources, while edges represent data sharing capabilities. + + + +## Centralised Federation + + +![](images/centralised-federation.png) + +:::{.notes} +The simplest federation structure has each client connected to a single server. This results in a star-like empirical graph. Somewhat tautologically, this is also known as centralised federated learning. + +The goal here is to co-train a single model for all clients, which is contained within the server, but the data on which that model is trained, tested and validated remains with each client. +::: + +## Clustered Federated Learning + +![](images/clustered-federation.png) + +:::{.notes} +Alternatively, we might want provide different models to clients according to which group they belong with. + +These groups might be known a priori (e.g. through metadata on the clients) or might be determined by clustering the clients in some way (e.g. using the statistical similarity between the data or model parameters that they hold). + +Things can of course become more complicated - we might have independent models for each cluster or each might be part some potentially deep hierarchical structure of clusters and super-clusters. + +Things get even more complex in this case if we are modelling over time, where the models for each cluster need to be kept up to date and clients could potentially move between clusters. +::: + +## Personalised Federated Learning + +![](images/personalised-federation.png) + +:::{.notes} +One extreme case of clustered federated learning is centralised FL - the other extreme is personalised FL. + +In this arrangement each client has their own model. + +Again these individual models might be independent or they might be coupled in some way. An analogy here is a longitudinal study where each client is a study participant and we use a model with random intercepts and slopes. +::: + +## Directions of Federation + +
+ +::::{.columns} +:::{.column width="45%"} +### Horizontal Federation +![](images/horizontal-federation.png) +::: +:::{.column width="10%"} +::: +:::{.column width="45%"} +### Vertical Federation +![](images/vertical-federation.png) +::: +:::: + +:::{.notes} +The empirical graph describes how information is shared within a federation network, but does not describe the types of information that are shared. This leads us on to two new terms: horizontal and vertical federation. + +### Horizontal federation + +In Horizontal federation the same predictors and responses are available at all clients but particular instances of these are split between clients (potentially with overlap). + +If we consider a design matrix for our learning problem, this corresponds to different rows of our data being stored by the various clients. + +Federated Learning in this sense is a bit like a meta-analysis on steroids, our centralised model gains power from a collection of federated datasets each of the same form. + +### Vertical Federation + +You might be able to now extrapolate to vertical federation. + +In this set up, each client contains a different subset of the predictors that are used by the server model. Importantly, each of these predictors is recorded for the same instances (e.g. health data sorted by different medical practices, or screen time on macbook, ipad and iphone for a given apple ID) + +In vertical federation, each row of our design matrix is present in each client data set but each client hold only have a small subset of all the columns (or predictors). +::: + +## Why bother with Federated Learning? + +::::{.columns} +:::{.column width="45%"} +

+ +`r emo::ji("check")` Easy to explain + +
+ +`r emo::ji("check")` No loss of information + +
+ +`r emo::ji("check")` Lower computational costs +::: +:::{.column width="10%"} +::: +:::{.column width="45%"} +

+ +`r emo::ji("x")` Client or individual information still vulnerable + +
+ +`r emo::ji("x")` Combining local information is hard + +
+ +`r emo::ji("x")` Exacerbates existing modelling issues +::: +:::: + +:::{.notes} + +- Easy to explain that data does not move +- No loss of information by obfuscating or aggregating +- Lower computational costs than standard encryption methods + + +- Small sample at client or high influence clients can still expose information in aggregated model. +- how to properly combine local information into global model requires careful consideration +- Further complicates existing modelling issues + - missing data + non-response + - imbalanced dat + super-clients + - data/concept drift + sampling frequency + - parallel computation + differences in software/hardware/capability +::: + + +## Encryption + +Pass data $x$ through some function $E$ with inverse $E^{-1}=D$: + + - Inversion easy with some extra information available to trusted individuals + - Inversion very difficult otherwise. + +. . . + +_Pros_ + + - Data security when in storage or transit. + - Reduce associated costs. + +. . . + +_Cons_ + + - Can't compute on $x$ without first decrypting. + + +## Malleability + +:::{.fragment} +$$f(E[x]) = E[f(x)]$$ +::: + +:::{.fragment} +This need not literally be the same function: +$$g(E[x]) = E[f(x)].$$ +::: + +:::{.incremental} +- Predictable modification without decryption (+/-) +- Outsource computation with our compromising security / privacy + - company can keep model private from hosting service + - customer can keep data private from host and provider + - still vulnerable to repeated query attacks. +::: + +## Fully Homomorphic Encryption + +(Fully) Homomorphic encryption is an emerging technology in private ML. + +
+ +_Homomorphic encryption schemes_ allow $f$ to be addition: + +$$E[x] \oplus E[y]= E[x + y].$$ +_Fully homomorphic encryption schemes_ additionally allow $f$ multiplication: + +$$E[x] \otimes E[y]= E[x \times y].$$ + +This allows us to construct polynomial approximations to ML models. + +. . . + +- How closely can our model be approximated by a polynomial? +- Practical issues with imperfect data storage and large number of compositions. + + +# 4. Modelling {background-color="#555555"} + +## Privacy through modelling constraints + +The core idea of differential privacy is that we want to ensure that no individual data point influences the model "too much". + +::::{.columns} +:::{.column width="55%"} +:::{.fragment} +__Strategies:__ + +- Add noise to individual data entries or summary statistics. Similar to robust regression (median modelling, heavy-tailed noise) + +- Combine goodness of fit and sensitivity penalty in loss function. Similar to penalised regression. + +$$ L(\theta, x; \lambda) = \underset{\text{likelihood /} \\ \text{model fit}}{\underbrace{\ell(\theta, x)}} - \lambda \underset{\text{sensitivity} \\ \text{penality}}{\underbrace{h(\theta, x)}}$$ +::: +::: +:::{.column width="45%"} + +```{r high-leverage-point} +#| fig-width: 4 +#| fig-height: 6 +#| out-width: 70% +#| fig-align: center +set.seed(4321) +x <- rgamma(n = 30, shape = 1, rate = 1) +y <- 3*x + 2 + rnorm(30) +x_leverage <- 3.5 +y_leverage <- 3 + +lm1 <- lm(y~x) +lm2 <- lm(c(y,y_leverage) ~ c(x, x_leverage)) + +par(bg = NA) +plot(x,y, pch = 16, bty = "n") +points(x = x_leverage, y = y_leverage, pch = 16, col = zvplot::zv_orange) +abline(coefficients(lm1), lwd = 2) +abline(coefficients(lm2), lwd = 2, col = zvplot::zv_orange) +``` +::: +:::: + +## Federated Learning + +Similar idea to federated analytics but communicating e.g. gradient of loss function using local data. + +
+ +::::{.columns} +:::{.column width="50%"} +- This means that data stays with user, only partial model updates are transmitted. + +- Strong links to distributed computing and this is how Apple (and others) collect performance data from phones. + +Have to take care with non-responses so as not to bias the model. +::: +:::{.column width="50%"} +```{r centralised-federated-learning} +#| echo: false +#| fig-align: center +knitr::include_graphics("images/centralised-federation.png") +``` +::: +:::: + +# 5. Going into Production {background-color="#555555"} + +## Privacy of the model + +Putting a model into production exposes a whole range of adversarial circumstances. Two of the most common would be: + +::::{.columns} +:::{.column width="50%"} +- Attacks aiming to recover model structure + - to reproduce the model + - to exploit weaknesses +- Attacks aiming to recover individual training data +- Examples would be financial decision making and LLMs. +::: +:::{.column width="50%"} + +```{r privacy-attacks-paper} +#| echo: false +#| fig-align: center +knitr::include_graphics("images/rigaki-garcia-2020.png") +``` +[Rigaki, M. & Garcia, S. (2020)](https://arxiv.org/abs/2007.07646). “A Survey of Privacy Attacks in Machine Learning”. ArXiv preprint. +::: +:::: + +# Wrapping up {background-color="#555555"} + +## Summary + +Three things to remember from this workshop + +
+ +1. Privacy can become compromised at all stages of the ML pipeline. + +
+ +2. Core methods rely on some combination of localisation, encryption and noise. + +
+ +3. As in life, you can't do anything useful without risk but you can minimise those risks. + + +## Learning More + +::::{.columns} +:::{.column width="50%"} +```{r ethical-algorithm} +#| echo: false +#| fig-align: center +knitr::include_graphics("images/ethical-algorithm-cover.jpg") +``` +::: +:::{.column width="50%"} +```{r data-science-ethics} +#| echo: false +#| fig-align: center +knitr::include_graphics("images/data-science-ethics-cover.jpg") +``` +::: +:::: + + +## Build Information {.smaller} + +```{r} +pander::pander(sessionInfo()) +``` + +## References diff --git a/2024-privacy-by-design/assets/refs.bib b/2024-privacy-by-design/assets/refs.bib new file mode 100644 index 0000000..e69de29 diff --git a/2024-privacy-by-design/assets/zv-logo-192x192.png b/2024-privacy-by-design/assets/zv-logo-192x192.png new file mode 100644 index 0000000..0638ba3 Binary files /dev/null and b/2024-privacy-by-design/assets/zv-logo-192x192.png differ diff --git a/2024-privacy-by-design/assets/zv-slides-theme.scss b/2024-privacy-by-design/assets/zv-slides-theme.scss new file mode 100644 index 0000000..e03101d --- /dev/null +++ b/2024-privacy-by-design/assets/zv-slides-theme.scss @@ -0,0 +1,100 @@ +/*-- scss:defaults --*/ + +// Text + +@import url("https://fonts.googleapis.com/css2?family=Oswald:wght@200;300;400;500;600;700&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Oxygen:wght@200;300;400;500;600;700;800;900&display=swap"); + +$body-font-family: 'Oxygen', Arial, sans-serif !important; +$title-font-family: 'Oswald', Georgia, serif !important; + +$presentation-font-size-root: 24pt; +$code-block-font-size: 0.8em; +$fig-caption-font-size: 0.6em; +$presentation-h1-font-size: 2.0em; +$presentation-h2-font-size: 1.6em; +$presentation-h3-font-size: 1.3em; +$presentation-h4-font-size: 1.1em; +$presentation-line-height: 1.5em; +$navlink-active-weight: 600; + +// Colours +$zv-black: #202020; +$zv-white: #FAFAFA; +$zv-grey: #EEEEEE; +$zv-teal: #0AB3C7; +$zv-fuchia: #C81E87; +$zv-blue: #3D52D5; +$zv-orange: #E87800; +$zv-navy: #003E74; + +$body-color: $zv-black; +$primary: $zv-black; +$link-color: $zv-orange; +$body-bg: $zv-white; +$code-block-bg: $zv-grey; +$code-block-border-color: $zv-black; +$code-color: $zv-fuchia; + + +h1, h2, h3, h4 { + font-family: $title-font-family; +} + +h2 { // Pad slide titles + padding-top: -0.1em; + padding-bottom: 0.7em; +} + +p, li { + font-family: $body-font-family; + font-weight: lighter; +} + +li { + padding-top: 0.6em; + padding-bottom: 0.6em; +} + +.slide-number { + font-family: $body-font-family; +} + +strong { + color: $zv-black; + font-weight: bolder; +} + +em { + color: $zv-orange; +} + +/*-- scss:rules --*/ + +.reveal .slide figure > figcaption{ + font-family: $body-font-family; + font-size: $fig-caption-font-size; +} + +.reveal .slide-logo { + max-height: 3.5% !important; +} + +.reveal .progress { + background: $zv-grey; + color: $zv-orange; + height: 0.7%; +} + +.code_class { +height: 700px; +width: 1200px; +} + +.vertical-center { + margin: 0; + position: absolute; + top: 50%; + -ms-transform: translateY(-50%); + transform: translateY(-50%); +} diff --git a/2024-privacy-by-design/hospital-example-complete.xlsx b/2024-privacy-by-design/hospital-example-complete.xlsx new file mode 100644 index 0000000..3128061 Binary files /dev/null and b/2024-privacy-by-design/hospital-example-complete.xlsx differ diff --git a/2024-privacy-by-design/hospital-example-group-1.xlsx b/2024-privacy-by-design/hospital-example-group-1.xlsx new file mode 100644 index 0000000..1a567e8 Binary files /dev/null and b/2024-privacy-by-design/hospital-example-group-1.xlsx differ diff --git a/2024-privacy-by-design/hospital-example-group-2.xlsx b/2024-privacy-by-design/hospital-example-group-2.xlsx new file mode 100644 index 0000000..1a567e8 Binary files /dev/null and b/2024-privacy-by-design/hospital-example-group-2.xlsx differ diff --git a/2024-privacy-by-design/hospital-example-group-3.xlsx b/2024-privacy-by-design/hospital-example-group-3.xlsx new file mode 100644 index 0000000..1a567e8 Binary files /dev/null and b/2024-privacy-by-design/hospital-example-group-3.xlsx differ diff --git a/2024-privacy-by-design/hospital-example-group-4.xlsx b/2024-privacy-by-design/hospital-example-group-4.xlsx new file mode 100644 index 0000000..1a567e8 Binary files /dev/null and b/2024-privacy-by-design/hospital-example-group-4.xlsx differ diff --git a/2024-privacy-by-design/hospital-example-group-5.xlsx b/2024-privacy-by-design/hospital-example-group-5.xlsx new file mode 100644 index 0000000..1a567e8 Binary files /dev/null and b/2024-privacy-by-design/hospital-example-group-5.xlsx differ diff --git a/2024-privacy-by-design/images/caesar-cipher-zak.png b/2024-privacy-by-design/images/caesar-cipher-zak.png new file mode 100644 index 0000000..9429b3d Binary files /dev/null and b/2024-privacy-by-design/images/caesar-cipher-zak.png differ diff --git a/2024-privacy-by-design/images/centralised-federation.png b/2024-privacy-by-design/images/centralised-federation.png new file mode 100644 index 0000000..57e93a5 Binary files /dev/null and b/2024-privacy-by-design/images/centralised-federation.png differ diff --git a/2024-privacy-by-design/images/clustered-federation.png b/2024-privacy-by-design/images/clustered-federation.png new file mode 100644 index 0000000..15a23b8 Binary files /dev/null and b/2024-privacy-by-design/images/clustered-federation.png differ diff --git a/2024-privacy-by-design/images/data-science-ethics-cover.jpg b/2024-privacy-by-design/images/data-science-ethics-cover.jpg new file mode 100644 index 0000000..8ac6ef8 Binary files /dev/null and b/2024-privacy-by-design/images/data-science-ethics-cover.jpg differ diff --git a/2024-privacy-by-design/images/encryption.png b/2024-privacy-by-design/images/encryption.png new file mode 100644 index 0000000..b603417 Binary files /dev/null and b/2024-privacy-by-design/images/encryption.png differ diff --git a/2024-privacy-by-design/images/ethical-algorithm-cover.jpg b/2024-privacy-by-design/images/ethical-algorithm-cover.jpg new file mode 100644 index 0000000..0f16cb7 Binary files /dev/null and b/2024-privacy-by-design/images/ethical-algorithm-cover.jpg differ diff --git a/2024-privacy-by-design/images/horizontal-federation.png b/2024-privacy-by-design/images/horizontal-federation.png new file mode 100644 index 0000000..193aa31 Binary files /dev/null and b/2024-privacy-by-design/images/horizontal-federation.png differ diff --git a/2024-privacy-by-design/images/k-anon-example.png b/2024-privacy-by-design/images/k-anon-example.png new file mode 100644 index 0000000..16b807c Binary files /dev/null and b/2024-privacy-by-design/images/k-anon-example.png differ diff --git a/2024-privacy-by-design/images/k-anon-survey.png b/2024-privacy-by-design/images/k-anon-survey.png new file mode 100644 index 0000000..68f62fe Binary files /dev/null and b/2024-privacy-by-design/images/k-anon-survey.png differ diff --git a/2024-privacy-by-design/images/personalised-federation.png b/2024-privacy-by-design/images/personalised-federation.png new file mode 100644 index 0000000..8d20c35 Binary files /dev/null and b/2024-privacy-by-design/images/personalised-federation.png differ diff --git a/2024-privacy-by-design/images/private-ml-cycle.png b/2024-privacy-by-design/images/private-ml-cycle.png new file mode 100644 index 0000000..83b4684 Binary files /dev/null and b/2024-privacy-by-design/images/private-ml-cycle.png differ diff --git a/2024-privacy-by-design/images/private-ml-piepline.png b/2024-privacy-by-design/images/private-ml-piepline.png new file mode 100644 index 0000000..db34dda Binary files /dev/null and b/2024-privacy-by-design/images/private-ml-piepline.png differ diff --git a/2024-privacy-by-design/images/randomised-response-privacy.png b/2024-privacy-by-design/images/randomised-response-privacy.png new file mode 100644 index 0000000..aabd321 Binary files /dev/null and b/2024-privacy-by-design/images/randomised-response-privacy.png differ diff --git a/2024-privacy-by-design/images/randomised-response-tree.png b/2024-privacy-by-design/images/randomised-response-tree.png new file mode 100644 index 0000000..d10faac Binary files /dev/null and b/2024-privacy-by-design/images/randomised-response-tree.png differ diff --git a/2024-privacy-by-design/images/rigaki-garcia-2020.png b/2024-privacy-by-design/images/rigaki-garcia-2020.png new file mode 100644 index 0000000..c00de53 Binary files /dev/null and b/2024-privacy-by-design/images/rigaki-garcia-2020.png differ diff --git a/2024-privacy-by-design/images/snowball-1.png b/2024-privacy-by-design/images/snowball-1.png new file mode 100644 index 0000000..e5677ee Binary files /dev/null and b/2024-privacy-by-design/images/snowball-1.png differ diff --git a/2024-privacy-by-design/images/snowball-2.png b/2024-privacy-by-design/images/snowball-2.png new file mode 100644 index 0000000..69d4078 Binary files /dev/null and b/2024-privacy-by-design/images/snowball-2.png differ diff --git a/2024-privacy-by-design/images/snowball-3.png b/2024-privacy-by-design/images/snowball-3.png new file mode 100644 index 0000000..4ba40e9 Binary files /dev/null and b/2024-privacy-by-design/images/snowball-3.png differ diff --git a/2024-privacy-by-design/images/snowball-4.png b/2024-privacy-by-design/images/snowball-4.png new file mode 100644 index 0000000..302ebd7 Binary files /dev/null and b/2024-privacy-by-design/images/snowball-4.png differ diff --git a/2024-privacy-by-design/images/snowball-5.png b/2024-privacy-by-design/images/snowball-5.png new file mode 100644 index 0000000..b6b406b Binary files /dev/null and b/2024-privacy-by-design/images/snowball-5.png differ diff --git a/2024-privacy-by-design/images/vertical-federation.png b/2024-privacy-by-design/images/vertical-federation.png new file mode 100644 index 0000000..6d56be5 Binary files /dev/null and b/2024-privacy-by-design/images/vertical-federation.png differ diff --git a/2024-privacy-by-design/images/zv_c.jpg b/2024-privacy-by-design/images/zv_c.jpg new file mode 100644 index 0000000..53ce9e4 Binary files /dev/null and b/2024-privacy-by-design/images/zv_c.jpg differ diff --git a/2024-privacy-by-design/preview.png b/2024-privacy-by-design/preview.png new file mode 100644 index 0000000..905ff53 Binary files /dev/null and b/2024-privacy-by-design/preview.png differ diff --git a/2024-privacy-by-design/readme.md b/2024-privacy-by-design/readme.md new file mode 100644 index 0000000..606f614 --- /dev/null +++ b/2024-privacy-by-design/readme.md @@ -0,0 +1,10 @@ +# Workshop: Privacy by Design in the Machine Learning Pipeline + +## Description + +Slides for a half-day workshop at the University of Venice. + +![](preview.png) + +### Abstract + diff --git a/2024-privacy-by-design/~$hospital-example-complete.xlsx b/2024-privacy-by-design/~$hospital-example-complete.xlsx new file mode 100644 index 0000000..5a93205 Binary files /dev/null and b/2024-privacy-by-design/~$hospital-example-complete.xlsx differ diff --git a/2024-random-forests/2024-random-forests.html b/2024-random-forests/2024-random-forests.html new file mode 100644 index 0000000..4af6933 --- /dev/null +++ b/2024-random-forests/2024-random-forests.html @@ -0,0 +1,2684 @@ + + + + + + + + + + + + + + Introduction to Random Forests + + + + + + + + + + + + + + + +
+
+ +
+

Introduction to Random Forests

+

(via bootstrap aggregation, in ten minutes or less)

+ +
+
+
+Zak Varty +
+
+
+ +
+
+

Classification and Regression Trees - Recap

+
+
+
    +
  • Partition predictor space and predict modal/mean outcome in each subregion.
  • +
  • Sequential, conditional “cuts” perpendicular to predictor axes
  • +
  • Continue splitting until stopping criteria met +
      +
    • e.g. change in residual deviance is small.
    • +
  • +
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+

Classification and Regression Trees - Recap

+
+
+
    +
  • Easily interpretable model
  • +
  • bias-variance trade-off +
      +
    • decision boundaries bisect (continuous) data points, so are very sensitive to individual data point values.
    • +
    • This is a low-bias high-variance model but we want one that generalises well.
    • +
  • +
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+

Solution 1: Bagging

+

If \(Y_1, \ldots,Y_n\) are independent RVs with variance \(\sigma^2\) then

+

\[ \text{Var}(\bar Y) = \text{Var}\left(\frac{1}{n}\sum_{i=1}^{n} Y_i\right) = \frac{\sigma^2}{n}.\] This suggests that we could reduce the sensitivity of our tree-based predictions to the particular values in our dataset by:

+
    +
  • Taking many training sets
  • +
  • Fitting a decision tree to each
  • +
  • Averaging the predictions made by each tree.
  • +
+
+

This is the first example of an ensemble model. Common in weather/hazard modelling.

+
+
+
+

Bagging

+

Issue: we only have one set of training data.

+

Bootstrap Aggregation

+
    +
  1. Re-sample with replacement our original data \(x\), \(B\) times: \(\{x^1,\ldots,x^2,x^B\}\).
  2. +
  3. Fit tree \(\hat f_b(x)\) using \(x^b\) for \(b\) in \(1,\ldots,B\).
  4. +
  5. Take our ensemble prediction as the mean (mode) of all regression (classification) tree predictions.
  6. +
+

\[ \hat f(x) = \frac{1}{B}\sum_{i=1}^{n}\hat f_b(x).\]

+
+

Claim: This has a stabilising effect, reducing sensitivity to the particular data values we observe.

+
+
+
+

Bagging - Example (Bootstrap 1)

+ +
+
+

Bagging - Example (Bootstrap 1)

+ +
+
+

Bagging - Example (Bootstrap 1)

+

Fit a classification tree \(\hat f_1(x)\) to the first bootstrapped data set

+



+
+
+
+

+
+
+

+
+
+
+
+
+

Bagging - Example (Bootstrap 2)

+ +
+
+

Bagging - Example (Bootstrap 2)

+ +
+
+

Bagging - Example (Bootstrap 2)

+

Fit a classification tree \(\hat f_2(x)\) to the second bootstrapped data set

+



+
+
+
+

+
+
+

+
+
+
+
+
+

Bagging - Example (Repeat)

+
+
+
+

+
+
+

+
+
+

+
+
+

+
+
+
+
+

+
+
+

+
+
+

+
+
+

+
+
+
+
+

+
+
+

+
+
+

+
+
+

+
+
+
+
+
+

Bagging - Example (Aggregate)

+

Take point-wise modal class over all trees as prediction.

+ +
+
+

Bagging - Summary

+


+
    +
  • ✅ Reduced variance of final model, as compared to a single tree.
  • +
  • ✅ Built-in holdout sets for cross validation using “out of bag” points.
  • +
+
+


+
    +
  • ❌ Non-parametric bootstrap means we only see the same values as in our original data.
  • +
  • ❌ Aggregating trees destroys the interpretability of the model.
  • +
  • ❌ Each of the trees we are aggregating are likely to be similar. (*)
  • +
+
+
+
+

Random Forests

+

Suppose we have one very strong predictor and several moderately strong predictors.

+


+
+
    +
  • The first cut is going to be in the strong predictor for almost all bagged trees.
  • +
  • Leads to high “correlation” between trees (technically predictions of these trees)
  • +
  • Reduces the effective number of trees and the size of variance reduction compared to what we might initially have expected.
  • +
+
+
+
+

Random Forests

+

Exactly the same as bagging, but using only a random subset of \(m << p\) predictors to determine each split.

+
+

Seems like throwing away information, but can help us to reduce the dependence between the trees that we are aggregating.

+
+


+
+

Generalising what we had before:

+

\[ \text{Var}(\bar Y) = \frac{\sigma^2}{n} + \underset{\text{minimise this}}{\underbrace{\frac{2}{n} \sum_{i<j} \text{Cov}(Y_i, Y_j)}}.\]

+
+


+
+
+

Bioinformatics & multicollinearity: multiple genes expressed together, random subsetting allows us to “spread” the influence on the outcome across these genes.

+
+
+
+
+

Random Forest Summary

+
+

Random forests are an ensemble model, averaging the prediction of multiple regression or classification trees.

+
+
    +
  • Bootstrap aggregation reduces variance of the resulting predictions by averaging over multiple data sets that we might have seen.

  • +
  • Variance is further reduced by considering a random subset of predictors at each split, in order to decorrelate the trees we are aggregating.

  • +
+
+
+

Lab: Comparison of single tree, bagging and random forest for student grade prediction.

+
+
+
+
+

Build Information

+
+
+

R version 4.3.3 (2024-02-29)

+

Platform: x86_64-apple-darwin20 (64-bit)

+

locale: en_US.UTF-8||en_US.UTF-8||en_US.UTF-8||C||en_US.UTF-8||en_US.UTF-8

+

attached base packages: stats, graphics, grDevices, utils, datasets, methods and base

+

other attached packages: DescTools(v.0.99.58), rpart.plot(v.3.1.2), rpart(v.4.1.23), glue(v.1.8.0), ggplot2(v.3.5.1), dplyr(v.1.1.4) and palmerpenguins(v.0.1.1)

+

loaded via a namespace (and not attached): gld(v.2.6.6), gtable(v.0.3.5), xfun(v.0.43), lattice(v.0.22-5), vctrs(v.0.6.5), tools(v.4.3.3), generics(v.0.1.3), tibble(v.3.2.1), proxy(v.0.4-27), fansi(v.1.0.6), pkgconfig(v.2.0.3), Matrix(v.1.6-1.1), data.table(v.1.15.4), readxl(v.1.4.3), assertthat(v.0.2.1), lifecycle(v.1.0.4), rootSolve(v.1.8.2.4), compiler(v.4.3.3), farver(v.2.1.2), stringr(v.1.5.1), Exact(v.3.3), munsell(v.0.5.1), htmltools(v.0.5.8.1), class(v.7.3-22), yaml(v.2.3.8), pillar(v.1.9.0), crayon(v.1.5.3), MASS(v.7.3-60.0.1), boot(v.1.3-29), tidyselect(v.1.2.1), digest(v.0.6.35), mvtnorm(v.1.2-5), stringi(v.1.8.4), pander(v.0.6.5), purrr(v.1.0.2), showtextdb(v.3.0), labeling(v.0.4.3), forcats(v.1.0.0), zvplot(v.0.0.0.9000), fastmap(v.1.1.1), grid(v.4.3.3), colorspace(v.2.1-1), lmom(v.3.2), expm(v.1.0-0), cli(v.3.6.3), magrittr(v.2.0.3), emo(v.0.0.0.9000), utf8(v.1.2.4), e1071(v.1.7-14), withr(v.3.0.1), scales(v.1.3.0), showtext(v.0.9-7), lubridate(v.1.9.3), timechange(v.0.3.0), rmarkdown(v.2.26), httr(v.1.4.7), sysfonts(v.0.8.9), cellranger(v.1.1.0), hms(v.1.1.3), evaluate(v.0.23), knitr(v.1.45), haven(v.2.5.4), rlang(v.1.1.4), Rcpp(v.1.0.12), rstudioapi(v.0.16.0), jsonlite(v.1.8.8) and R6(v.2.5.1)

+
+
+
+

+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/2024-random-forests/2024-random-forests.qmd b/2024-random-forests/2024-random-forests.qmd new file mode 100644 index 0000000..3b0696e --- /dev/null +++ b/2024-random-forests/2024-random-forests.qmd @@ -0,0 +1,335 @@ +--- +title: "Introduction to Random Forests" +subtitle: "(via bootstrap aggregation, in ten minutes or less)" +author: Zak Varty +date: "" +editor: source +format: + revealjs: + theme: assets/zv-slides-theme.scss + logo: assets/zv-logo-192x192.png + bibliography: assets/refs.bib + footer: " November 2024 - Zak Varty" + menu: true + slide-number: true + show-slide-number: all # (all / print / speaker) + self-contained: true # (set to true before publishing html to web) + width: 1600 # default is 1050 + height: 900 # default is 850 + incremental: false +--- + +```{r} +library(palmerpenguins) +library(dplyr) +library(ggplot2) +library(glue) +library(rpart) +library(rpart.plot) +``` + +## Classification and Regression Trees - Recap + +::::{.columns} +:::{.column width="50%"} +- Partition predictor space and predict modal/mean outcome in each subregion. +- Sequential, conditional "cuts" perpendicular to predictor axes +- Continue splitting until stopping criteria met + - e.g. change in residual deviance is small. +::: +:::{.column width="50%"} + +```{r} +peng <- penguins %>% select(species, bill_length = bill_length_mm, bill_depth = bill_depth_mm) + +#ggplot() + +# geom_point(aes(x = bill_length, y = bill_depth, colour=species), data = peng) #+ +# theme_minimal() + +tree <- rpart(species ~ bill_length + bill_depth, data = peng, method = "class") +rpart.plot(tree, main = "Decision Tree for the Palmer Penguins Dataset") + +peng_grid <- tibble( + bill_length = rep(seq(30, 60, by = 0.1), each = 131), + bill_depth = rep(seq(12, 25, by = 0.1), times = 301), +) + +peng_grid$prediction <- rpart.predict(tree, newdata = peng_grid, type = "class") +``` + +::: +:::: + +## Classification and Regression Trees - Recap + +::::{.columns} +:::{.column width="50%"} + +- Easily interpretable model +- bias-variance trade-off + - decision boundaries bisect (continuous) data points, so are very sensitive to individual data point values. + - This is a low-bias high-variance model but we want one that generalises well. + +::: +:::{.column width="50%"} +```{r} +ggplot() + + geom_raster(aes(x = bill_length, y = bill_depth, fill=prediction), data = peng_grid, alpha = 0.3) + + geom_point(aes(x = bill_length, y = bill_depth, colour=species), data = peng) + + zvplot::theme_zv() +``` +::: +:::: + +## Solution 1: Bagging + +If $Y_1, \ldots,Y_n$ are independent RVs with variance $\sigma^2$ then + +$$ \text{Var}(\bar Y) = \text{Var}\left(\frac{1}{n}\sum_{i=1}^{n} Y_i\right) = \frac{\sigma^2}{n}.$$ +This suggests that we could reduce the sensitivity of our tree-based predictions to the particular values in our dataset by: + +- Taking many training sets +- Fitting a decision tree to each +- Averaging the predictions made by each tree. + +. . . + +This is the first example of an ensemble model. Common in weather/hazard modelling. + +## Bagging + +**Issue: we only have one set of training data.** + +_Bootstrap_ Aggregation + +1. Re-sample with replacement our original data $x$, $B$ times: $\{x^1,\ldots,x^2,x^B\}$. +2. Fit tree $\hat f_b(x)$ using $x^b$ for $b$ in $1,\ldots,B$. +3. Take our ensemble prediction as the mean (mode) of all regression (classification) tree predictions. + +$$ \hat f(x) = \frac{1}{B}\sum_{i=1}^{n}\hat f_b(x).$$ + +> **Claim:** This has a stabilising effect, reducing sensitivity to the particular data values we observe. + +## Bagging - Example (Bootstrap 1) + +```{r} +ggplot() + + geom_point(aes(x = bill_length, y = bill_depth, colour=species), data = peng, alpha = 0.5, size = 2) + + lims(x = c(30,60), y = c(12.5, 22.5)) + + zvplot::theme_zv() + + ggtitle("Take the original data") +``` + +## Bagging - Example (Bootstrap 1) + +```{r} +b <- 1 +i <- sample(1:nrow(peng), nrow(peng), replace = TRUE) +peng_b <- peng[i,] +ggplot() + + geom_point(aes(x = bill_length, y = bill_depth, colour=species), data = peng_b, alpha = 0.5, size = 2) + + lims(x = c(30,60), y = c(12.5, 22.5)) + + zvplot::theme_zv() + + ggtitle(glue("Resample with replacement to get bootstrap sample b={b}")) +``` + +## Bagging - Example (Bootstrap 1) + +Fit a classification tree $\hat f_1(x)$ to the first bootstrapped data set + +

+ +```{r} +#| layout-ncol: 2 + tree_b <- rpart(species ~ bill_length + bill_depth, data = peng_b, method = "class") + rpart.plot(tree_b, main = "Classification tree for the first bootstrapped dataset", sub = glue("Bootstrap sample b={b}")) + + peng_grid[,b+3] <- rpart.predict(tree_b, newdata = peng_grid, type = "class") + names(peng_grid)[b + 3] <- glue("b_{b}") + + ggplot() + + geom_raster(aes(x = bill_length, y = bill_depth, fill = .data[[glue("b_{b}")]]), data = peng_grid, alpha = 0.3, ) + + geom_point(aes(x = bill_length, y = bill_depth, colour=species), data = peng_b, alpha = 0.5) + + zvplot::theme_zv() + + ggtitle("Classification Tree Predictions", glue("bootstrap sample b={b}")) +``` + +## Bagging - Example (Bootstrap 2) + +```{r} +ggplot() + + geom_point(aes(x = bill_length, y = bill_depth, colour=species), data = peng, alpha = 0.5, size = 2) + + lims(x = c(30,60), y = c(12.5, 22.5)) + + zvplot::theme_zv() + + ggtitle("Take the original data, again") +``` + +## Bagging - Example (Bootstrap 2) + +```{r} +b <- 2 +i <- sample(1:nrow(peng), nrow(peng), replace = TRUE) +peng_b <- peng[i,] +ggplot() + + geom_point(aes(x = bill_length, y = bill_depth, colour=species), data = peng_b, alpha = 0.5, size = 2) + + lims(x = c(30,60), y = c(12.5, 22.5)) + + zvplot::theme_zv() + + ggtitle(glue("Resample with replacement to get another bootstrap sample b={b}")) +``` + +## Bagging - Example (Bootstrap 2) + +Fit a classification tree $\hat f_2(x)$ to the second bootstrapped data set + +

+ +```{r} +#| layout-ncol: 2 + tree_b <- rpart(species ~ bill_length + bill_depth, data = peng_b, method = "class") + rpart.plot(tree_b, main = "Classification tree for the first bootstrapped dataset", sub = glue("Bootstrap sample b={b}")) + + peng_grid[,b+3] <- rpart.predict(tree_b, newdata = peng_grid, type = "class") + names(peng_grid)[b + 3] <- glue("b_{b}") + + ggplot() + + geom_raster(aes(x = bill_length, y = bill_depth, fill = .data[[glue("b_{b}")]]), data = peng_grid, alpha = 0.3, ) + + geom_point(aes(x = bill_length, y = bill_depth, colour=species), data = peng_b, alpha = 0.5) + + zvplot::theme_zv() + + ggtitle("Classification Tree Predictions", glue("bootstrap sample b={b}")) +``` + + + +## Bagging - Example (Repeat) + +```{r} +tree <- rpart(species ~ bill_length + bill_depth, data = peng, method = "class") + +peng_grid <- tibble( + bill_length = rep(seq(30, 60, by = 0.1), each = 131), + bill_depth = rep(seq(12, 25, by = 0.1), times = 301), +) + +peng_grid$prediction <- rpart.predict(tree, newdata = peng_grid, type = "class") + + +plots <- list() +set.seed(1234) +for (b in 1:15) { + i <- sample(1:nrow(peng), nrow(peng), replace = TRUE) + peng_b <- peng[i,] + + tree_b <- rpart(species ~ bill_length + bill_depth, data = peng_b, method = "class") + + peng_grid[,b+3] <- rpart.predict(tree_b, newdata = peng_grid, type = "class") + names(peng_grid)[b + 3] <- glue("b_{b}") + + plots[[b]] <- ggplot() + + geom_raster(aes(x = bill_length, y = bill_depth, fill = .data[[glue("b_{b}")]]), data = peng_grid, alpha = 0.3, ) + + geom_point(aes(x = bill_length, y = bill_depth, colour=species), data = peng_b, alpha = 0.5) + + zvplot::theme_zv() + + ggtitle("Decision Tree Predictions", glue("bootstrap sample b={b}")) +} +``` + +```{r} +#| layout-ncol: 4 +plots[[1]] +plots[[2]] +plots[[3]] +plots[[4]] +plots[[5]] +plots[[6]] +plots[[7]] +plots[[8]] +plots[[9]] +plots[[10]] +plots[[11]] +plots[[12]] +``` + +## Bagging - Example (Aggregate) + +Take point-wise modal class over all trees as prediction. + +```{r} +#| fig-align: center +library(DescTools) +peng_grid$bag_pred <- apply(X = peng_grid[,4:18],MARGIN = 1, FUN = Mode) +peng_grid$bag_pred <- as.factor(peng_grid$bag_pred) + +ggplot() + + geom_raster(aes(x = bill_length, y = bill_depth, fill = .data[["bag_pred"]]), data = peng_grid, alpha = 0.3) + + geom_point(aes(x = bill_length, y = bill_depth, colour=species), data = peng, alpha = 0.5) + + zvplot::theme_zv() + + ggtitle("Bagged Tree Predictions") +``` + +## Bagging - Summary + +
+ +- ✅ Reduced variance of final model, as compared to a single tree. +- ✅ Built-in holdout sets for cross validation using "out of bag" points. + +. . . + +
+ +- `r emo::ji("cross mark")` Non-parametric bootstrap means we only see the same values as in our original data. +- `r emo::ji("cross mark")` Aggregating trees destroys the interpretability of the model. +- `r emo::ji("cross mark")` Each of the trees we are aggregating are likely to be similar. (*) + + +## Random Forests + +Suppose we have one very strong predictor and several moderately strong predictors. + +
+ +:::{.incremental} +- The first cut is going to be in the strong predictor for almost all bagged trees. +- Leads to high "correlation" between trees (technically predictions of these trees) +- Reduces the effective number of trees and the size of variance reduction compared to what we might initially have expected. +::: + +## Random Forests + +Exactly the same as bagging, but using **only a random subset of $m << p$ predictors** to determine each split. + +:::{.fragment} +Seems like throwing away information, but can help us to reduce the dependence between the trees that we are aggregating. +::: + +
+ +:::{.fragment} +Generalising what we had before: + +$$ \text{Var}(\bar Y) = \frac{\sigma^2}{n} + \underset{\text{minimise this}}{\underbrace{\frac{2}{n} \sum_{i + +:::{.fragment} +> Bioinformatics & multicollinearity: multiple genes expressed together, random subsetting allows us to "spread" the influence on the outcome across these genes. +::: +## Random Forest Summary + +> Random forests are an ensemble model, averaging the prediction of multiple regression or classification trees. + +- Bootstrap aggregation reduces variance of the resulting predictions by averaging over multiple data sets that we might have seen. + +- Variance is further reduced by considering a random subset of predictors at each split, in order to decorrelate the trees we are aggregating. + +. . . + +> Lab: Comparison of single tree, bagging and random forest for student grade prediction. + + + +## Build Information {.smaller} + +```{r} +pander::pander(sessionInfo()) +``` diff --git a/2024-random-forests/_extensions/quarto-ext/fontawesome/_extension.yml b/2024-random-forests/_extensions/quarto-ext/fontawesome/_extension.yml new file mode 100644 index 0000000..c0787a8 --- /dev/null +++ b/2024-random-forests/_extensions/quarto-ext/fontawesome/_extension.yml @@ -0,0 +1,7 @@ +title: Font Awesome support +author: Carlos Scheidegger +version: 1.1.0 +quarto-required: ">=1.2.269" +contributes: + shortcodes: + - fontawesome.lua diff --git a/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/css/all.css b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/css/all.css new file mode 100644 index 0000000..9c2adee --- /dev/null +++ b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/css/all.css @@ -0,0 +1,7831 @@ +/*! + * Font Awesome Free 6.1.1 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 2022 Fonticons, Inc. + */ +.fa { + font-family: var(--fa-style-family, "Font Awesome 6 Free"); + font-weight: var(--fa-style, 900); } + +.fa, +.fas, +.fa-solid, +.far, +.fa-regular, +.fal, +.fa-light, +.fat, +.fa-thin, +.fad, +.fa-duotone, +.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; } + +.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, 0); + animation-delay: var(--fa-animation-delay, 0); + -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, 0); + animation-delay: var(--fa-animation-delay, 0); + -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, 0); + animation-delay: var(--fa-animation-delay, 0); + -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, 0); + animation-delay: var(--fa-animation-delay, 0); + -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, 0); + animation-delay: var(--fa-animation-delay, 0); + -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, 0); + animation-delay: var(--fa-animation-delay, 0); + -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, 0); + animation-delay: var(--fa-animation-delay, 0); + -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; + transition-delay: 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, none)); + transform: rotate(var(--fa-rotate-angle, none)); } + +.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-a::before { + content: "\41"; } + +.fa-address-book::before { + content: "\f2b9"; } + +.fa-contact-book::before { + content: "\f2b9"; } + +.fa-address-card::before { + content: "\f2bb"; } + +.fa-contact-card::before { + content: "\f2bb"; } + +.fa-vcard::before { + content: "\f2bb"; } + +.fa-align-center::before { + content: "\f037"; } + +.fa-align-justify::before { + content: "\f039"; } + +.fa-align-left::before { + content: "\f036"; } + +.fa-align-right::before { + content: "\f038"; } + +.fa-anchor::before { + content: "\f13d"; } + +.fa-anchor-circle-check::before { + content: "\e4aa"; } + +.fa-anchor-circle-exclamation::before { + content: "\e4ab"; } + +.fa-anchor-circle-xmark::before { + content: "\e4ac"; } + +.fa-anchor-lock::before { + content: "\e4ad"; } + +.fa-angle-down::before { + content: "\f107"; } + +.fa-angle-left::before { + content: "\f104"; } + +.fa-angle-right::before { + content: "\f105"; } + +.fa-angle-up::before { + content: "\f106"; } + +.fa-angles-down::before { + content: "\f103"; } + +.fa-angle-double-down::before { + content: "\f103"; } + +.fa-angles-left::before { + content: "\f100"; } + +.fa-angle-double-left::before { + content: "\f100"; } + +.fa-angles-right::before { + content: "\f101"; } + +.fa-angle-double-right::before { + content: "\f101"; } + +.fa-angles-up::before { + content: "\f102"; } + +.fa-angle-double-up::before { + content: "\f102"; } + +.fa-ankh::before { + content: "\f644"; } + +.fa-apple-whole::before { + content: "\f5d1"; } + +.fa-apple-alt::before { + content: "\f5d1"; } + +.fa-archway::before { + content: "\f557"; } + +.fa-arrow-down::before { + content: "\f063"; } + +.fa-arrow-down-1-9::before { + content: "\f162"; } + +.fa-sort-numeric-asc::before { + content: "\f162"; } + +.fa-sort-numeric-down::before { + content: "\f162"; } + +.fa-arrow-down-9-1::before { + content: "\f886"; } + +.fa-sort-numeric-desc::before { + content: "\f886"; } + +.fa-sort-numeric-down-alt::before { + content: "\f886"; } + +.fa-arrow-down-a-z::before { + content: "\f15d"; } + +.fa-sort-alpha-asc::before { + content: "\f15d"; } + +.fa-sort-alpha-down::before { + content: "\f15d"; } + +.fa-arrow-down-long::before { + content: "\f175"; } + +.fa-long-arrow-down::before { + content: "\f175"; } + +.fa-arrow-down-short-wide::before { + content: "\f884"; } + +.fa-sort-amount-desc::before { + content: "\f884"; } + +.fa-sort-amount-down-alt::before { + content: "\f884"; } + +.fa-arrow-down-up-across-line::before { + content: "\e4af"; } + +.fa-arrow-down-up-lock::before { + content: "\e4b0"; } + +.fa-arrow-down-wide-short::before { + content: "\f160"; } + +.fa-sort-amount-asc::before { + content: "\f160"; } + +.fa-sort-amount-down::before { + content: "\f160"; } + +.fa-arrow-down-z-a::before { + content: "\f881"; } + +.fa-sort-alpha-desc::before { + content: "\f881"; } + +.fa-sort-alpha-down-alt::before { + content: "\f881"; } + +.fa-arrow-left::before { + content: "\f060"; } + +.fa-arrow-left-long::before { + content: "\f177"; } + +.fa-long-arrow-left::before { + content: "\f177"; } + +.fa-arrow-pointer::before { + content: "\f245"; } + +.fa-mouse-pointer::before { + content: "\f245"; } + +.fa-arrow-right::before { + content: "\f061"; } + +.fa-arrow-right-arrow-left::before { + content: "\f0ec"; } + +.fa-exchange::before { + content: "\f0ec"; } + +.fa-arrow-right-from-bracket::before { + content: "\f08b"; } + +.fa-sign-out::before { + content: "\f08b"; } + +.fa-arrow-right-long::before { + content: "\f178"; } + +.fa-long-arrow-right::before { + content: "\f178"; } + +.fa-arrow-right-to-bracket::before { + content: "\f090"; } + +.fa-sign-in::before { + content: "\f090"; } + +.fa-arrow-right-to-city::before { + content: "\e4b3"; } + +.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-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-arrow-trend-down::before { + content: "\e097"; } + +.fa-arrow-trend-up::before { + content: "\e098"; } + +.fa-arrow-turn-down::before { + content: "\f149"; } + +.fa-level-down::before { + content: "\f149"; } + +.fa-arrow-turn-up::before { + content: "\f148"; } + +.fa-level-up::before { + content: "\f148"; } + +.fa-arrow-up::before { + content: "\f062"; } + +.fa-arrow-up-1-9::before { + content: "\f163"; } + +.fa-sort-numeric-up::before { + content: "\f163"; } + +.fa-arrow-up-9-1::before { + content: "\f887"; } + +.fa-sort-numeric-up-alt::before { + content: "\f887"; } + +.fa-arrow-up-a-z::before { + content: "\f15e"; } + +.fa-sort-alpha-up::before { + content: "\f15e"; } + +.fa-arrow-up-from-bracket::before { + content: "\e09a"; } + +.fa-arrow-up-from-ground-water::before { + content: "\e4b5"; } + +.fa-arrow-up-from-water-pump::before { + content: "\e4b6"; } + +.fa-arrow-up-long::before { + content: "\f176"; } + +.fa-long-arrow-up::before { + content: "\f176"; } + +.fa-arrow-up-right-dots::before { + content: "\e4b7"; } + +.fa-arrow-up-right-from-square::before { + content: "\f08e"; } + +.fa-external-link::before { + content: "\f08e"; } + +.fa-arrow-up-short-wide::before { + content: "\f885"; } + +.fa-sort-amount-up-alt::before { + content: "\f885"; } + +.fa-arrow-up-wide-short::before { + content: "\f161"; } + +.fa-sort-amount-up::before { + content: "\f161"; } + +.fa-arrow-up-z-a::before { + content: "\f882"; } + +.fa-sort-alpha-up-alt::before { + content: "\f882"; } + +.fa-arrows-down-to-line::before { + content: "\e4b8"; } + +.fa-arrows-down-to-people::before { + content: "\e4b9"; } + +.fa-arrows-left-right::before { + content: "\f07e"; } + +.fa-arrows-h::before { + content: "\f07e"; } + +.fa-arrows-left-right-to-line::before { + content: "\e4ba"; } + +.fa-arrows-rotate::before { + content: "\f021"; } + +.fa-refresh::before { + content: "\f021"; } + +.fa-sync::before { + content: "\f021"; } + +.fa-arrows-spin::before { + content: "\e4bb"; } + +.fa-arrows-split-up-and-left::before { + content: "\e4bc"; } + +.fa-arrows-to-circle::before { + content: "\e4bd"; } + +.fa-arrows-to-dot::before { + content: "\e4be"; } + +.fa-arrows-to-eye::before { + content: "\e4bf"; } + +.fa-arrows-turn-right::before { + content: "\e4c0"; } + +.fa-arrows-turn-to-dots::before { + content: "\e4c1"; } + +.fa-arrows-up-down::before { + content: "\f07d"; } + +.fa-arrows-v::before { + content: "\f07d"; } + +.fa-arrows-up-down-left-right::before { + content: "\f047"; } + +.fa-arrows::before { + content: "\f047"; } + +.fa-arrows-up-to-line::before { + content: "\e4c2"; } + +.fa-asterisk::before { + content: "\2a"; } + +.fa-at::before { + content: "\40"; } + +.fa-atom::before { + content: "\f5d2"; } + +.fa-audio-description::before { + content: "\f29e"; } + +.fa-austral-sign::before { + content: "\e0a9"; } + +.fa-award::before { + content: "\f559"; } + +.fa-b::before { + content: "\42"; } + +.fa-baby::before { + content: "\f77c"; } + +.fa-baby-carriage::before { + content: "\f77d"; } + +.fa-carriage-baby::before { + content: "\f77d"; } + +.fa-backward::before { + content: "\f04a"; } + +.fa-backward-fast::before { + content: "\f049"; } + +.fa-fast-backward::before { + content: "\f049"; } + +.fa-backward-step::before { + content: "\f048"; } + +.fa-step-backward::before { + content: "\f048"; } + +.fa-bacon::before { + content: "\f7e5"; } + +.fa-bacteria::before { + content: "\e059"; } + +.fa-bacterium::before { + content: "\e05a"; } + +.fa-bag-shopping::before { + content: "\f290"; } + +.fa-shopping-bag::before { + content: "\f290"; } + +.fa-bahai::before { + content: "\f666"; } + +.fa-baht-sign::before { + content: "\e0ac"; } + +.fa-ban::before { + content: "\f05e"; } + +.fa-cancel::before { + content: "\f05e"; } + +.fa-ban-smoking::before { + content: "\f54d"; } + +.fa-smoking-ban::before { + content: "\f54d"; } + +.fa-bandage::before { + content: "\f462"; } + +.fa-band-aid::before { + content: "\f462"; } + +.fa-barcode::before { + content: "\f02a"; } + +.fa-bars::before { + content: "\f0c9"; } + +.fa-navicon::before { + content: "\f0c9"; } + +.fa-bars-progress::before { + content: "\f828"; } + +.fa-tasks-alt::before { + content: "\f828"; } + +.fa-bars-staggered::before { + content: "\f550"; } + +.fa-reorder::before { + content: "\f550"; } + +.fa-stream::before { + content: "\f550"; } + +.fa-baseball::before { + content: "\f433"; } + +.fa-baseball-ball::before { + content: "\f433"; } + +.fa-baseball-bat-ball::before { + content: "\f432"; } + +.fa-basket-shopping::before { + content: "\f291"; } + +.fa-shopping-basket::before { + content: "\f291"; } + +.fa-basketball::before { + content: "\f434"; } + +.fa-basketball-ball::before { + content: "\f434"; } + +.fa-bath::before { + content: "\f2cd"; } + +.fa-bathtub::before { + content: "\f2cd"; } + +.fa-battery-empty::before { + content: "\f244"; } + +.fa-battery-0::before { + content: "\f244"; } + +.fa-battery-full::before { + content: "\f240"; } + +.fa-battery::before { + content: "\f240"; } + +.fa-battery-5::before { + content: "\f240"; } + +.fa-battery-half::before { + content: "\f242"; } + +.fa-battery-3::before { + content: "\f242"; } + +.fa-battery-quarter::before { + content: "\f243"; } + +.fa-battery-2::before { + content: "\f243"; } + +.fa-battery-three-quarters::before { + content: "\f241"; } + +.fa-battery-4::before { + content: "\f241"; } + +.fa-bed::before { + content: "\f236"; } + +.fa-bed-pulse::before { + content: "\f487"; } + +.fa-procedures::before { + content: "\f487"; } + +.fa-beer-mug-empty::before { + content: "\f0fc"; } + +.fa-beer::before { + content: "\f0fc"; } + +.fa-bell::before { + content: "\f0f3"; } + +.fa-bell-concierge::before { + content: "\f562"; } + +.fa-concierge-bell::before { + content: "\f562"; } + +.fa-bell-slash::before { + content: "\f1f6"; } + +.fa-bezier-curve::before { + content: "\f55b"; } + +.fa-bicycle::before { + content: "\f206"; } + +.fa-binoculars::before { + content: "\f1e5"; } + +.fa-biohazard::before { + content: "\f780"; } + +.fa-bitcoin-sign::before { + content: "\e0b4"; } + +.fa-blender::before { + content: "\f517"; } + +.fa-blender-phone::before { + content: "\f6b6"; } + +.fa-blog::before { + content: "\f781"; } + +.fa-bold::before { + content: "\f032"; } + +.fa-bolt::before { + content: "\f0e7"; } + +.fa-zap::before { + content: "\f0e7"; } + +.fa-bolt-lightning::before { + content: "\e0b7"; } + +.fa-bomb::before { + content: "\f1e2"; } + +.fa-bone::before { + content: "\f5d7"; } + +.fa-bong::before { + content: "\f55c"; } + +.fa-book::before { + content: "\f02d"; } + +.fa-book-atlas::before { + content: "\f558"; } + +.fa-atlas::before { + content: "\f558"; } + +.fa-book-bible::before { + content: "\f647"; } + +.fa-bible::before { + content: "\f647"; } + +.fa-book-bookmark::before { + content: "\e0bb"; } + +.fa-book-journal-whills::before { + content: "\f66a"; } + +.fa-journal-whills::before { + content: "\f66a"; } + +.fa-book-medical::before { + content: "\f7e6"; } + +.fa-book-open::before { + content: "\f518"; } + +.fa-book-open-reader::before { + content: "\f5da"; } + +.fa-book-reader::before { + content: "\f5da"; } + +.fa-book-quran::before { + content: "\f687"; } + +.fa-quran::before { + content: "\f687"; } + +.fa-book-skull::before { + content: "\f6b7"; } + +.fa-book-dead::before { + content: "\f6b7"; } + +.fa-bookmark::before { + content: "\f02e"; } + +.fa-border-all::before { + content: "\f84c"; } + +.fa-border-none::before { + content: "\f850"; } + +.fa-border-top-left::before { + content: "\f853"; } + +.fa-border-style::before { + content: "\f853"; } + +.fa-bore-hole::before { + content: "\e4c3"; } + +.fa-bottle-droplet::before { + content: "\e4c4"; } + +.fa-bottle-water::before { + content: "\e4c5"; } + +.fa-bowl-food::before { + content: "\e4c6"; } + +.fa-bowl-rice::before { + content: "\e2eb"; } + +.fa-bowling-ball::before { + content: "\f436"; } + +.fa-box::before { + content: "\f466"; } + +.fa-box-archive::before { + content: "\f187"; } + +.fa-archive::before { + content: "\f187"; } + +.fa-box-open::before { + content: "\f49e"; } + +.fa-box-tissue::before { + content: "\e05b"; } + +.fa-boxes-packing::before { + content: "\e4c7"; } + +.fa-boxes-stacked::before { + content: "\f468"; } + +.fa-boxes::before { + content: "\f468"; } + +.fa-boxes-alt::before { + content: "\f468"; } + +.fa-braille::before { + content: "\f2a1"; } + +.fa-brain::before { + content: "\f5dc"; } + +.fa-brazilian-real-sign::before { + content: "\e46c"; } + +.fa-bread-slice::before { + content: "\f7ec"; } + +.fa-bridge::before { + content: "\e4c8"; } + +.fa-bridge-circle-check::before { + content: "\e4c9"; } + +.fa-bridge-circle-exclamation::before { + content: "\e4ca"; } + +.fa-bridge-circle-xmark::before { + content: "\e4cb"; } + +.fa-bridge-lock::before { + content: "\e4cc"; } + +.fa-bridge-water::before { + content: "\e4ce"; } + +.fa-briefcase::before { + content: "\f0b1"; } + +.fa-briefcase-medical::before { + content: "\f469"; } + +.fa-broom::before { + content: "\f51a"; } + +.fa-broom-ball::before { + content: "\f458"; } + +.fa-quidditch::before { + content: "\f458"; } + +.fa-quidditch-broom-ball::before { + content: "\f458"; } + +.fa-brush::before { + content: "\f55d"; } + +.fa-bucket::before { + content: "\e4cf"; } + +.fa-bug::before { + content: "\f188"; } + +.fa-bug-slash::before { + content: "\e490"; } + +.fa-bugs::before { + content: "\e4d0"; } + +.fa-building::before { + content: "\f1ad"; } + +.fa-building-circle-arrow-right::before { + content: "\e4d1"; } + +.fa-building-circle-check::before { + content: "\e4d2"; } + +.fa-building-circle-exclamation::before { + content: "\e4d3"; } + +.fa-building-circle-xmark::before { + content: "\e4d4"; } + +.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-building-flag::before { + content: "\e4d5"; } + +.fa-building-lock::before { + content: "\e4d6"; } + +.fa-building-ngo::before { + content: "\e4d7"; } + +.fa-building-shield::before { + content: "\e4d8"; } + +.fa-building-un::before { + content: "\e4d9"; } + +.fa-building-user::before { + content: "\e4da"; } + +.fa-building-wheat::before { + content: "\e4db"; } + +.fa-bullhorn::before { + content: "\f0a1"; } + +.fa-bullseye::before { + content: "\f140"; } + +.fa-burger::before { + content: "\f805"; } + +.fa-hamburger::before { + content: "\f805"; } + +.fa-burst::before { + content: "\e4dc"; } + +.fa-bus::before { + content: "\f207"; } + +.fa-bus-simple::before { + content: "\f55e"; } + +.fa-bus-alt::before { + content: "\f55e"; } + +.fa-business-time::before { + content: "\f64a"; } + +.fa-briefcase-clock::before { + content: "\f64a"; } + +.fa-c::before { + content: "\43"; } + +.fa-cake-candles::before { + content: "\f1fd"; } + +.fa-birthday-cake::before { + content: "\f1fd"; } + +.fa-cake::before { + content: "\f1fd"; } + +.fa-calculator::before { + content: "\f1ec"; } + +.fa-calendar::before { + content: "\f133"; } + +.fa-calendar-check::before { + content: "\f274"; } + +.fa-calendar-day::before { + content: "\f783"; } + +.fa-calendar-days::before { + content: "\f073"; } + +.fa-calendar-alt::before { + content: "\f073"; } + +.fa-calendar-minus::before { + content: "\f272"; } + +.fa-calendar-plus::before { + content: "\f271"; } + +.fa-calendar-week::before { + content: "\f784"; } + +.fa-calendar-xmark::before { + content: "\f273"; } + +.fa-calendar-times::before { + content: "\f273"; } + +.fa-camera::before { + content: "\f030"; } + +.fa-camera-alt::before { + content: "\f030"; } + +.fa-camera-retro::before { + content: "\f083"; } + +.fa-camera-rotate::before { + content: "\e0d8"; } + +.fa-campground::before { + content: "\f6bb"; } + +.fa-candy-cane::before { + content: "\f786"; } + +.fa-cannabis::before { + content: "\f55f"; } + +.fa-capsules::before { + content: "\f46b"; } + +.fa-car::before { + content: "\f1b9"; } + +.fa-automobile::before { + content: "\f1b9"; } + +.fa-car-battery::before { + content: "\f5df"; } + +.fa-battery-car::before { + content: "\f5df"; } + +.fa-car-burst::before { + content: "\f5e1"; } + +.fa-car-crash::before { + content: "\f5e1"; } + +.fa-car-on::before { + content: "\e4dd"; } + +.fa-car-rear::before { + content: "\f5de"; } + +.fa-car-alt::before { + content: "\f5de"; } + +.fa-car-side::before { + content: "\f5e4"; } + +.fa-car-tunnel::before { + content: "\e4de"; } + +.fa-caravan::before { + content: "\f8ff"; } + +.fa-caret-down::before { + content: "\f0d7"; } + +.fa-caret-left::before { + content: "\f0d9"; } + +.fa-caret-right::before { + content: "\f0da"; } + +.fa-caret-up::before { + content: "\f0d8"; } + +.fa-carrot::before { + content: "\f787"; } + +.fa-cart-arrow-down::before { + content: "\f218"; } + +.fa-cart-flatbed::before { + content: "\f474"; } + +.fa-dolly-flatbed::before { + content: "\f474"; } + +.fa-cart-flatbed-suitcase::before { + content: "\f59d"; } + +.fa-luggage-cart::before { + content: "\f59d"; } + +.fa-cart-plus::before { + content: "\f217"; } + +.fa-cart-shopping::before { + content: "\f07a"; } + +.fa-shopping-cart::before { + content: "\f07a"; } + +.fa-cash-register::before { + content: "\f788"; } + +.fa-cat::before { + content: "\f6be"; } + +.fa-cedi-sign::before { + content: "\e0df"; } + +.fa-cent-sign::before { + content: "\e3f5"; } + +.fa-certificate::before { + content: "\f0a3"; } + +.fa-chair::before { + content: "\f6c0"; } + +.fa-chalkboard::before { + content: "\f51b"; } + +.fa-blackboard::before { + content: "\f51b"; } + +.fa-chalkboard-user::before { + content: "\f51c"; } + +.fa-chalkboard-teacher::before { + content: "\f51c"; } + +.fa-champagne-glasses::before { + content: "\f79f"; } + +.fa-glass-cheers::before { + content: "\f79f"; } + +.fa-charging-station::before { + content: "\f5e7"; } + +.fa-chart-area::before { + content: "\f1fe"; } + +.fa-area-chart::before { + content: "\f1fe"; } + +.fa-chart-bar::before { + content: "\f080"; } + +.fa-bar-chart::before { + content: "\f080"; } + +.fa-chart-column::before { + content: "\e0e3"; } + +.fa-chart-gantt::before { + content: "\e0e4"; } + +.fa-chart-line::before { + content: "\f201"; } + +.fa-line-chart::before { + content: "\f201"; } + +.fa-chart-pie::before { + content: "\f200"; } + +.fa-pie-chart::before { + content: "\f200"; } + +.fa-chart-simple::before { + content: "\e473"; } + +.fa-check::before { + content: "\f00c"; } + +.fa-check-double::before { + content: "\f560"; } + +.fa-check-to-slot::before { + content: "\f772"; } + +.fa-vote-yea::before { + content: "\f772"; } + +.fa-cheese::before { + content: "\f7ef"; } + +.fa-chess::before { + content: "\f439"; } + +.fa-chess-bishop::before { + content: "\f43a"; } + +.fa-chess-board::before { + content: "\f43c"; } + +.fa-chess-king::before { + content: "\f43f"; } + +.fa-chess-knight::before { + content: "\f441"; } + +.fa-chess-pawn::before { + content: "\f443"; } + +.fa-chess-queen::before { + content: "\f445"; } + +.fa-chess-rook::before { + content: "\f447"; } + +.fa-chevron-down::before { + content: "\f078"; } + +.fa-chevron-left::before { + content: "\f053"; } + +.fa-chevron-right::before { + content: "\f054"; } + +.fa-chevron-up::before { + content: "\f077"; } + +.fa-child::before { + content: "\f1ae"; } + +.fa-child-dress::before { + content: "\e59c"; } + +.fa-child-reaching::before { + content: "\e59d"; } + +.fa-child-rifle::before { + content: "\e4e0"; } + +.fa-children::before { + content: "\e4e1"; } + +.fa-church::before { + content: "\f51d"; } + +.fa-circle::before { + content: "\f111"; } + +.fa-circle-arrow-down::before { + content: "\f0ab"; } + +.fa-arrow-circle-down::before { + content: "\f0ab"; } + +.fa-circle-arrow-left::before { + content: "\f0a8"; } + +.fa-arrow-circle-left::before { + content: "\f0a8"; } + +.fa-circle-arrow-right::before { + content: "\f0a9"; } + +.fa-arrow-circle-right::before { + content: "\f0a9"; } + +.fa-circle-arrow-up::before { + content: "\f0aa"; } + +.fa-arrow-circle-up::before { + content: "\f0aa"; } + +.fa-circle-check::before { + content: "\f058"; } + +.fa-check-circle::before { + content: "\f058"; } + +.fa-circle-chevron-down::before { + content: "\f13a"; } + +.fa-chevron-circle-down::before { + content: "\f13a"; } + +.fa-circle-chevron-left::before { + content: "\f137"; } + +.fa-chevron-circle-left::before { + content: "\f137"; } + +.fa-circle-chevron-right::before { + content: "\f138"; } + +.fa-chevron-circle-right::before { + content: "\f138"; } + +.fa-circle-chevron-up::before { + content: "\f139"; } + +.fa-chevron-circle-up::before { + content: "\f139"; } + +.fa-circle-dollar-to-slot::before { + content: "\f4b9"; } + +.fa-donate::before { + content: "\f4b9"; } + +.fa-circle-dot::before { + content: "\f192"; } + +.fa-dot-circle::before { + content: "\f192"; } + +.fa-circle-down::before { + content: "\f358"; } + +.fa-arrow-alt-circle-down::before { + content: "\f358"; } + +.fa-circle-exclamation::before { + content: "\f06a"; } + +.fa-exclamation-circle::before { + content: "\f06a"; } + +.fa-circle-h::before { + content: "\f47e"; } + +.fa-hospital-symbol::before { + content: "\f47e"; } + +.fa-circle-half-stroke::before { + content: "\f042"; } + +.fa-adjust::before { + content: "\f042"; } + +.fa-circle-info::before { + content: "\f05a"; } + +.fa-info-circle::before { + content: "\f05a"; } + +.fa-circle-left::before { + content: "\f359"; } + +.fa-arrow-alt-circle-left::before { + content: "\f359"; } + +.fa-circle-minus::before { + content: "\f056"; } + +.fa-minus-circle::before { + content: "\f056"; } + +.fa-circle-nodes::before { + content: "\e4e2"; } + +.fa-circle-notch::before { + content: "\f1ce"; } + +.fa-circle-pause::before { + content: "\f28b"; } + +.fa-pause-circle::before { + content: "\f28b"; } + +.fa-circle-play::before { + content: "\f144"; } + +.fa-play-circle::before { + content: "\f144"; } + +.fa-circle-plus::before { + content: "\f055"; } + +.fa-plus-circle::before { + content: "\f055"; } + +.fa-circle-question::before { + content: "\f059"; } + +.fa-question-circle::before { + content: "\f059"; } + +.fa-circle-radiation::before { + content: "\f7ba"; } + +.fa-radiation-alt::before { + content: "\f7ba"; } + +.fa-circle-right::before { + content: "\f35a"; } + +.fa-arrow-alt-circle-right::before { + content: "\f35a"; } + +.fa-circle-stop::before { + content: "\f28d"; } + +.fa-stop-circle::before { + content: "\f28d"; } + +.fa-circle-up::before { + content: "\f35b"; } + +.fa-arrow-alt-circle-up::before { + content: "\f35b"; } + +.fa-circle-user::before { + content: "\f2bd"; } + +.fa-user-circle::before { + content: "\f2bd"; } + +.fa-circle-xmark::before { + content: "\f057"; } + +.fa-times-circle::before { + content: "\f057"; } + +.fa-xmark-circle::before { + content: "\f057"; } + +.fa-city::before { + content: "\f64f"; } + +.fa-clapperboard::before { + content: "\e131"; } + +.fa-clipboard::before { + content: "\f328"; } + +.fa-clipboard-check::before { + content: "\f46c"; } + +.fa-clipboard-list::before { + content: "\f46d"; } + +.fa-clipboard-question::before { + content: "\e4e3"; } + +.fa-clipboard-user::before { + content: "\f7f3"; } + +.fa-clock::before { + content: "\f017"; } + +.fa-clock-four::before { + content: "\f017"; } + +.fa-clock-rotate-left::before { + content: "\f1da"; } + +.fa-history::before { + content: "\f1da"; } + +.fa-clone::before { + content: "\f24d"; } + +.fa-closed-captioning::before { + content: "\f20a"; } + +.fa-cloud::before { + content: "\f0c2"; } + +.fa-cloud-arrow-down::before { + content: "\f0ed"; } + +.fa-cloud-download::before { + content: "\f0ed"; } + +.fa-cloud-download-alt::before { + content: "\f0ed"; } + +.fa-cloud-arrow-up::before { + content: "\f0ee"; } + +.fa-cloud-upload::before { + content: "\f0ee"; } + +.fa-cloud-upload-alt::before { + content: "\f0ee"; } + +.fa-cloud-bolt::before { + content: "\f76c"; } + +.fa-thunderstorm::before { + content: "\f76c"; } + +.fa-cloud-meatball::before { + content: "\f73b"; } + +.fa-cloud-moon::before { + content: "\f6c3"; } + +.fa-cloud-moon-rain::before { + content: "\f73c"; } + +.fa-cloud-rain::before { + content: "\f73d"; } + +.fa-cloud-showers-heavy::before { + content: "\f740"; } + +.fa-cloud-showers-water::before { + content: "\e4e4"; } + +.fa-cloud-sun::before { + content: "\f6c4"; } + +.fa-cloud-sun-rain::before { + content: "\f743"; } + +.fa-clover::before { + content: "\e139"; } + +.fa-code::before { + content: "\f121"; } + +.fa-code-branch::before { + content: "\f126"; } + +.fa-code-commit::before { + content: "\f386"; } + +.fa-code-compare::before { + content: "\e13a"; } + +.fa-code-fork::before { + content: "\e13b"; } + +.fa-code-merge::before { + content: "\f387"; } + +.fa-code-pull-request::before { + content: "\e13c"; } + +.fa-coins::before { + content: "\f51e"; } + +.fa-colon-sign::before { + content: "\e140"; } + +.fa-comment::before { + content: "\f075"; } + +.fa-comment-dollar::before { + content: "\f651"; } + +.fa-comment-dots::before { + content: "\f4ad"; } + +.fa-commenting::before { + content: "\f4ad"; } + +.fa-comment-medical::before { + content: "\f7f5"; } + +.fa-comment-slash::before { + content: "\f4b3"; } + +.fa-comment-sms::before { + content: "\f7cd"; } + +.fa-sms::before { + content: "\f7cd"; } + +.fa-comments::before { + content: "\f086"; } + +.fa-comments-dollar::before { + content: "\f653"; } + +.fa-compact-disc::before { + content: "\f51f"; } + +.fa-compass::before { + content: "\f14e"; } + +.fa-compass-drafting::before { + content: "\f568"; } + +.fa-drafting-compass::before { + content: "\f568"; } + +.fa-compress::before { + content: "\f066"; } + +.fa-computer::before { + content: "\e4e5"; } + +.fa-computer-mouse::before { + content: "\f8cc"; } + +.fa-mouse::before { + content: "\f8cc"; } + +.fa-cookie::before { + content: "\f563"; } + +.fa-cookie-bite::before { + content: "\f564"; } + +.fa-copy::before { + content: "\f0c5"; } + +.fa-copyright::before { + content: "\f1f9"; } + +.fa-couch::before { + content: "\f4b8"; } + +.fa-cow::before { + content: "\f6c8"; } + +.fa-credit-card::before { + content: "\f09d"; } + +.fa-credit-card-alt::before { + content: "\f09d"; } + +.fa-crop::before { + content: "\f125"; } + +.fa-crop-simple::before { + content: "\f565"; } + +.fa-crop-alt::before { + content: "\f565"; } + +.fa-cross::before { + content: "\f654"; } + +.fa-crosshairs::before { + content: "\f05b"; } + +.fa-crow::before { + content: "\f520"; } + +.fa-crown::before { + content: "\f521"; } + +.fa-crutch::before { + content: "\f7f7"; } + +.fa-cruzeiro-sign::before { + content: "\e152"; } + +.fa-cube::before { + content: "\f1b2"; } + +.fa-cubes::before { + content: "\f1b3"; } + +.fa-cubes-stacked::before { + content: "\e4e6"; } + +.fa-d::before { + content: "\44"; } + +.fa-database::before { + content: "\f1c0"; } + +.fa-delete-left::before { + content: "\f55a"; } + +.fa-backspace::before { + content: "\f55a"; } + +.fa-democrat::before { + content: "\f747"; } + +.fa-desktop::before { + content: "\f390"; } + +.fa-desktop-alt::before { + content: "\f390"; } + +.fa-dharmachakra::before { + content: "\f655"; } + +.fa-diagram-next::before { + content: "\e476"; } + +.fa-diagram-predecessor::before { + content: "\e477"; } + +.fa-diagram-project::before { + content: "\f542"; } + +.fa-project-diagram::before { + content: "\f542"; } + +.fa-diagram-successor::before { + content: "\e47a"; } + +.fa-diamond::before { + content: "\f219"; } + +.fa-diamond-turn-right::before { + content: "\f5eb"; } + +.fa-directions::before { + content: "\f5eb"; } + +.fa-dice::before { + content: "\f522"; } + +.fa-dice-d20::before { + content: "\f6cf"; } + +.fa-dice-d6::before { + content: "\f6d1"; } + +.fa-dice-five::before { + content: "\f523"; } + +.fa-dice-four::before { + content: "\f524"; } + +.fa-dice-one::before { + content: "\f525"; } + +.fa-dice-six::before { + content: "\f526"; } + +.fa-dice-three::before { + content: "\f527"; } + +.fa-dice-two::before { + content: "\f528"; } + +.fa-disease::before { + content: "\f7fa"; } + +.fa-display::before { + content: "\e163"; } + +.fa-divide::before { + content: "\f529"; } + +.fa-dna::before { + content: "\f471"; } + +.fa-dog::before { + content: "\f6d3"; } + +.fa-dollar-sign::before { + content: "\24"; } + +.fa-dollar::before { + content: "\24"; } + +.fa-usd::before { + content: "\24"; } + +.fa-dolly::before { + content: "\f472"; } + +.fa-dolly-box::before { + content: "\f472"; } + +.fa-dong-sign::before { + content: "\e169"; } + +.fa-door-closed::before { + content: "\f52a"; } + +.fa-door-open::before { + content: "\f52b"; } + +.fa-dove::before { + content: "\f4ba"; } + +.fa-down-left-and-up-right-to-center::before { + content: "\f422"; } + +.fa-compress-alt::before { + content: "\f422"; } + +.fa-down-long::before { + content: "\f309"; } + +.fa-long-arrow-alt-down::before { + content: "\f309"; } + +.fa-download::before { + content: "\f019"; } + +.fa-dragon::before { + content: "\f6d5"; } + +.fa-draw-polygon::before { + content: "\f5ee"; } + +.fa-droplet::before { + content: "\f043"; } + +.fa-tint::before { + content: "\f043"; } + +.fa-droplet-slash::before { + content: "\f5c7"; } + +.fa-tint-slash::before { + content: "\f5c7"; } + +.fa-drum::before { + content: "\f569"; } + +.fa-drum-steelpan::before { + content: "\f56a"; } + +.fa-drumstick-bite::before { + content: "\f6d7"; } + +.fa-dumbbell::before { + content: "\f44b"; } + +.fa-dumpster::before { + content: "\f793"; } + +.fa-dumpster-fire::before { + content: "\f794"; } + +.fa-dungeon::before { + content: "\f6d9"; } + +.fa-e::before { + content: "\45"; } + +.fa-ear-deaf::before { + content: "\f2a4"; } + +.fa-deaf::before { + content: "\f2a4"; } + +.fa-deafness::before { + content: "\f2a4"; } + +.fa-hard-of-hearing::before { + content: "\f2a4"; } + +.fa-ear-listen::before { + content: "\f2a2"; } + +.fa-assistive-listening-systems::before { + content: "\f2a2"; } + +.fa-earth-africa::before { + content: "\f57c"; } + +.fa-globe-africa::before { + content: "\f57c"; } + +.fa-earth-americas::before { + content: "\f57d"; } + +.fa-earth::before { + content: "\f57d"; } + +.fa-earth-america::before { + content: "\f57d"; } + +.fa-globe-americas::before { + content: "\f57d"; } + +.fa-earth-asia::before { + content: "\f57e"; } + +.fa-globe-asia::before { + content: "\f57e"; } + +.fa-earth-europe::before { + content: "\f7a2"; } + +.fa-globe-europe::before { + content: "\f7a2"; } + +.fa-earth-oceania::before { + content: "\e47b"; } + +.fa-globe-oceania::before { + content: "\e47b"; } + +.fa-egg::before { + content: "\f7fb"; } + +.fa-eject::before { + content: "\f052"; } + +.fa-elevator::before { + content: "\e16d"; } + +.fa-ellipsis::before { + content: "\f141"; } + +.fa-ellipsis-h::before { + content: "\f141"; } + +.fa-ellipsis-vertical::before { + content: "\f142"; } + +.fa-ellipsis-v::before { + content: "\f142"; } + +.fa-envelope::before { + content: "\f0e0"; } + +.fa-envelope-circle-check::before { + content: "\e4e8"; } + +.fa-envelope-open::before { + content: "\f2b6"; } + +.fa-envelope-open-text::before { + content: "\f658"; } + +.fa-envelopes-bulk::before { + content: "\f674"; } + +.fa-mail-bulk::before { + content: "\f674"; } + +.fa-equals::before { + content: "\3d"; } + +.fa-eraser::before { + content: "\f12d"; } + +.fa-ethernet::before { + content: "\f796"; } + +.fa-euro-sign::before { + content: "\f153"; } + +.fa-eur::before { + content: "\f153"; } + +.fa-euro::before { + content: "\f153"; } + +.fa-exclamation::before { + content: "\21"; } + +.fa-expand::before { + content: "\f065"; } + +.fa-explosion::before { + content: "\e4e9"; } + +.fa-eye::before { + content: "\f06e"; } + +.fa-eye-dropper::before { + content: "\f1fb"; } + +.fa-eye-dropper-empty::before { + content: "\f1fb"; } + +.fa-eyedropper::before { + content: "\f1fb"; } + +.fa-eye-low-vision::before { + content: "\f2a8"; } + +.fa-low-vision::before { + content: "\f2a8"; } + +.fa-eye-slash::before { + content: "\f070"; } + +.fa-f::before { + content: "\46"; } + +.fa-face-angry::before { + content: "\f556"; } + +.fa-angry::before { + content: "\f556"; } + +.fa-face-dizzy::before { + content: "\f567"; } + +.fa-dizzy::before { + content: "\f567"; } + +.fa-face-flushed::before { + content: "\f579"; } + +.fa-flushed::before { + content: "\f579"; } + +.fa-face-frown::before { + content: "\f119"; } + +.fa-frown::before { + content: "\f119"; } + +.fa-face-frown-open::before { + content: "\f57a"; } + +.fa-frown-open::before { + content: "\f57a"; } + +.fa-face-grimace::before { + content: "\f57f"; } + +.fa-grimace::before { + content: "\f57f"; } + +.fa-face-grin::before { + content: "\f580"; } + +.fa-grin::before { + content: "\f580"; } + +.fa-face-grin-beam::before { + content: "\f582"; } + +.fa-grin-beam::before { + content: "\f582"; } + +.fa-face-grin-beam-sweat::before { + content: "\f583"; } + +.fa-grin-beam-sweat::before { + content: "\f583"; } + +.fa-face-grin-hearts::before { + content: "\f584"; } + +.fa-grin-hearts::before { + content: "\f584"; } + +.fa-face-grin-squint::before { + content: "\f585"; } + +.fa-grin-squint::before { + content: "\f585"; } + +.fa-face-grin-squint-tears::before { + content: "\f586"; } + +.fa-grin-squint-tears::before { + content: "\f586"; } + +.fa-face-grin-stars::before { + content: "\f587"; } + +.fa-grin-stars::before { + content: "\f587"; } + +.fa-face-grin-tears::before { + content: "\f588"; } + +.fa-grin-tears::before { + content: "\f588"; } + +.fa-face-grin-tongue::before { + content: "\f589"; } + +.fa-grin-tongue::before { + content: "\f589"; } + +.fa-face-grin-tongue-squint::before { + content: "\f58a"; } + +.fa-grin-tongue-squint::before { + content: "\f58a"; } + +.fa-face-grin-tongue-wink::before { + content: "\f58b"; } + +.fa-grin-tongue-wink::before { + content: "\f58b"; } + +.fa-face-grin-wide::before { + content: "\f581"; } + +.fa-grin-alt::before { + content: "\f581"; } + +.fa-face-grin-wink::before { + content: "\f58c"; } + +.fa-grin-wink::before { + content: "\f58c"; } + +.fa-face-kiss::before { + content: "\f596"; } + +.fa-kiss::before { + content: "\f596"; } + +.fa-face-kiss-beam::before { + content: "\f597"; } + +.fa-kiss-beam::before { + content: "\f597"; } + +.fa-face-kiss-wink-heart::before { + content: "\f598"; } + +.fa-kiss-wink-heart::before { + content: "\f598"; } + +.fa-face-laugh::before { + content: "\f599"; } + +.fa-laugh::before { + content: "\f599"; } + +.fa-face-laugh-beam::before { + content: "\f59a"; } + +.fa-laugh-beam::before { + content: "\f59a"; } + +.fa-face-laugh-squint::before { + content: "\f59b"; } + +.fa-laugh-squint::before { + content: "\f59b"; } + +.fa-face-laugh-wink::before { + content: "\f59c"; } + +.fa-laugh-wink::before { + content: "\f59c"; } + +.fa-face-meh::before { + content: "\f11a"; } + +.fa-meh::before { + content: "\f11a"; } + +.fa-face-meh-blank::before { + content: "\f5a4"; } + +.fa-meh-blank::before { + content: "\f5a4"; } + +.fa-face-rolling-eyes::before { + content: "\f5a5"; } + +.fa-meh-rolling-eyes::before { + content: "\f5a5"; } + +.fa-face-sad-cry::before { + content: "\f5b3"; } + +.fa-sad-cry::before { + content: "\f5b3"; } + +.fa-face-sad-tear::before { + content: "\f5b4"; } + +.fa-sad-tear::before { + content: "\f5b4"; } + +.fa-face-smile::before { + content: "\f118"; } + +.fa-smile::before { + content: "\f118"; } + +.fa-face-smile-beam::before { + content: "\f5b8"; } + +.fa-smile-beam::before { + content: "\f5b8"; } + +.fa-face-smile-wink::before { + content: "\f4da"; } + +.fa-smile-wink::before { + content: "\f4da"; } + +.fa-face-surprise::before { + content: "\f5c2"; } + +.fa-surprise::before { + content: "\f5c2"; } + +.fa-face-tired::before { + content: "\f5c8"; } + +.fa-tired::before { + content: "\f5c8"; } + +.fa-fan::before { + content: "\f863"; } + +.fa-faucet::before { + content: "\e005"; } + +.fa-faucet-drip::before { + content: "\e006"; } + +.fa-fax::before { + content: "\f1ac"; } + +.fa-feather::before { + content: "\f52d"; } + +.fa-feather-pointed::before { + content: "\f56b"; } + +.fa-feather-alt::before { + content: "\f56b"; } + +.fa-ferry::before { + content: "\e4ea"; } + +.fa-file::before { + content: "\f15b"; } + +.fa-file-arrow-down::before { + content: "\f56d"; } + +.fa-file-download::before { + content: "\f56d"; } + +.fa-file-arrow-up::before { + content: "\f574"; } + +.fa-file-upload::before { + content: "\f574"; } + +.fa-file-audio::before { + content: "\f1c7"; } + +.fa-file-circle-check::before { + content: "\e493"; } + +.fa-file-circle-exclamation::before { + content: "\e4eb"; } + +.fa-file-circle-minus::before { + content: "\e4ed"; } + +.fa-file-circle-plus::before { + content: "\e4ee"; } + +.fa-file-circle-question::before { + content: "\e4ef"; } + +.fa-file-circle-xmark::before { + content: "\e494"; } + +.fa-file-code::before { + content: "\f1c9"; } + +.fa-file-contract::before { + content: "\f56c"; } + +.fa-file-csv::before { + content: "\f6dd"; } + +.fa-file-excel::before { + content: "\f1c3"; } + +.fa-file-export::before { + content: "\f56e"; } + +.fa-arrow-right-from-file::before { + content: "\f56e"; } + +.fa-file-image::before { + content: "\f1c5"; } + +.fa-file-import::before { + content: "\f56f"; } + +.fa-arrow-right-to-file::before { + content: "\f56f"; } + +.fa-file-invoice::before { + content: "\f570"; } + +.fa-file-invoice-dollar::before { + content: "\f571"; } + +.fa-file-lines::before { + content: "\f15c"; } + +.fa-file-alt::before { + content: "\f15c"; } + +.fa-file-text::before { + content: "\f15c"; } + +.fa-file-medical::before { + content: "\f477"; } + +.fa-file-pdf::before { + content: "\f1c1"; } + +.fa-file-pen::before { + content: "\f31c"; } + +.fa-file-edit::before { + content: "\f31c"; } + +.fa-file-powerpoint::before { + content: "\f1c4"; } + +.fa-file-prescription::before { + content: "\f572"; } + +.fa-file-shield::before { + content: "\e4f0"; } + +.fa-file-signature::before { + content: "\f573"; } + +.fa-file-video::before { + content: "\f1c8"; } + +.fa-file-waveform::before { + content: "\f478"; } + +.fa-file-medical-alt::before { + content: "\f478"; } + +.fa-file-word::before { + content: "\f1c2"; } + +.fa-file-zipper::before { + content: "\f1c6"; } + +.fa-file-archive::before { + content: "\f1c6"; } + +.fa-fill::before { + content: "\f575"; } + +.fa-fill-drip::before { + content: "\f576"; } + +.fa-film::before { + content: "\f008"; } + +.fa-filter::before { + content: "\f0b0"; } + +.fa-filter-circle-dollar::before { + content: "\f662"; } + +.fa-funnel-dollar::before { + content: "\f662"; } + +.fa-filter-circle-xmark::before { + content: "\e17b"; } + +.fa-fingerprint::before { + content: "\f577"; } + +.fa-fire::before { + content: "\f06d"; } + +.fa-fire-burner::before { + content: "\e4f1"; } + +.fa-fire-extinguisher::before { + content: "\f134"; } + +.fa-fire-flame-curved::before { + content: "\f7e4"; } + +.fa-fire-alt::before { + content: "\f7e4"; } + +.fa-fire-flame-simple::before { + content: "\f46a"; } + +.fa-burn::before { + content: "\f46a"; } + +.fa-fish::before { + content: "\f578"; } + +.fa-fish-fins::before { + content: "\e4f2"; } + +.fa-flag::before { + content: "\f024"; } + +.fa-flag-checkered::before { + content: "\f11e"; } + +.fa-flag-usa::before { + content: "\f74d"; } + +.fa-flask::before { + content: "\f0c3"; } + +.fa-flask-vial::before { + content: "\e4f3"; } + +.fa-floppy-disk::before { + content: "\f0c7"; } + +.fa-save::before { + content: "\f0c7"; } + +.fa-florin-sign::before { + content: "\e184"; } + +.fa-folder::before { + content: "\f07b"; } + +.fa-folder-blank::before { + content: "\f07b"; } + +.fa-folder-closed::before { + content: "\e185"; } + +.fa-folder-minus::before { + content: "\f65d"; } + +.fa-folder-open::before { + content: "\f07c"; } + +.fa-folder-plus::before { + content: "\f65e"; } + +.fa-folder-tree::before { + content: "\f802"; } + +.fa-font::before { + content: "\f031"; } + +.fa-football::before { + content: "\f44e"; } + +.fa-football-ball::before { + content: "\f44e"; } + +.fa-forward::before { + content: "\f04e"; } + +.fa-forward-fast::before { + content: "\f050"; } + +.fa-fast-forward::before { + content: "\f050"; } + +.fa-forward-step::before { + content: "\f051"; } + +.fa-step-forward::before { + content: "\f051"; } + +.fa-franc-sign::before { + content: "\e18f"; } + +.fa-frog::before { + content: "\f52e"; } + +.fa-futbol::before { + content: "\f1e3"; } + +.fa-futbol-ball::before { + content: "\f1e3"; } + +.fa-soccer-ball::before { + content: "\f1e3"; } + +.fa-g::before { + content: "\47"; } + +.fa-gamepad::before { + content: "\f11b"; } + +.fa-gas-pump::before { + content: "\f52f"; } + +.fa-gauge::before { + content: "\f624"; } + +.fa-dashboard::before { + content: "\f624"; } + +.fa-gauge-med::before { + content: "\f624"; } + +.fa-tachometer-alt-average::before { + content: "\f624"; } + +.fa-gauge-high::before { + content: "\f625"; } + +.fa-tachometer-alt::before { + content: "\f625"; } + +.fa-tachometer-alt-fast::before { + content: "\f625"; } + +.fa-gauge-simple::before { + content: "\f629"; } + +.fa-gauge-simple-med::before { + content: "\f629"; } + +.fa-tachometer-average::before { + content: "\f629"; } + +.fa-gauge-simple-high::before { + content: "\f62a"; } + +.fa-tachometer::before { + content: "\f62a"; } + +.fa-tachometer-fast::before { + content: "\f62a"; } + +.fa-gavel::before { + content: "\f0e3"; } + +.fa-legal::before { + content: "\f0e3"; } + +.fa-gear::before { + content: "\f013"; } + +.fa-cog::before { + content: "\f013"; } + +.fa-gears::before { + content: "\f085"; } + +.fa-cogs::before { + content: "\f085"; } + +.fa-gem::before { + content: "\f3a5"; } + +.fa-genderless::before { + content: "\f22d"; } + +.fa-ghost::before { + content: "\f6e2"; } + +.fa-gift::before { + content: "\f06b"; } + +.fa-gifts::before { + content: "\f79c"; } + +.fa-glass-water::before { + content: "\e4f4"; } + +.fa-glass-water-droplet::before { + content: "\e4f5"; } + +.fa-glasses::before { + content: "\f530"; } + +.fa-globe::before { + content: "\f0ac"; } + +.fa-golf-ball-tee::before { + content: "\f450"; } + +.fa-golf-ball::before { + content: "\f450"; } + +.fa-gopuram::before { + content: "\f664"; } + +.fa-graduation-cap::before { + content: "\f19d"; } + +.fa-mortar-board::before { + content: "\f19d"; } + +.fa-greater-than::before { + content: "\3e"; } + +.fa-greater-than-equal::before { + content: "\f532"; } + +.fa-grip::before { + content: "\f58d"; } + +.fa-grip-horizontal::before { + content: "\f58d"; } + +.fa-grip-lines::before { + content: "\f7a4"; } + +.fa-grip-lines-vertical::before { + content: "\f7a5"; } + +.fa-grip-vertical::before { + content: "\f58e"; } + +.fa-group-arrows-rotate::before { + content: "\e4f6"; } + +.fa-guarani-sign::before { + content: "\e19a"; } + +.fa-guitar::before { + content: "\f7a6"; } + +.fa-gun::before { + content: "\e19b"; } + +.fa-h::before { + content: "\48"; } + +.fa-hammer::before { + content: "\f6e3"; } + +.fa-hamsa::before { + content: "\f665"; } + +.fa-hand::before { + content: "\f256"; } + +.fa-hand-paper::before { + content: "\f256"; } + +.fa-hand-back-fist::before { + content: "\f255"; } + +.fa-hand-rock::before { + content: "\f255"; } + +.fa-hand-dots::before { + content: "\f461"; } + +.fa-allergies::before { + content: "\f461"; } + +.fa-hand-fist::before { + content: "\f6de"; } + +.fa-fist-raised::before { + content: "\f6de"; } + +.fa-hand-holding::before { + content: "\f4bd"; } + +.fa-hand-holding-dollar::before { + content: "\f4c0"; } + +.fa-hand-holding-usd::before { + content: "\f4c0"; } + +.fa-hand-holding-droplet::before { + content: "\f4c1"; } + +.fa-hand-holding-water::before { + content: "\f4c1"; } + +.fa-hand-holding-hand::before { + content: "\e4f7"; } + +.fa-hand-holding-heart::before { + content: "\f4be"; } + +.fa-hand-holding-medical::before { + content: "\e05c"; } + +.fa-hand-lizard::before { + content: "\f258"; } + +.fa-hand-middle-finger::before { + content: "\f806"; } + +.fa-hand-peace::before { + content: "\f25b"; } + +.fa-hand-point-down::before { + content: "\f0a7"; } + +.fa-hand-point-left::before { + content: "\f0a5"; } + +.fa-hand-point-right::before { + content: "\f0a4"; } + +.fa-hand-point-up::before { + content: "\f0a6"; } + +.fa-hand-pointer::before { + content: "\f25a"; } + +.fa-hand-scissors::before { + content: "\f257"; } + +.fa-hand-sparkles::before { + content: "\e05d"; } + +.fa-hand-spock::before { + content: "\f259"; } + +.fa-handcuffs::before { + content: "\e4f8"; } + +.fa-hands::before { + content: "\f2a7"; } + +.fa-sign-language::before { + content: "\f2a7"; } + +.fa-signing::before { + content: "\f2a7"; } + +.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-hands-bound::before { + content: "\e4f9"; } + +.fa-hands-bubbles::before { + content: "\e05e"; } + +.fa-hands-wash::before { + content: "\e05e"; } + +.fa-hands-clapping::before { + content: "\e1a8"; } + +.fa-hands-holding::before { + content: "\f4c2"; } + +.fa-hands-holding-child::before { + content: "\e4fa"; } + +.fa-hands-holding-circle::before { + content: "\e4fb"; } + +.fa-hands-praying::before { + content: "\f684"; } + +.fa-praying-hands::before { + content: "\f684"; } + +.fa-handshake::before { + content: "\f2b5"; } + +.fa-handshake-angle::before { + content: "\f4c4"; } + +.fa-hands-helping::before { + content: "\f4c4"; } + +.fa-handshake-simple::before { + content: "\f4c6"; } + +.fa-handshake-alt::before { + content: "\f4c6"; } + +.fa-handshake-simple-slash::before { + content: "\e05f"; } + +.fa-handshake-alt-slash::before { + content: "\e05f"; } + +.fa-handshake-slash::before { + content: "\e060"; } + +.fa-hanukiah::before { + content: "\f6e6"; } + +.fa-hard-drive::before { + content: "\f0a0"; } + +.fa-hdd::before { + content: "\f0a0"; } + +.fa-hashtag::before { + content: "\23"; } + +.fa-hat-cowboy::before { + content: "\f8c0"; } + +.fa-hat-cowboy-side::before { + content: "\f8c1"; } + +.fa-hat-wizard::before { + content: "\f6e8"; } + +.fa-head-side-cough::before { + content: "\e061"; } + +.fa-head-side-cough-slash::before { + content: "\e062"; } + +.fa-head-side-mask::before { + content: "\e063"; } + +.fa-head-side-virus::before { + content: "\e064"; } + +.fa-heading::before { + content: "\f1dc"; } + +.fa-header::before { + content: "\f1dc"; } + +.fa-headphones::before { + content: "\f025"; } + +.fa-headphones-simple::before { + content: "\f58f"; } + +.fa-headphones-alt::before { + content: "\f58f"; } + +.fa-headset::before { + content: "\f590"; } + +.fa-heart::before { + content: "\f004"; } + +.fa-heart-circle-bolt::before { + content: "\e4fc"; } + +.fa-heart-circle-check::before { + content: "\e4fd"; } + +.fa-heart-circle-exclamation::before { + content: "\e4fe"; } + +.fa-heart-circle-minus::before { + content: "\e4ff"; } + +.fa-heart-circle-plus::before { + content: "\e500"; } + +.fa-heart-circle-xmark::before { + content: "\e501"; } + +.fa-heart-crack::before { + content: "\f7a9"; } + +.fa-heart-broken::before { + content: "\f7a9"; } + +.fa-heart-pulse::before { + content: "\f21e"; } + +.fa-heartbeat::before { + content: "\f21e"; } + +.fa-helicopter::before { + content: "\f533"; } + +.fa-helicopter-symbol::before { + content: "\e502"; } + +.fa-helmet-safety::before { + content: "\f807"; } + +.fa-hard-hat::before { + content: "\f807"; } + +.fa-hat-hard::before { + content: "\f807"; } + +.fa-helmet-un::before { + content: "\e503"; } + +.fa-highlighter::before { + content: "\f591"; } + +.fa-hill-avalanche::before { + content: "\e507"; } + +.fa-hill-rockslide::before { + content: "\e508"; } + +.fa-hippo::before { + content: "\f6ed"; } + +.fa-hockey-puck::before { + content: "\f453"; } + +.fa-holly-berry::before { + content: "\f7aa"; } + +.fa-horse::before { + content: "\f6f0"; } + +.fa-horse-head::before { + content: "\f7ab"; } + +.fa-hospital::before { + content: "\f0f8"; } + +.fa-hospital-alt::before { + content: "\f0f8"; } + +.fa-hospital-wide::before { + content: "\f0f8"; } + +.fa-hospital-user::before { + content: "\f80d"; } + +.fa-hot-tub-person::before { + content: "\f593"; } + +.fa-hot-tub::before { + content: "\f593"; } + +.fa-hotdog::before { + content: "\f80f"; } + +.fa-hotel::before { + content: "\f594"; } + +.fa-hourglass::before { + content: "\f254"; } + +.fa-hourglass-2::before { + content: "\f254"; } + +.fa-hourglass-half::before { + content: "\f254"; } + +.fa-hourglass-empty::before { + content: "\f252"; } + +.fa-hourglass-end::before { + content: "\f253"; } + +.fa-hourglass-3::before { + content: "\f253"; } + +.fa-hourglass-start::before { + content: "\f251"; } + +.fa-hourglass-1::before { + content: "\f251"; } + +.fa-house::before { + content: "\f015"; } + +.fa-home::before { + content: "\f015"; } + +.fa-home-alt::before { + content: "\f015"; } + +.fa-home-lg-alt::before { + content: "\f015"; } + +.fa-house-chimney::before { + content: "\e3af"; } + +.fa-home-lg::before { + content: "\e3af"; } + +.fa-house-chimney-crack::before { + content: "\f6f1"; } + +.fa-house-damage::before { + content: "\f6f1"; } + +.fa-house-chimney-medical::before { + content: "\f7f2"; } + +.fa-clinic-medical::before { + content: "\f7f2"; } + +.fa-house-chimney-user::before { + content: "\e065"; } + +.fa-house-chimney-window::before { + content: "\e00d"; } + +.fa-house-circle-check::before { + content: "\e509"; } + +.fa-house-circle-exclamation::before { + content: "\e50a"; } + +.fa-house-circle-xmark::before { + content: "\e50b"; } + +.fa-house-crack::before { + content: "\e3b1"; } + +.fa-house-fire::before { + content: "\e50c"; } + +.fa-house-flag::before { + content: "\e50d"; } + +.fa-house-flood-water::before { + content: "\e50e"; } + +.fa-house-flood-water-circle-arrow-right::before { + content: "\e50f"; } + +.fa-house-laptop::before { + content: "\e066"; } + +.fa-laptop-house::before { + content: "\e066"; } + +.fa-house-lock::before { + content: "\e510"; } + +.fa-house-medical::before { + content: "\e3b2"; } + +.fa-house-medical-circle-check::before { + content: "\e511"; } + +.fa-house-medical-circle-exclamation::before { + content: "\e512"; } + +.fa-house-medical-circle-xmark::before { + content: "\e513"; } + +.fa-house-medical-flag::before { + content: "\e514"; } + +.fa-house-signal::before { + content: "\e012"; } + +.fa-house-tsunami::before { + content: "\e515"; } + +.fa-house-user::before { + content: "\e1b0"; } + +.fa-home-user::before { + content: "\e1b0"; } + +.fa-hryvnia-sign::before { + content: "\f6f2"; } + +.fa-hryvnia::before { + content: "\f6f2"; } + +.fa-hurricane::before { + content: "\f751"; } + +.fa-i::before { + content: "\49"; } + +.fa-i-cursor::before { + content: "\f246"; } + +.fa-ice-cream::before { + content: "\f810"; } + +.fa-icicles::before { + content: "\f7ad"; } + +.fa-icons::before { + content: "\f86d"; } + +.fa-heart-music-camera-bolt::before { + content: "\f86d"; } + +.fa-id-badge::before { + content: "\f2c1"; } + +.fa-id-card::before { + content: "\f2c2"; } + +.fa-drivers-license::before { + content: "\f2c2"; } + +.fa-id-card-clip::before { + content: "\f47f"; } + +.fa-id-card-alt::before { + content: "\f47f"; } + +.fa-igloo::before { + content: "\f7ae"; } + +.fa-image::before { + content: "\f03e"; } + +.fa-image-portrait::before { + content: "\f3e0"; } + +.fa-portrait::before { + content: "\f3e0"; } + +.fa-images::before { + content: "\f302"; } + +.fa-inbox::before { + content: "\f01c"; } + +.fa-indent::before { + content: "\f03c"; } + +.fa-indian-rupee-sign::before { + content: "\e1bc"; } + +.fa-indian-rupee::before { + content: "\e1bc"; } + +.fa-inr::before { + content: "\e1bc"; } + +.fa-industry::before { + content: "\f275"; } + +.fa-infinity::before { + content: "\f534"; } + +.fa-info::before { + content: "\f129"; } + +.fa-italic::before { + content: "\f033"; } + +.fa-j::before { + content: "\4a"; } + +.fa-jar::before { + content: "\e516"; } + +.fa-jar-wheat::before { + content: "\e517"; } + +.fa-jedi::before { + content: "\f669"; } + +.fa-jet-fighter::before { + content: "\f0fb"; } + +.fa-fighter-jet::before { + content: "\f0fb"; } + +.fa-jet-fighter-up::before { + content: "\e518"; } + +.fa-joint::before { + content: "\f595"; } + +.fa-jug-detergent::before { + content: "\e519"; } + +.fa-k::before { + content: "\4b"; } + +.fa-kaaba::before { + content: "\f66b"; } + +.fa-key::before { + content: "\f084"; } + +.fa-keyboard::before { + content: "\f11c"; } + +.fa-khanda::before { + content: "\f66d"; } + +.fa-kip-sign::before { + content: "\e1c4"; } + +.fa-kit-medical::before { + content: "\f479"; } + +.fa-first-aid::before { + content: "\f479"; } + +.fa-kitchen-set::before { + content: "\e51a"; } + +.fa-kiwi-bird::before { + content: "\f535"; } + +.fa-l::before { + content: "\4c"; } + +.fa-land-mine-on::before { + content: "\e51b"; } + +.fa-landmark::before { + content: "\f66f"; } + +.fa-landmark-dome::before { + content: "\f752"; } + +.fa-landmark-alt::before { + content: "\f752"; } + +.fa-landmark-flag::before { + content: "\e51c"; } + +.fa-language::before { + content: "\f1ab"; } + +.fa-laptop::before { + content: "\f109"; } + +.fa-laptop-code::before { + content: "\f5fc"; } + +.fa-laptop-file::before { + content: "\e51d"; } + +.fa-laptop-medical::before { + content: "\f812"; } + +.fa-lari-sign::before { + content: "\e1c8"; } + +.fa-layer-group::before { + content: "\f5fd"; } + +.fa-leaf::before { + content: "\f06c"; } + +.fa-left-long::before { + content: "\f30a"; } + +.fa-long-arrow-alt-left::before { + content: "\f30a"; } + +.fa-left-right::before { + content: "\f337"; } + +.fa-arrows-alt-h::before { + content: "\f337"; } + +.fa-lemon::before { + content: "\f094"; } + +.fa-less-than::before { + content: "\3c"; } + +.fa-less-than-equal::before { + content: "\f537"; } + +.fa-life-ring::before { + content: "\f1cd"; } + +.fa-lightbulb::before { + content: "\f0eb"; } + +.fa-lines-leaning::before { + content: "\e51e"; } + +.fa-link::before { + content: "\f0c1"; } + +.fa-chain::before { + content: "\f0c1"; } + +.fa-link-slash::before { + content: "\f127"; } + +.fa-chain-broken::before { + content: "\f127"; } + +.fa-chain-slash::before { + content: "\f127"; } + +.fa-unlink::before { + content: "\f127"; } + +.fa-lira-sign::before { + content: "\f195"; } + +.fa-list::before { + content: "\f03a"; } + +.fa-list-squares::before { + content: "\f03a"; } + +.fa-list-check::before { + content: "\f0ae"; } + +.fa-tasks::before { + content: "\f0ae"; } + +.fa-list-ol::before { + content: "\f0cb"; } + +.fa-list-1-2::before { + content: "\f0cb"; } + +.fa-list-numeric::before { + content: "\f0cb"; } + +.fa-list-ul::before { + content: "\f0ca"; } + +.fa-list-dots::before { + content: "\f0ca"; } + +.fa-litecoin-sign::before { + content: "\e1d3"; } + +.fa-location-arrow::before { + content: "\f124"; } + +.fa-location-crosshairs::before { + content: "\f601"; } + +.fa-location::before { + content: "\f601"; } + +.fa-location-dot::before { + content: "\f3c5"; } + +.fa-map-marker-alt::before { + content: "\f3c5"; } + +.fa-location-pin::before { + content: "\f041"; } + +.fa-map-marker::before { + content: "\f041"; } + +.fa-location-pin-lock::before { + content: "\e51f"; } + +.fa-lock::before { + content: "\f023"; } + +.fa-lock-open::before { + content: "\f3c1"; } + +.fa-locust::before { + content: "\e520"; } + +.fa-lungs::before { + content: "\f604"; } + +.fa-lungs-virus::before { + content: "\e067"; } + +.fa-m::before { + content: "\4d"; } + +.fa-magnet::before { + content: "\f076"; } + +.fa-magnifying-glass::before { + content: "\f002"; } + +.fa-search::before { + content: "\f002"; } + +.fa-magnifying-glass-arrow-right::before { + content: "\e521"; } + +.fa-magnifying-glass-chart::before { + content: "\e522"; } + +.fa-magnifying-glass-dollar::before { + content: "\f688"; } + +.fa-search-dollar::before { + content: "\f688"; } + +.fa-magnifying-glass-location::before { + content: "\f689"; } + +.fa-search-location::before { + content: "\f689"; } + +.fa-magnifying-glass-minus::before { + content: "\f010"; } + +.fa-search-minus::before { + content: "\f010"; } + +.fa-magnifying-glass-plus::before { + content: "\f00e"; } + +.fa-search-plus::before { + content: "\f00e"; } + +.fa-manat-sign::before { + content: "\e1d5"; } + +.fa-map::before { + content: "\f279"; } + +.fa-map-location::before { + content: "\f59f"; } + +.fa-map-marked::before { + content: "\f59f"; } + +.fa-map-location-dot::before { + content: "\f5a0"; } + +.fa-map-marked-alt::before { + content: "\f5a0"; } + +.fa-map-pin::before { + content: "\f276"; } + +.fa-marker::before { + content: "\f5a1"; } + +.fa-mars::before { + content: "\f222"; } + +.fa-mars-and-venus::before { + content: "\f224"; } + +.fa-mars-and-venus-burst::before { + content: "\e523"; } + +.fa-mars-double::before { + content: "\f227"; } + +.fa-mars-stroke::before { + content: "\f229"; } + +.fa-mars-stroke-right::before { + content: "\f22b"; } + +.fa-mars-stroke-h::before { + content: "\f22b"; } + +.fa-mars-stroke-up::before { + content: "\f22a"; } + +.fa-mars-stroke-v::before { + content: "\f22a"; } + +.fa-martini-glass::before { + content: "\f57b"; } + +.fa-glass-martini-alt::before { + content: "\f57b"; } + +.fa-martini-glass-citrus::before { + content: "\f561"; } + +.fa-cocktail::before { + content: "\f561"; } + +.fa-martini-glass-empty::before { + content: "\f000"; } + +.fa-glass-martini::before { + content: "\f000"; } + +.fa-mask::before { + content: "\f6fa"; } + +.fa-mask-face::before { + content: "\e1d7"; } + +.fa-mask-ventilator::before { + content: "\e524"; } + +.fa-masks-theater::before { + content: "\f630"; } + +.fa-theater-masks::before { + content: "\f630"; } + +.fa-mattress-pillow::before { + content: "\e525"; } + +.fa-maximize::before { + content: "\f31e"; } + +.fa-expand-arrows-alt::before { + content: "\f31e"; } + +.fa-medal::before { + content: "\f5a2"; } + +.fa-memory::before { + content: "\f538"; } + +.fa-menorah::before { + content: "\f676"; } + +.fa-mercury::before { + content: "\f223"; } + +.fa-message::before { + content: "\f27a"; } + +.fa-comment-alt::before { + content: "\f27a"; } + +.fa-meteor::before { + content: "\f753"; } + +.fa-microchip::before { + content: "\f2db"; } + +.fa-microphone::before { + content: "\f130"; } + +.fa-microphone-lines::before { + content: "\f3c9"; } + +.fa-microphone-alt::before { + content: "\f3c9"; } + +.fa-microphone-lines-slash::before { + content: "\f539"; } + +.fa-microphone-alt-slash::before { + content: "\f539"; } + +.fa-microphone-slash::before { + content: "\f131"; } + +.fa-microscope::before { + content: "\f610"; } + +.fa-mill-sign::before { + content: "\e1ed"; } + +.fa-minimize::before { + content: "\f78c"; } + +.fa-compress-arrows-alt::before { + content: "\f78c"; } + +.fa-minus::before { + content: "\f068"; } + +.fa-subtract::before { + content: "\f068"; } + +.fa-mitten::before { + content: "\f7b5"; } + +.fa-mobile::before { + content: "\f3ce"; } + +.fa-mobile-android::before { + content: "\f3ce"; } + +.fa-mobile-phone::before { + content: "\f3ce"; } + +.fa-mobile-button::before { + content: "\f10b"; } + +.fa-mobile-retro::before { + content: "\e527"; } + +.fa-mobile-screen::before { + content: "\f3cf"; } + +.fa-mobile-android-alt::before { + content: "\f3cf"; } + +.fa-mobile-screen-button::before { + content: "\f3cd"; } + +.fa-mobile-alt::before { + content: "\f3cd"; } + +.fa-money-bill::before { + content: "\f0d6"; } + +.fa-money-bill-1::before { + content: "\f3d1"; } + +.fa-money-bill-alt::before { + content: "\f3d1"; } + +.fa-money-bill-1-wave::before { + content: "\f53b"; } + +.fa-money-bill-wave-alt::before { + content: "\f53b"; } + +.fa-money-bill-transfer::before { + content: "\e528"; } + +.fa-money-bill-trend-up::before { + content: "\e529"; } + +.fa-money-bill-wave::before { + content: "\f53a"; } + +.fa-money-bill-wheat::before { + content: "\e52a"; } + +.fa-money-bills::before { + content: "\e1f3"; } + +.fa-money-check::before { + content: "\f53c"; } + +.fa-money-check-dollar::before { + content: "\f53d"; } + +.fa-money-check-alt::before { + content: "\f53d"; } + +.fa-monument::before { + content: "\f5a6"; } + +.fa-moon::before { + content: "\f186"; } + +.fa-mortar-pestle::before { + content: "\f5a7"; } + +.fa-mosque::before { + content: "\f678"; } + +.fa-mosquito::before { + content: "\e52b"; } + +.fa-mosquito-net::before { + content: "\e52c"; } + +.fa-motorcycle::before { + content: "\f21c"; } + +.fa-mound::before { + content: "\e52d"; } + +.fa-mountain::before { + content: "\f6fc"; } + +.fa-mountain-city::before { + content: "\e52e"; } + +.fa-mountain-sun::before { + content: "\e52f"; } + +.fa-mug-hot::before { + content: "\f7b6"; } + +.fa-mug-saucer::before { + content: "\f0f4"; } + +.fa-coffee::before { + content: "\f0f4"; } + +.fa-music::before { + content: "\f001"; } + +.fa-n::before { + content: "\4e"; } + +.fa-naira-sign::before { + content: "\e1f6"; } + +.fa-network-wired::before { + content: "\f6ff"; } + +.fa-neuter::before { + content: "\f22c"; } + +.fa-newspaper::before { + content: "\f1ea"; } + +.fa-not-equal::before { + content: "\f53e"; } + +.fa-note-sticky::before { + content: "\f249"; } + +.fa-sticky-note::before { + content: "\f249"; } + +.fa-notes-medical::before { + content: "\f481"; } + +.fa-o::before { + content: "\4f"; } + +.fa-object-group::before { + content: "\f247"; } + +.fa-object-ungroup::before { + content: "\f248"; } + +.fa-oil-can::before { + content: "\f613"; } + +.fa-oil-well::before { + content: "\e532"; } + +.fa-om::before { + content: "\f679"; } + +.fa-otter::before { + content: "\f700"; } + +.fa-outdent::before { + content: "\f03b"; } + +.fa-dedent::before { + content: "\f03b"; } + +.fa-p::before { + content: "\50"; } + +.fa-pager::before { + content: "\f815"; } + +.fa-paint-roller::before { + content: "\f5aa"; } + +.fa-paintbrush::before { + content: "\f1fc"; } + +.fa-paint-brush::before { + content: "\f1fc"; } + +.fa-palette::before { + content: "\f53f"; } + +.fa-pallet::before { + content: "\f482"; } + +.fa-panorama::before { + content: "\e209"; } + +.fa-paper-plane::before { + content: "\f1d8"; } + +.fa-paperclip::before { + content: "\f0c6"; } + +.fa-parachute-box::before { + content: "\f4cd"; } + +.fa-paragraph::before { + content: "\f1dd"; } + +.fa-passport::before { + content: "\f5ab"; } + +.fa-paste::before { + content: "\f0ea"; } + +.fa-file-clipboard::before { + content: "\f0ea"; } + +.fa-pause::before { + content: "\f04c"; } + +.fa-paw::before { + content: "\f1b0"; } + +.fa-peace::before { + content: "\f67c"; } + +.fa-pen::before { + content: "\f304"; } + +.fa-pen-clip::before { + content: "\f305"; } + +.fa-pen-alt::before { + content: "\f305"; } + +.fa-pen-fancy::before { + content: "\f5ac"; } + +.fa-pen-nib::before { + content: "\f5ad"; } + +.fa-pen-ruler::before { + content: "\f5ae"; } + +.fa-pencil-ruler::before { + content: "\f5ae"; } + +.fa-pen-to-square::before { + content: "\f044"; } + +.fa-edit::before { + content: "\f044"; } + +.fa-pencil::before { + content: "\f303"; } + +.fa-pencil-alt::before { + content: "\f303"; } + +.fa-people-arrows-left-right::before { + content: "\e068"; } + +.fa-people-arrows::before { + content: "\e068"; } + +.fa-people-carry-box::before { + content: "\f4ce"; } + +.fa-people-carry::before { + content: "\f4ce"; } + +.fa-people-group::before { + content: "\e533"; } + +.fa-people-line::before { + content: "\e534"; } + +.fa-people-pulling::before { + content: "\e535"; } + +.fa-people-robbery::before { + content: "\e536"; } + +.fa-people-roof::before { + content: "\e537"; } + +.fa-pepper-hot::before { + content: "\f816"; } + +.fa-percent::before { + content: "\25"; } + +.fa-percentage::before { + content: "\25"; } + +.fa-person::before { + content: "\f183"; } + +.fa-male::before { + content: "\f183"; } + +.fa-person-arrow-down-to-line::before { + content: "\e538"; } + +.fa-person-arrow-up-from-line::before { + content: "\e539"; } + +.fa-person-biking::before { + content: "\f84a"; } + +.fa-biking::before { + content: "\f84a"; } + +.fa-person-booth::before { + content: "\f756"; } + +.fa-person-breastfeeding::before { + content: "\e53a"; } + +.fa-person-burst::before { + content: "\e53b"; } + +.fa-person-cane::before { + content: "\e53c"; } + +.fa-person-chalkboard::before { + content: "\e53d"; } + +.fa-person-circle-check::before { + content: "\e53e"; } + +.fa-person-circle-exclamation::before { + content: "\e53f"; } + +.fa-person-circle-minus::before { + content: "\e540"; } + +.fa-person-circle-plus::before { + content: "\e541"; } + +.fa-person-circle-question::before { + content: "\e542"; } + +.fa-person-circle-xmark::before { + content: "\e543"; } + +.fa-person-digging::before { + content: "\f85e"; } + +.fa-digging::before { + content: "\f85e"; } + +.fa-person-dots-from-line::before { + content: "\f470"; } + +.fa-diagnoses::before { + content: "\f470"; } + +.fa-person-dress::before { + content: "\f182"; } + +.fa-female::before { + content: "\f182"; } + +.fa-person-dress-burst::before { + content: "\e544"; } + +.fa-person-drowning::before { + content: "\e545"; } + +.fa-person-falling::before { + content: "\e546"; } + +.fa-person-falling-burst::before { + content: "\e547"; } + +.fa-person-half-dress::before { + content: "\e548"; } + +.fa-person-harassing::before { + content: "\e549"; } + +.fa-person-hiking::before { + content: "\f6ec"; } + +.fa-hiking::before { + content: "\f6ec"; } + +.fa-person-military-pointing::before { + content: "\e54a"; } + +.fa-person-military-rifle::before { + content: "\e54b"; } + +.fa-person-military-to-person::before { + content: "\e54c"; } + +.fa-person-praying::before { + content: "\f683"; } + +.fa-pray::before { + content: "\f683"; } + +.fa-person-pregnant::before { + content: "\e31e"; } + +.fa-person-rays::before { + content: "\e54d"; } + +.fa-person-rifle::before { + content: "\e54e"; } + +.fa-person-running::before { + content: "\f70c"; } + +.fa-running::before { + content: "\f70c"; } + +.fa-person-shelter::before { + content: "\e54f"; } + +.fa-person-skating::before { + content: "\f7c5"; } + +.fa-skating::before { + content: "\f7c5"; } + +.fa-person-skiing::before { + content: "\f7c9"; } + +.fa-skiing::before { + content: "\f7c9"; } + +.fa-person-skiing-nordic::before { + content: "\f7ca"; } + +.fa-skiing-nordic::before { + content: "\f7ca"; } + +.fa-person-snowboarding::before { + content: "\f7ce"; } + +.fa-snowboarding::before { + content: "\f7ce"; } + +.fa-person-swimming::before { + content: "\f5c4"; } + +.fa-swimmer::before { + content: "\f5c4"; } + +.fa-person-through-window::before { + content: "\e433"; } + +.fa-person-walking::before { + content: "\f554"; } + +.fa-walking::before { + content: "\f554"; } + +.fa-person-walking-arrow-loop-left::before { + content: "\e551"; } + +.fa-person-walking-arrow-right::before { + content: "\e552"; } + +.fa-person-walking-dashed-line-arrow-right::before { + content: "\e553"; } + +.fa-person-walking-luggage::before { + content: "\e554"; } + +.fa-person-walking-with-cane::before { + content: "\f29d"; } + +.fa-blind::before { + content: "\f29d"; } + +.fa-peseta-sign::before { + content: "\e221"; } + +.fa-peso-sign::before { + content: "\e222"; } + +.fa-phone::before { + content: "\f095"; } + +.fa-phone-flip::before { + content: "\f879"; } + +.fa-phone-alt::before { + content: "\f879"; } + +.fa-phone-slash::before { + content: "\f3dd"; } + +.fa-phone-volume::before { + content: "\f2a0"; } + +.fa-volume-control-phone::before { + content: "\f2a0"; } + +.fa-photo-film::before { + content: "\f87c"; } + +.fa-photo-video::before { + content: "\f87c"; } + +.fa-piggy-bank::before { + content: "\f4d3"; } + +.fa-pills::before { + content: "\f484"; } + +.fa-pizza-slice::before { + content: "\f818"; } + +.fa-place-of-worship::before { + content: "\f67f"; } + +.fa-plane::before { + content: "\f072"; } + +.fa-plane-arrival::before { + content: "\f5af"; } + +.fa-plane-circle-check::before { + content: "\e555"; } + +.fa-plane-circle-exclamation::before { + content: "\e556"; } + +.fa-plane-circle-xmark::before { + content: "\e557"; } + +.fa-plane-departure::before { + content: "\f5b0"; } + +.fa-plane-lock::before { + content: "\e558"; } + +.fa-plane-slash::before { + content: "\e069"; } + +.fa-plane-up::before { + content: "\e22d"; } + +.fa-plant-wilt::before { + content: "\e43b"; } + +.fa-plate-wheat::before { + content: "\e55a"; } + +.fa-play::before { + content: "\f04b"; } + +.fa-plug::before { + content: "\f1e6"; } + +.fa-plug-circle-bolt::before { + content: "\e55b"; } + +.fa-plug-circle-check::before { + content: "\e55c"; } + +.fa-plug-circle-exclamation::before { + content: "\e55d"; } + +.fa-plug-circle-minus::before { + content: "\e55e"; } + +.fa-plug-circle-plus::before { + content: "\e55f"; } + +.fa-plug-circle-xmark::before { + content: "\e560"; } + +.fa-plus::before { + content: "\2b"; } + +.fa-add::before { + content: "\2b"; } + +.fa-plus-minus::before { + content: "\e43c"; } + +.fa-podcast::before { + content: "\f2ce"; } + +.fa-poo::before { + content: "\f2fe"; } + +.fa-poo-storm::before { + content: "\f75a"; } + +.fa-poo-bolt::before { + content: "\f75a"; } + +.fa-poop::before { + content: "\f619"; } + +.fa-power-off::before { + content: "\f011"; } + +.fa-prescription::before { + content: "\f5b1"; } + +.fa-prescription-bottle::before { + content: "\f485"; } + +.fa-prescription-bottle-medical::before { + content: "\f486"; } + +.fa-prescription-bottle-alt::before { + content: "\f486"; } + +.fa-print::before { + content: "\f02f"; } + +.fa-pump-medical::before { + content: "\e06a"; } + +.fa-pump-soap::before { + content: "\e06b"; } + +.fa-puzzle-piece::before { + content: "\f12e"; } + +.fa-q::before { + content: "\51"; } + +.fa-qrcode::before { + content: "\f029"; } + +.fa-question::before { + content: "\3f"; } + +.fa-quote-left::before { + content: "\f10d"; } + +.fa-quote-left-alt::before { + content: "\f10d"; } + +.fa-quote-right::before { + content: "\f10e"; } + +.fa-quote-right-alt::before { + content: "\f10e"; } + +.fa-r::before { + content: "\52"; } + +.fa-radiation::before { + content: "\f7b9"; } + +.fa-radio::before { + content: "\f8d7"; } + +.fa-rainbow::before { + content: "\f75b"; } + +.fa-ranking-star::before { + content: "\e561"; } + +.fa-receipt::before { + content: "\f543"; } + +.fa-record-vinyl::before { + content: "\f8d9"; } + +.fa-rectangle-ad::before { + content: "\f641"; } + +.fa-ad::before { + content: "\f641"; } + +.fa-rectangle-list::before { + content: "\f022"; } + +.fa-list-alt::before { + content: "\f022"; } + +.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-recycle::before { + content: "\f1b8"; } + +.fa-registered::before { + content: "\f25d"; } + +.fa-repeat::before { + content: "\f363"; } + +.fa-reply::before { + content: "\f3e5"; } + +.fa-mail-reply::before { + content: "\f3e5"; } + +.fa-reply-all::before { + content: "\f122"; } + +.fa-mail-reply-all::before { + content: "\f122"; } + +.fa-republican::before { + content: "\f75e"; } + +.fa-restroom::before { + content: "\f7bd"; } + +.fa-retweet::before { + content: "\f079"; } + +.fa-ribbon::before { + content: "\f4d6"; } + +.fa-right-from-bracket::before { + content: "\f2f5"; } + +.fa-sign-out-alt::before { + content: "\f2f5"; } + +.fa-right-left::before { + content: "\f362"; } + +.fa-exchange-alt::before { + content: "\f362"; } + +.fa-right-long::before { + content: "\f30b"; } + +.fa-long-arrow-alt-right::before { + content: "\f30b"; } + +.fa-right-to-bracket::before { + content: "\f2f6"; } + +.fa-sign-in-alt::before { + content: "\f2f6"; } + +.fa-ring::before { + content: "\f70b"; } + +.fa-road::before { + content: "\f018"; } + +.fa-road-barrier::before { + content: "\e562"; } + +.fa-road-bridge::before { + content: "\e563"; } + +.fa-road-circle-check::before { + content: "\e564"; } + +.fa-road-circle-exclamation::before { + content: "\e565"; } + +.fa-road-circle-xmark::before { + content: "\e566"; } + +.fa-road-lock::before { + content: "\e567"; } + +.fa-road-spikes::before { + content: "\e568"; } + +.fa-robot::before { + content: "\f544"; } + +.fa-rocket::before { + content: "\f135"; } + +.fa-rotate::before { + content: "\f2f1"; } + +.fa-sync-alt::before { + content: "\f2f1"; } + +.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-rotate-right::before { + content: "\f2f9"; } + +.fa-redo-alt::before { + content: "\f2f9"; } + +.fa-rotate-forward::before { + content: "\f2f9"; } + +.fa-route::before { + content: "\f4d7"; } + +.fa-rss::before { + content: "\f09e"; } + +.fa-feed::before { + content: "\f09e"; } + +.fa-ruble-sign::before { + content: "\f158"; } + +.fa-rouble::before { + content: "\f158"; } + +.fa-rub::before { + content: "\f158"; } + +.fa-ruble::before { + content: "\f158"; } + +.fa-rug::before { + content: "\e569"; } + +.fa-ruler::before { + content: "\f545"; } + +.fa-ruler-combined::before { + content: "\f546"; } + +.fa-ruler-horizontal::before { + content: "\f547"; } + +.fa-ruler-vertical::before { + content: "\f548"; } + +.fa-rupee-sign::before { + content: "\f156"; } + +.fa-rupee::before { + content: "\f156"; } + +.fa-rupiah-sign::before { + content: "\e23d"; } + +.fa-s::before { + content: "\53"; } + +.fa-sack-dollar::before { + content: "\f81d"; } + +.fa-sack-xmark::before { + content: "\e56a"; } + +.fa-sailboat::before { + content: "\e445"; } + +.fa-satellite::before { + content: "\f7bf"; } + +.fa-satellite-dish::before { + content: "\f7c0"; } + +.fa-scale-balanced::before { + content: "\f24e"; } + +.fa-balance-scale::before { + content: "\f24e"; } + +.fa-scale-unbalanced::before { + content: "\f515"; } + +.fa-balance-scale-left::before { + content: "\f515"; } + +.fa-scale-unbalanced-flip::before { + content: "\f516"; } + +.fa-balance-scale-right::before { + content: "\f516"; } + +.fa-school::before { + content: "\f549"; } + +.fa-school-circle-check::before { + content: "\e56b"; } + +.fa-school-circle-exclamation::before { + content: "\e56c"; } + +.fa-school-circle-xmark::before { + content: "\e56d"; } + +.fa-school-flag::before { + content: "\e56e"; } + +.fa-school-lock::before { + content: "\e56f"; } + +.fa-scissors::before { + content: "\f0c4"; } + +.fa-cut::before { + content: "\f0c4"; } + +.fa-screwdriver::before { + content: "\f54a"; } + +.fa-screwdriver-wrench::before { + content: "\f7d9"; } + +.fa-tools::before { + content: "\f7d9"; } + +.fa-scroll::before { + content: "\f70e"; } + +.fa-scroll-torah::before { + content: "\f6a0"; } + +.fa-torah::before { + content: "\f6a0"; } + +.fa-sd-card::before { + content: "\f7c2"; } + +.fa-section::before { + content: "\e447"; } + +.fa-seedling::before { + content: "\f4d8"; } + +.fa-sprout::before { + content: "\f4d8"; } + +.fa-server::before { + content: "\f233"; } + +.fa-shapes::before { + content: "\f61f"; } + +.fa-triangle-circle-square::before { + content: "\f61f"; } + +.fa-share::before { + content: "\f064"; } + +.fa-arrow-turn-right::before { + content: "\f064"; } + +.fa-mail-forward::before { + content: "\f064"; } + +.fa-share-from-square::before { + content: "\f14d"; } + +.fa-share-square::before { + content: "\f14d"; } + +.fa-share-nodes::before { + content: "\f1e0"; } + +.fa-share-alt::before { + content: "\f1e0"; } + +.fa-sheet-plastic::before { + content: "\e571"; } + +.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-shield::before { + content: "\f132"; } + +.fa-shield-blank::before { + content: "\f132"; } + +.fa-shield-cat::before { + content: "\e572"; } + +.fa-shield-dog::before { + content: "\e573"; } + +.fa-shield-halved::before { + content: "\f3ed"; } + +.fa-shield-alt::before { + content: "\f3ed"; } + +.fa-shield-heart::before { + content: "\e574"; } + +.fa-shield-virus::before { + content: "\e06c"; } + +.fa-ship::before { + content: "\f21a"; } + +.fa-shirt::before { + content: "\f553"; } + +.fa-t-shirt::before { + content: "\f553"; } + +.fa-tshirt::before { + content: "\f553"; } + +.fa-shoe-prints::before { + content: "\f54b"; } + +.fa-shop::before { + content: "\f54f"; } + +.fa-store-alt::before { + content: "\f54f"; } + +.fa-shop-lock::before { + content: "\e4a5"; } + +.fa-shop-slash::before { + content: "\e070"; } + +.fa-store-alt-slash::before { + content: "\e070"; } + +.fa-shower::before { + content: "\f2cc"; } + +.fa-shrimp::before { + content: "\e448"; } + +.fa-shuffle::before { + content: "\f074"; } + +.fa-random::before { + content: "\f074"; } + +.fa-shuttle-space::before { + content: "\f197"; } + +.fa-space-shuttle::before { + content: "\f197"; } + +.fa-sign-hanging::before { + content: "\f4d9"; } + +.fa-sign::before { + content: "\f4d9"; } + +.fa-signal::before { + content: "\f012"; } + +.fa-signal-5::before { + content: "\f012"; } + +.fa-signal-perfect::before { + content: "\f012"; } + +.fa-signature::before { + content: "\f5b7"; } + +.fa-signs-post::before { + content: "\f277"; } + +.fa-map-signs::before { + content: "\f277"; } + +.fa-sim-card::before { + content: "\f7c4"; } + +.fa-sink::before { + content: "\e06d"; } + +.fa-sitemap::before { + content: "\f0e8"; } + +.fa-skull::before { + content: "\f54c"; } + +.fa-skull-crossbones::before { + content: "\f714"; } + +.fa-slash::before { + content: "\f715"; } + +.fa-sleigh::before { + content: "\f7cc"; } + +.fa-sliders::before { + content: "\f1de"; } + +.fa-sliders-h::before { + content: "\f1de"; } + +.fa-smog::before { + content: "\f75f"; } + +.fa-smoking::before { + content: "\f48d"; } + +.fa-snowflake::before { + content: "\f2dc"; } + +.fa-snowman::before { + content: "\f7d0"; } + +.fa-snowplow::before { + content: "\f7d2"; } + +.fa-soap::before { + content: "\e06e"; } + +.fa-socks::before { + content: "\f696"; } + +.fa-solar-panel::before { + content: "\f5ba"; } + +.fa-sort::before { + content: "\f0dc"; } + +.fa-unsorted::before { + content: "\f0dc"; } + +.fa-sort-down::before { + content: "\f0dd"; } + +.fa-sort-desc::before { + content: "\f0dd"; } + +.fa-sort-up::before { + content: "\f0de"; } + +.fa-sort-asc::before { + content: "\f0de"; } + +.fa-spa::before { + content: "\f5bb"; } + +.fa-spaghetti-monster-flying::before { + content: "\f67b"; } + +.fa-pastafarianism::before { + content: "\f67b"; } + +.fa-spell-check::before { + content: "\f891"; } + +.fa-spider::before { + content: "\f717"; } + +.fa-spinner::before { + content: "\f110"; } + +.fa-splotch::before { + content: "\f5bc"; } + +.fa-spoon::before { + content: "\f2e5"; } + +.fa-utensil-spoon::before { + content: "\f2e5"; } + +.fa-spray-can::before { + content: "\f5bd"; } + +.fa-spray-can-sparkles::before { + content: "\f5d0"; } + +.fa-air-freshener::before { + content: "\f5d0"; } + +.fa-square::before { + content: "\f0c8"; } + +.fa-square-arrow-up-right::before { + content: "\f14c"; } + +.fa-external-link-square::before { + content: "\f14c"; } + +.fa-square-caret-down::before { + content: "\f150"; } + +.fa-caret-square-down::before { + content: "\f150"; } + +.fa-square-caret-left::before { + content: "\f191"; } + +.fa-caret-square-left::before { + content: "\f191"; } + +.fa-square-caret-right::before { + content: "\f152"; } + +.fa-caret-square-right::before { + content: "\f152"; } + +.fa-square-caret-up::before { + content: "\f151"; } + +.fa-caret-square-up::before { + content: "\f151"; } + +.fa-square-check::before { + content: "\f14a"; } + +.fa-check-square::before { + content: "\f14a"; } + +.fa-square-envelope::before { + content: "\f199"; } + +.fa-envelope-square::before { + content: "\f199"; } + +.fa-square-full::before { + content: "\f45c"; } + +.fa-square-h::before { + content: "\f0fd"; } + +.fa-h-square::before { + content: "\f0fd"; } + +.fa-square-minus::before { + content: "\f146"; } + +.fa-minus-square::before { + content: "\f146"; } + +.fa-square-nfi::before { + content: "\e576"; } + +.fa-square-parking::before { + content: "\f540"; } + +.fa-parking::before { + content: "\f540"; } + +.fa-square-pen::before { + content: "\f14b"; } + +.fa-pen-square::before { + content: "\f14b"; } + +.fa-pencil-square::before { + content: "\f14b"; } + +.fa-square-person-confined::before { + content: "\e577"; } + +.fa-square-phone::before { + content: "\f098"; } + +.fa-phone-square::before { + content: "\f098"; } + +.fa-square-phone-flip::before { + content: "\f87b"; } + +.fa-phone-square-alt::before { + content: "\f87b"; } + +.fa-square-plus::before { + content: "\f0fe"; } + +.fa-plus-square::before { + content: "\f0fe"; } + +.fa-square-poll-horizontal::before { + content: "\f682"; } + +.fa-poll-h::before { + content: "\f682"; } + +.fa-square-poll-vertical::before { + content: "\f681"; } + +.fa-poll::before { + content: "\f681"; } + +.fa-square-root-variable::before { + content: "\f698"; } + +.fa-square-root-alt::before { + content: "\f698"; } + +.fa-square-rss::before { + content: "\f143"; } + +.fa-rss-square::before { + content: "\f143"; } + +.fa-square-share-nodes::before { + content: "\f1e1"; } + +.fa-share-alt-square::before { + content: "\f1e1"; } + +.fa-square-up-right::before { + content: "\f360"; } + +.fa-external-link-square-alt::before { + content: "\f360"; } + +.fa-square-virus::before { + content: "\e578"; } + +.fa-square-xmark::before { + content: "\f2d3"; } + +.fa-times-square::before { + content: "\f2d3"; } + +.fa-xmark-square::before { + content: "\f2d3"; } + +.fa-staff-aesculapius::before { + content: "\e579"; } + +.fa-rod-asclepius::before { + content: "\e579"; } + +.fa-rod-snake::before { + content: "\e579"; } + +.fa-staff-snake::before { + content: "\e579"; } + +.fa-stairs::before { + content: "\e289"; } + +.fa-stamp::before { + content: "\f5bf"; } + +.fa-star::before { + content: "\f005"; } + +.fa-star-and-crescent::before { + content: "\f699"; } + +.fa-star-half::before { + content: "\f089"; } + +.fa-star-half-stroke::before { + content: "\f5c0"; } + +.fa-star-half-alt::before { + content: "\f5c0"; } + +.fa-star-of-david::before { + content: "\f69a"; } + +.fa-star-of-life::before { + content: "\f621"; } + +.fa-sterling-sign::before { + content: "\f154"; } + +.fa-gbp::before { + content: "\f154"; } + +.fa-pound-sign::before { + content: "\f154"; } + +.fa-stethoscope::before { + content: "\f0f1"; } + +.fa-stop::before { + content: "\f04d"; } + +.fa-stopwatch::before { + content: "\f2f2"; } + +.fa-stopwatch-20::before { + content: "\e06f"; } + +.fa-store::before { + content: "\f54e"; } + +.fa-store-slash::before { + content: "\e071"; } + +.fa-street-view::before { + content: "\f21d"; } + +.fa-strikethrough::before { + content: "\f0cc"; } + +.fa-stroopwafel::before { + content: "\f551"; } + +.fa-subscript::before { + content: "\f12c"; } + +.fa-suitcase::before { + content: "\f0f2"; } + +.fa-suitcase-medical::before { + content: "\f0fa"; } + +.fa-medkit::before { + content: "\f0fa"; } + +.fa-suitcase-rolling::before { + content: "\f5c1"; } + +.fa-sun::before { + content: "\f185"; } + +.fa-sun-plant-wilt::before { + content: "\e57a"; } + +.fa-superscript::before { + content: "\f12b"; } + +.fa-swatchbook::before { + content: "\f5c3"; } + +.fa-synagogue::before { + content: "\f69b"; } + +.fa-syringe::before { + content: "\f48e"; } + +.fa-t::before { + content: "\54"; } + +.fa-table::before { + content: "\f0ce"; } + +.fa-table-cells::before { + content: "\f00a"; } + +.fa-th::before { + content: "\f00a"; } + +.fa-table-cells-large::before { + content: "\f009"; } + +.fa-th-large::before { + content: "\f009"; } + +.fa-table-columns::before { + content: "\f0db"; } + +.fa-columns::before { + content: "\f0db"; } + +.fa-table-list::before { + content: "\f00b"; } + +.fa-th-list::before { + content: "\f00b"; } + +.fa-table-tennis-paddle-ball::before { + content: "\f45d"; } + +.fa-ping-pong-paddle-ball::before { + content: "\f45d"; } + +.fa-table-tennis::before { + content: "\f45d"; } + +.fa-tablet::before { + content: "\f3fb"; } + +.fa-tablet-android::before { + content: "\f3fb"; } + +.fa-tablet-button::before { + content: "\f10a"; } + +.fa-tablet-screen-button::before { + content: "\f3fa"; } + +.fa-tablet-alt::before { + content: "\f3fa"; } + +.fa-tablets::before { + content: "\f490"; } + +.fa-tachograph-digital::before { + content: "\f566"; } + +.fa-digital-tachograph::before { + content: "\f566"; } + +.fa-tag::before { + content: "\f02b"; } + +.fa-tags::before { + content: "\f02c"; } + +.fa-tape::before { + content: "\f4db"; } + +.fa-tarp::before { + content: "\e57b"; } + +.fa-tarp-droplet::before { + content: "\e57c"; } + +.fa-taxi::before { + content: "\f1ba"; } + +.fa-cab::before { + content: "\f1ba"; } + +.fa-teeth::before { + content: "\f62e"; } + +.fa-teeth-open::before { + content: "\f62f"; } + +.fa-temperature-arrow-down::before { + content: "\e03f"; } + +.fa-temperature-down::before { + content: "\e03f"; } + +.fa-temperature-arrow-up::before { + content: "\e040"; } + +.fa-temperature-up::before { + content: "\e040"; } + +.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-temperature-full::before { + content: "\f2c7"; } + +.fa-temperature-4::before { + content: "\f2c7"; } + +.fa-thermometer-4::before { + content: "\f2c7"; } + +.fa-thermometer-full::before { + content: "\f2c7"; } + +.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-temperature-high::before { + content: "\f769"; } + +.fa-temperature-low::before { + content: "\f76b"; } + +.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-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-tenge-sign::before { + content: "\f7d7"; } + +.fa-tenge::before { + content: "\f7d7"; } + +.fa-tent::before { + content: "\e57d"; } + +.fa-tent-arrow-down-to-line::before { + content: "\e57e"; } + +.fa-tent-arrow-left-right::before { + content: "\e57f"; } + +.fa-tent-arrow-turn-left::before { + content: "\e580"; } + +.fa-tent-arrows-down::before { + content: "\e581"; } + +.fa-tents::before { + content: "\e582"; } + +.fa-terminal::before { + content: "\f120"; } + +.fa-text-height::before { + content: "\f034"; } + +.fa-text-slash::before { + content: "\f87d"; } + +.fa-remove-format::before { + content: "\f87d"; } + +.fa-text-width::before { + content: "\f035"; } + +.fa-thermometer::before { + content: "\f491"; } + +.fa-thumbs-down::before { + content: "\f165"; } + +.fa-thumbs-up::before { + content: "\f164"; } + +.fa-thumbtack::before { + content: "\f08d"; } + +.fa-thumb-tack::before { + content: "\f08d"; } + +.fa-ticket::before { + content: "\f145"; } + +.fa-ticket-simple::before { + content: "\f3ff"; } + +.fa-ticket-alt::before { + content: "\f3ff"; } + +.fa-timeline::before { + content: "\e29c"; } + +.fa-toggle-off::before { + content: "\f204"; } + +.fa-toggle-on::before { + content: "\f205"; } + +.fa-toilet::before { + content: "\f7d8"; } + +.fa-toilet-paper::before { + content: "\f71e"; } + +.fa-toilet-paper-slash::before { + content: "\e072"; } + +.fa-toilet-portable::before { + content: "\e583"; } + +.fa-toilets-portable::before { + content: "\e584"; } + +.fa-toolbox::before { + content: "\f552"; } + +.fa-tooth::before { + content: "\f5c9"; } + +.fa-torii-gate::before { + content: "\f6a1"; } + +.fa-tornado::before { + content: "\f76f"; } + +.fa-tower-broadcast::before { + content: "\f519"; } + +.fa-broadcast-tower::before { + content: "\f519"; } + +.fa-tower-cell::before { + content: "\e585"; } + +.fa-tower-observation::before { + content: "\e586"; } + +.fa-tractor::before { + content: "\f722"; } + +.fa-trademark::before { + content: "\f25c"; } + +.fa-traffic-light::before { + content: "\f637"; } + +.fa-trailer::before { + content: "\e041"; } + +.fa-train::before { + content: "\f238"; } + +.fa-train-subway::before { + content: "\f239"; } + +.fa-subway::before { + content: "\f239"; } + +.fa-train-tram::before { + content: "\f7da"; } + +.fa-tram::before { + content: "\f7da"; } + +.fa-transgender::before { + content: "\f225"; } + +.fa-transgender-alt::before { + content: "\f225"; } + +.fa-trash::before { + content: "\f1f8"; } + +.fa-trash-arrow-up::before { + content: "\f829"; } + +.fa-trash-restore::before { + content: "\f829"; } + +.fa-trash-can::before { + content: "\f2ed"; } + +.fa-trash-alt::before { + content: "\f2ed"; } + +.fa-trash-can-arrow-up::before { + content: "\f82a"; } + +.fa-trash-restore-alt::before { + content: "\f82a"; } + +.fa-tree::before { + content: "\f1bb"; } + +.fa-tree-city::before { + content: "\e587"; } + +.fa-triangle-exclamation::before { + content: "\f071"; } + +.fa-exclamation-triangle::before { + content: "\f071"; } + +.fa-warning::before { + content: "\f071"; } + +.fa-trophy::before { + content: "\f091"; } + +.fa-trowel::before { + content: "\e589"; } + +.fa-trowel-bricks::before { + content: "\e58a"; } + +.fa-truck::before { + content: "\f0d1"; } + +.fa-truck-arrow-right::before { + content: "\e58b"; } + +.fa-truck-droplet::before { + content: "\e58c"; } + +.fa-truck-fast::before { + content: "\f48b"; } + +.fa-shipping-fast::before { + content: "\f48b"; } + +.fa-truck-field::before { + content: "\e58d"; } + +.fa-truck-field-un::before { + content: "\e58e"; } + +.fa-truck-front::before { + content: "\e2b7"; } + +.fa-truck-medical::before { + content: "\f0f9"; } + +.fa-ambulance::before { + content: "\f0f9"; } + +.fa-truck-monster::before { + content: "\f63b"; } + +.fa-truck-moving::before { + content: "\f4df"; } + +.fa-truck-pickup::before { + content: "\f63c"; } + +.fa-truck-plane::before { + content: "\e58f"; } + +.fa-truck-ramp-box::before { + content: "\f4de"; } + +.fa-truck-loading::before { + content: "\f4de"; } + +.fa-tty::before { + content: "\f1e4"; } + +.fa-teletype::before { + content: "\f1e4"; } + +.fa-turkish-lira-sign::before { + content: "\e2bb"; } + +.fa-try::before { + content: "\e2bb"; } + +.fa-turkish-lira::before { + content: "\e2bb"; } + +.fa-turn-down::before { + content: "\f3be"; } + +.fa-level-down-alt::before { + content: "\f3be"; } + +.fa-turn-up::before { + content: "\f3bf"; } + +.fa-level-up-alt::before { + content: "\f3bf"; } + +.fa-tv::before { + content: "\f26c"; } + +.fa-television::before { + content: "\f26c"; } + +.fa-tv-alt::before { + content: "\f26c"; } + +.fa-u::before { + content: "\55"; } + +.fa-umbrella::before { + content: "\f0e9"; } + +.fa-umbrella-beach::before { + content: "\f5ca"; } + +.fa-underline::before { + content: "\f0cd"; } + +.fa-universal-access::before { + content: "\f29a"; } + +.fa-unlock::before { + content: "\f09c"; } + +.fa-unlock-keyhole::before { + content: "\f13e"; } + +.fa-unlock-alt::before { + content: "\f13e"; } + +.fa-up-down::before { + content: "\f338"; } + +.fa-arrows-alt-v::before { + content: "\f338"; } + +.fa-up-down-left-right::before { + content: "\f0b2"; } + +.fa-arrows-alt::before { + content: "\f0b2"; } + +.fa-up-long::before { + content: "\f30c"; } + +.fa-long-arrow-alt-up::before { + content: "\f30c"; } + +.fa-up-right-and-down-left-from-center::before { + content: "\f424"; } + +.fa-expand-alt::before { + content: "\f424"; } + +.fa-up-right-from-square::before { + content: "\f35d"; } + +.fa-external-link-alt::before { + content: "\f35d"; } + +.fa-upload::before { + content: "\f093"; } + +.fa-user::before { + content: "\f007"; } + +.fa-user-astronaut::before { + content: "\f4fb"; } + +.fa-user-check::before { + content: "\f4fc"; } + +.fa-user-clock::before { + content: "\f4fd"; } + +.fa-user-doctor::before { + content: "\f0f0"; } + +.fa-user-md::before { + content: "\f0f0"; } + +.fa-user-gear::before { + content: "\f4fe"; } + +.fa-user-cog::before { + content: "\f4fe"; } + +.fa-user-graduate::before { + content: "\f501"; } + +.fa-user-group::before { + content: "\f500"; } + +.fa-user-friends::before { + content: "\f500"; } + +.fa-user-injured::before { + content: "\f728"; } + +.fa-user-large::before { + content: "\f406"; } + +.fa-user-alt::before { + content: "\f406"; } + +.fa-user-large-slash::before { + content: "\f4fa"; } + +.fa-user-alt-slash::before { + content: "\f4fa"; } + +.fa-user-lock::before { + content: "\f502"; } + +.fa-user-minus::before { + content: "\f503"; } + +.fa-user-ninja::before { + content: "\f504"; } + +.fa-user-nurse::before { + content: "\f82f"; } + +.fa-user-pen::before { + content: "\f4ff"; } + +.fa-user-edit::before { + content: "\f4ff"; } + +.fa-user-plus::before { + content: "\f234"; } + +.fa-user-secret::before { + content: "\f21b"; } + +.fa-user-shield::before { + content: "\f505"; } + +.fa-user-slash::before { + content: "\f506"; } + +.fa-user-tag::before { + content: "\f507"; } + +.fa-user-tie::before { + content: "\f508"; } + +.fa-user-xmark::before { + content: "\f235"; } + +.fa-user-times::before { + content: "\f235"; } + +.fa-users::before { + content: "\f0c0"; } + +.fa-users-between-lines::before { + content: "\e591"; } + +.fa-users-gear::before { + content: "\f509"; } + +.fa-users-cog::before { + content: "\f509"; } + +.fa-users-line::before { + content: "\e592"; } + +.fa-users-rays::before { + content: "\e593"; } + +.fa-users-rectangle::before { + content: "\e594"; } + +.fa-users-slash::before { + content: "\e073"; } + +.fa-users-viewfinder::before { + content: "\e595"; } + +.fa-utensils::before { + content: "\f2e7"; } + +.fa-cutlery::before { + content: "\f2e7"; } + +.fa-v::before { + content: "\56"; } + +.fa-van-shuttle::before { + content: "\f5b6"; } + +.fa-shuttle-van::before { + content: "\f5b6"; } + +.fa-vault::before { + content: "\e2c5"; } + +.fa-vector-square::before { + content: "\f5cb"; } + +.fa-venus::before { + content: "\f221"; } + +.fa-venus-double::before { + content: "\f226"; } + +.fa-venus-mars::before { + content: "\f228"; } + +.fa-vest::before { + content: "\e085"; } + +.fa-vest-patches::before { + content: "\e086"; } + +.fa-vial::before { + content: "\f492"; } + +.fa-vial-circle-check::before { + content: "\e596"; } + +.fa-vial-virus::before { + content: "\e597"; } + +.fa-vials::before { + content: "\f493"; } + +.fa-video::before { + content: "\f03d"; } + +.fa-video-camera::before { + content: "\f03d"; } + +.fa-video-slash::before { + content: "\f4e2"; } + +.fa-vihara::before { + content: "\f6a7"; } + +.fa-virus::before { + content: "\e074"; } + +.fa-virus-covid::before { + content: "\e4a8"; } + +.fa-virus-covid-slash::before { + content: "\e4a9"; } + +.fa-virus-slash::before { + content: "\e075"; } + +.fa-viruses::before { + content: "\e076"; } + +.fa-voicemail::before { + content: "\f897"; } + +.fa-volcano::before { + content: "\f770"; } + +.fa-volleyball::before { + content: "\f45f"; } + +.fa-volleyball-ball::before { + content: "\f45f"; } + +.fa-volume-high::before { + content: "\f028"; } + +.fa-volume-up::before { + content: "\f028"; } + +.fa-volume-low::before { + content: "\f027"; } + +.fa-volume-down::before { + content: "\f027"; } + +.fa-volume-off::before { + content: "\f026"; } + +.fa-volume-xmark::before { + content: "\f6a9"; } + +.fa-volume-mute::before { + content: "\f6a9"; } + +.fa-volume-times::before { + content: "\f6a9"; } + +.fa-vr-cardboard::before { + content: "\f729"; } + +.fa-w::before { + content: "\57"; } + +.fa-walkie-talkie::before { + content: "\f8ef"; } + +.fa-wallet::before { + content: "\f555"; } + +.fa-wand-magic::before { + content: "\f0d0"; } + +.fa-magic::before { + content: "\f0d0"; } + +.fa-wand-magic-sparkles::before { + content: "\e2ca"; } + +.fa-magic-wand-sparkles::before { + content: "\e2ca"; } + +.fa-wand-sparkles::before { + content: "\f72b"; } + +.fa-warehouse::before { + content: "\f494"; } + +.fa-water::before { + content: "\f773"; } + +.fa-water-ladder::before { + content: "\f5c5"; } + +.fa-ladder-water::before { + content: "\f5c5"; } + +.fa-swimming-pool::before { + content: "\f5c5"; } + +.fa-wave-square::before { + content: "\f83e"; } + +.fa-weight-hanging::before { + content: "\f5cd"; } + +.fa-weight-scale::before { + content: "\f496"; } + +.fa-weight::before { + content: "\f496"; } + +.fa-wheat-awn::before { + content: "\e2cd"; } + +.fa-wheat-alt::before { + content: "\e2cd"; } + +.fa-wheat-awn-circle-exclamation::before { + content: "\e598"; } + +.fa-wheelchair::before { + content: "\f193"; } + +.fa-wheelchair-move::before { + content: "\e2ce"; } + +.fa-wheelchair-alt::before { + content: "\e2ce"; } + +.fa-whiskey-glass::before { + content: "\f7a0"; } + +.fa-glass-whiskey::before { + content: "\f7a0"; } + +.fa-wifi::before { + content: "\f1eb"; } + +.fa-wifi-3::before { + content: "\f1eb"; } + +.fa-wifi-strong::before { + content: "\f1eb"; } + +.fa-wind::before { + content: "\f72e"; } + +.fa-window-maximize::before { + content: "\f2d0"; } + +.fa-window-minimize::before { + content: "\f2d1"; } + +.fa-window-restore::before { + content: "\f2d2"; } + +.fa-wine-bottle::before { + content: "\f72f"; } + +.fa-wine-glass::before { + content: "\f4e3"; } + +.fa-wine-glass-empty::before { + content: "\f5ce"; } + +.fa-wine-glass-alt::before { + content: "\f5ce"; } + +.fa-won-sign::before { + content: "\f159"; } + +.fa-krw::before { + content: "\f159"; } + +.fa-won::before { + content: "\f159"; } + +.fa-worm::before { + content: "\e599"; } + +.fa-wrench::before { + content: "\f0ad"; } + +.fa-x::before { + content: "\58"; } + +.fa-x-ray::before { + content: "\f497"; } + +.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-xmarks-lines::before { + content: "\e59a"; } + +.fa-y::before { + content: "\59"; } + +.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-yin-yang::before { + content: "\f6ad"; } + +.fa-z::before { + content: "\5a"; } + +.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-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-family: 'Font Awesome 6 Brands'; + font-weight: 400; } + +.fa-42-group:before { + content: "\e080"; } + +.fa-innosoft:before { + content: "\e080"; } + +.fa-500px:before { + content: "\f26e"; } + +.fa-accessible-icon:before { + content: "\f368"; } + +.fa-accusoft:before { + content: "\f369"; } + +.fa-adn:before { + content: "\f170"; } + +.fa-adversal:before { + content: "\f36a"; } + +.fa-affiliatetheme:before { + content: "\f36b"; } + +.fa-airbnb:before { + content: "\f834"; } + +.fa-algolia:before { + content: "\f36c"; } + +.fa-alipay:before { + content: "\f642"; } + +.fa-amazon:before { + content: "\f270"; } + +.fa-amazon-pay:before { + content: "\f42c"; } + +.fa-amilia:before { + content: "\f36d"; } + +.fa-android:before { + content: "\f17b"; } + +.fa-angellist:before { + content: "\f209"; } + +.fa-angrycreative:before { + content: "\f36e"; } + +.fa-angular:before { + content: "\f420"; } + +.fa-app-store:before { + content: "\f36f"; } + +.fa-app-store-ios:before { + content: "\f370"; } + +.fa-apper:before { + content: "\f371"; } + +.fa-apple:before { + content: "\f179"; } + +.fa-apple-pay:before { + content: "\f415"; } + +.fa-artstation:before { + content: "\f77a"; } + +.fa-asymmetrik:before { + content: "\f372"; } + +.fa-atlassian:before { + content: "\f77b"; } + +.fa-audible:before { + content: "\f373"; } + +.fa-autoprefixer:before { + content: "\f41c"; } + +.fa-avianex:before { + content: "\f374"; } + +.fa-aviato:before { + content: "\f421"; } + +.fa-aws:before { + content: "\f375"; } + +.fa-bandcamp:before { + content: "\f2d5"; } + +.fa-battle-net:before { + content: "\f835"; } + +.fa-behance:before { + content: "\f1b4"; } + +.fa-behance-square:before { + content: "\f1b5"; } + +.fa-bilibili:before { + content: "\e3d9"; } + +.fa-bimobject:before { + content: "\f378"; } + +.fa-bitbucket:before { + content: "\f171"; } + +.fa-bitcoin:before { + content: "\f379"; } + +.fa-bity:before { + content: "\f37a"; } + +.fa-black-tie:before { + content: "\f27e"; } + +.fa-blackberry:before { + content: "\f37b"; } + +.fa-blogger:before { + content: "\f37c"; } + +.fa-blogger-b:before { + content: "\f37d"; } + +.fa-bluetooth:before { + content: "\f293"; } + +.fa-bluetooth-b:before { + content: "\f294"; } + +.fa-bootstrap:before { + content: "\f836"; } + +.fa-bots:before { + content: "\e340"; } + +.fa-btc:before { + content: "\f15a"; } + +.fa-buffer:before { + content: "\f837"; } + +.fa-buromobelexperte:before { + content: "\f37f"; } + +.fa-buy-n-large:before { + content: "\f8a6"; } + +.fa-buysellads:before { + content: "\f20d"; } + +.fa-canadian-maple-leaf:before { + content: "\f785"; } + +.fa-cc-amazon-pay:before { + content: "\f42d"; } + +.fa-cc-amex:before { + content: "\f1f3"; } + +.fa-cc-apple-pay:before { + content: "\f416"; } + +.fa-cc-diners-club:before { + content: "\f24c"; } + +.fa-cc-discover:before { + content: "\f1f2"; } + +.fa-cc-jcb:before { + content: "\f24b"; } + +.fa-cc-mastercard:before { + content: "\f1f1"; } + +.fa-cc-paypal:before { + content: "\f1f4"; } + +.fa-cc-stripe:before { + content: "\f1f5"; } + +.fa-cc-visa:before { + content: "\f1f0"; } + +.fa-centercode:before { + content: "\f380"; } + +.fa-centos:before { + content: "\f789"; } + +.fa-chrome:before { + content: "\f268"; } + +.fa-chromecast:before { + content: "\f838"; } + +.fa-cloudflare:before { + content: "\e07d"; } + +.fa-cloudscale:before { + content: "\f383"; } + +.fa-cloudsmith:before { + content: "\f384"; } + +.fa-cloudversify:before { + content: "\f385"; } + +.fa-cmplid:before { + content: "\e360"; } + +.fa-codepen:before { + content: "\f1cb"; } + +.fa-codiepie:before { + content: "\f284"; } + +.fa-confluence:before { + content: "\f78d"; } + +.fa-connectdevelop:before { + content: "\f20e"; } + +.fa-contao:before { + content: "\f26d"; } + +.fa-cotton-bureau:before { + content: "\f89e"; } + +.fa-cpanel:before { + content: "\f388"; } + +.fa-creative-commons:before { + content: "\f25e"; } + +.fa-creative-commons-by:before { + content: "\f4e7"; } + +.fa-creative-commons-nc:before { + content: "\f4e8"; } + +.fa-creative-commons-nc-eu:before { + content: "\f4e9"; } + +.fa-creative-commons-nc-jp:before { + content: "\f4ea"; } + +.fa-creative-commons-nd:before { + content: "\f4eb"; } + +.fa-creative-commons-pd:before { + content: "\f4ec"; } + +.fa-creative-commons-pd-alt:before { + content: "\f4ed"; } + +.fa-creative-commons-remix:before { + content: "\f4ee"; } + +.fa-creative-commons-sa:before { + content: "\f4ef"; } + +.fa-creative-commons-sampling:before { + content: "\f4f0"; } + +.fa-creative-commons-sampling-plus:before { + content: "\f4f1"; } + +.fa-creative-commons-share:before { + content: "\f4f2"; } + +.fa-creative-commons-zero:before { + content: "\f4f3"; } + +.fa-critical-role:before { + content: "\f6c9"; } + +.fa-css3:before { + content: "\f13c"; } + +.fa-css3-alt:before { + content: "\f38b"; } + +.fa-cuttlefish:before { + content: "\f38c"; } + +.fa-d-and-d:before { + content: "\f38d"; } + +.fa-d-and-d-beyond:before { + content: "\f6ca"; } + +.fa-dailymotion:before { + content: "\e052"; } + +.fa-dashcube:before { + content: "\f210"; } + +.fa-deezer:before { + content: "\e077"; } + +.fa-delicious:before { + content: "\f1a5"; } + +.fa-deploydog:before { + content: "\f38e"; } + +.fa-deskpro:before { + content: "\f38f"; } + +.fa-dev:before { + content: "\f6cc"; } + +.fa-deviantart:before { + content: "\f1bd"; } + +.fa-dhl:before { + content: "\f790"; } + +.fa-diaspora:before { + content: "\f791"; } + +.fa-digg:before { + content: "\f1a6"; } + +.fa-digital-ocean:before { + content: "\f391"; } + +.fa-discord:before { + content: "\f392"; } + +.fa-discourse:before { + content: "\f393"; } + +.fa-dochub:before { + content: "\f394"; } + +.fa-docker:before { + content: "\f395"; } + +.fa-draft2digital:before { + content: "\f396"; } + +.fa-dribbble:before { + content: "\f17d"; } + +.fa-dribbble-square:before { + content: "\f397"; } + +.fa-dropbox:before { + content: "\f16b"; } + +.fa-drupal:before { + content: "\f1a9"; } + +.fa-dyalog:before { + content: "\f399"; } + +.fa-earlybirds:before { + content: "\f39a"; } + +.fa-ebay:before { + content: "\f4f4"; } + +.fa-edge:before { + content: "\f282"; } + +.fa-edge-legacy:before { + content: "\e078"; } + +.fa-elementor:before { + content: "\f430"; } + +.fa-ello:before { + content: "\f5f1"; } + +.fa-ember:before { + content: "\f423"; } + +.fa-empire:before { + content: "\f1d1"; } + +.fa-envira:before { + content: "\f299"; } + +.fa-erlang:before { + content: "\f39d"; } + +.fa-ethereum:before { + content: "\f42e"; } + +.fa-etsy:before { + content: "\f2d7"; } + +.fa-evernote:before { + content: "\f839"; } + +.fa-expeditedssl:before { + content: "\f23e"; } + +.fa-facebook:before { + content: "\f09a"; } + +.fa-facebook-f:before { + content: "\f39e"; } + +.fa-facebook-messenger:before { + content: "\f39f"; } + +.fa-facebook-square:before { + content: "\f082"; } + +.fa-fantasy-flight-games:before { + content: "\f6dc"; } + +.fa-fedex:before { + content: "\f797"; } + +.fa-fedora:before { + content: "\f798"; } + +.fa-figma:before { + content: "\f799"; } + +.fa-firefox:before { + content: "\f269"; } + +.fa-firefox-browser:before { + content: "\e007"; } + +.fa-first-order:before { + content: "\f2b0"; } + +.fa-first-order-alt:before { + content: "\f50a"; } + +.fa-firstdraft:before { + content: "\f3a1"; } + +.fa-flickr:before { + content: "\f16e"; } + +.fa-flipboard:before { + content: "\f44d"; } + +.fa-fly:before { + content: "\f417"; } + +.fa-font-awesome:before { + content: "\f2b4"; } + +.fa-font-awesome-flag:before { + content: "\f2b4"; } + +.fa-font-awesome-logo-full:before { + content: "\f2b4"; } + +.fa-fonticons:before { + content: "\f280"; } + +.fa-fonticons-fi:before { + content: "\f3a2"; } + +.fa-fort-awesome:before { + content: "\f286"; } + +.fa-fort-awesome-alt:before { + content: "\f3a3"; } + +.fa-forumbee:before { + content: "\f211"; } + +.fa-foursquare:before { + content: "\f180"; } + +.fa-free-code-camp:before { + content: "\f2c5"; } + +.fa-freebsd:before { + content: "\f3a4"; } + +.fa-fulcrum:before { + content: "\f50b"; } + +.fa-galactic-republic:before { + content: "\f50c"; } + +.fa-galactic-senate:before { + content: "\f50d"; } + +.fa-get-pocket:before { + content: "\f265"; } + +.fa-gg:before { + content: "\f260"; } + +.fa-gg-circle:before { + content: "\f261"; } + +.fa-git:before { + content: "\f1d3"; } + +.fa-git-alt:before { + content: "\f841"; } + +.fa-git-square:before { + content: "\f1d2"; } + +.fa-github:before { + content: "\f09b"; } + +.fa-github-alt:before { + content: "\f113"; } + +.fa-github-square:before { + content: "\f092"; } + +.fa-gitkraken:before { + content: "\f3a6"; } + +.fa-gitlab:before { + content: "\f296"; } + +.fa-gitter:before { + content: "\f426"; } + +.fa-glide:before { + content: "\f2a5"; } + +.fa-glide-g:before { + content: "\f2a6"; } + +.fa-gofore:before { + content: "\f3a7"; } + +.fa-golang:before { + content: "\e40f"; } + +.fa-goodreads:before { + content: "\f3a8"; } + +.fa-goodreads-g:before { + content: "\f3a9"; } + +.fa-google:before { + content: "\f1a0"; } + +.fa-google-drive:before { + content: "\f3aa"; } + +.fa-google-pay:before { + content: "\e079"; } + +.fa-google-play:before { + content: "\f3ab"; } + +.fa-google-plus:before { + content: "\f2b3"; } + +.fa-google-plus-g:before { + content: "\f0d5"; } + +.fa-google-plus-square:before { + content: "\f0d4"; } + +.fa-google-wallet:before { + content: "\f1ee"; } + +.fa-gratipay:before { + content: "\f184"; } + +.fa-grav:before { + content: "\f2d6"; } + +.fa-gripfire:before { + content: "\f3ac"; } + +.fa-grunt:before { + content: "\f3ad"; } + +.fa-guilded:before { + content: "\e07e"; } + +.fa-gulp:before { + content: "\f3ae"; } + +.fa-hacker-news:before { + content: "\f1d4"; } + +.fa-hacker-news-square:before { + content: "\f3af"; } + +.fa-hackerrank:before { + content: "\f5f7"; } + +.fa-hashnode:before { + content: "\e499"; } + +.fa-hips:before { + content: "\f452"; } + +.fa-hire-a-helper:before { + content: "\f3b0"; } + +.fa-hive:before { + content: "\e07f"; } + +.fa-hooli:before { + content: "\f427"; } + +.fa-hornbill:before { + content: "\f592"; } + +.fa-hotjar:before { + content: "\f3b1"; } + +.fa-houzz:before { + content: "\f27c"; } + +.fa-html5:before { + content: "\f13b"; } + +.fa-hubspot:before { + content: "\f3b2"; } + +.fa-ideal:before { + content: "\e013"; } + +.fa-imdb:before { + content: "\f2d8"; } + +.fa-instagram:before { + content: "\f16d"; } + +.fa-instagram-square:before { + content: "\e055"; } + +.fa-instalod:before { + content: "\e081"; } + +.fa-intercom:before { + content: "\f7af"; } + +.fa-internet-explorer:before { + content: "\f26b"; } + +.fa-invision:before { + content: "\f7b0"; } + +.fa-ioxhost:before { + content: "\f208"; } + +.fa-itch-io:before { + content: "\f83a"; } + +.fa-itunes:before { + content: "\f3b4"; } + +.fa-itunes-note:before { + content: "\f3b5"; } + +.fa-java:before { + content: "\f4e4"; } + +.fa-jedi-order:before { + content: "\f50e"; } + +.fa-jenkins:before { + content: "\f3b6"; } + +.fa-jira:before { + content: "\f7b1"; } + +.fa-joget:before { + content: "\f3b7"; } + +.fa-joomla:before { + content: "\f1aa"; } + +.fa-js:before { + content: "\f3b8"; } + +.fa-js-square:before { + content: "\f3b9"; } + +.fa-jsfiddle:before { + content: "\f1cc"; } + +.fa-kaggle:before { + content: "\f5fa"; } + +.fa-keybase:before { + content: "\f4f5"; } + +.fa-keycdn:before { + content: "\f3ba"; } + +.fa-kickstarter:before { + content: "\f3bb"; } + +.fa-kickstarter-k:before { + content: "\f3bc"; } + +.fa-korvue:before { + content: "\f42f"; } + +.fa-laravel:before { + content: "\f3bd"; } + +.fa-lastfm:before { + content: "\f202"; } + +.fa-lastfm-square:before { + content: "\f203"; } + +.fa-leanpub:before { + content: "\f212"; } + +.fa-less:before { + content: "\f41d"; } + +.fa-line:before { + content: "\f3c0"; } + +.fa-linkedin:before { + content: "\f08c"; } + +.fa-linkedin-in:before { + content: "\f0e1"; } + +.fa-linode:before { + content: "\f2b8"; } + +.fa-linux:before { + content: "\f17c"; } + +.fa-lyft:before { + content: "\f3c3"; } + +.fa-magento:before { + content: "\f3c4"; } + +.fa-mailchimp:before { + content: "\f59e"; } + +.fa-mandalorian:before { + content: "\f50f"; } + +.fa-markdown:before { + content: "\f60f"; } + +.fa-mastodon:before { + content: "\f4f6"; } + +.fa-maxcdn:before { + content: "\f136"; } + +.fa-mdb:before { + content: "\f8ca"; } + +.fa-medapps:before { + content: "\f3c6"; } + +.fa-medium:before { + content: "\f23a"; } + +.fa-medium-m:before { + content: "\f23a"; } + +.fa-medrt:before { + content: "\f3c8"; } + +.fa-meetup:before { + content: "\f2e0"; } + +.fa-megaport:before { + content: "\f5a3"; } + +.fa-mendeley:before { + content: "\f7b3"; } + +.fa-microblog:before { + content: "\e01a"; } + +.fa-microsoft:before { + content: "\f3ca"; } + +.fa-mix:before { + content: "\f3cb"; } + +.fa-mixcloud:before { + content: "\f289"; } + +.fa-mixer:before { + content: "\e056"; } + +.fa-mizuni:before { + content: "\f3cc"; } + +.fa-modx:before { + content: "\f285"; } + +.fa-monero:before { + content: "\f3d0"; } + +.fa-napster:before { + content: "\f3d2"; } + +.fa-neos:before { + content: "\f612"; } + +.fa-nfc-directional:before { + content: "\e530"; } + +.fa-nfc-symbol:before { + content: "\e531"; } + +.fa-nimblr:before { + content: "\f5a8"; } + +.fa-node:before { + content: "\f419"; } + +.fa-node-js:before { + content: "\f3d3"; } + +.fa-npm:before { + content: "\f3d4"; } + +.fa-ns8:before { + content: "\f3d5"; } + +.fa-nutritionix:before { + content: "\f3d6"; } + +.fa-octopus-deploy:before { + content: "\e082"; } + +.fa-odnoklassniki:before { + content: "\f263"; } + +.fa-odnoklassniki-square:before { + content: "\f264"; } + +.fa-old-republic:before { + content: "\f510"; } + +.fa-opencart:before { + content: "\f23d"; } + +.fa-openid:before { + content: "\f19b"; } + +.fa-opera:before { + content: "\f26a"; } + +.fa-optin-monster:before { + content: "\f23c"; } + +.fa-orcid:before { + content: "\f8d2"; } + +.fa-osi:before { + content: "\f41a"; } + +.fa-padlet:before { + content: "\e4a0"; } + +.fa-page4:before { + content: "\f3d7"; } + +.fa-pagelines:before { + content: "\f18c"; } + +.fa-palfed:before { + content: "\f3d8"; } + +.fa-patreon:before { + content: "\f3d9"; } + +.fa-paypal:before { + content: "\f1ed"; } + +.fa-perbyte:before { + content: "\e083"; } + +.fa-periscope:before { + content: "\f3da"; } + +.fa-phabricator:before { + content: "\f3db"; } + +.fa-phoenix-framework:before { + content: "\f3dc"; } + +.fa-phoenix-squadron:before { + content: "\f511"; } + +.fa-php:before { + content: "\f457"; } + +.fa-pied-piper:before { + content: "\f2ae"; } + +.fa-pied-piper-alt:before { + content: "\f1a8"; } + +.fa-pied-piper-hat:before { + content: "\f4e5"; } + +.fa-pied-piper-pp:before { + content: "\f1a7"; } + +.fa-pied-piper-square:before { + content: "\e01e"; } + +.fa-pinterest:before { + content: "\f0d2"; } + +.fa-pinterest-p:before { + content: "\f231"; } + +.fa-pinterest-square:before { + content: "\f0d3"; } + +.fa-pix:before { + content: "\e43a"; } + +.fa-playstation:before { + content: "\f3df"; } + +.fa-product-hunt:before { + content: "\f288"; } + +.fa-pushed:before { + content: "\f3e1"; } + +.fa-python:before { + content: "\f3e2"; } + +.fa-qq:before { + content: "\f1d6"; } + +.fa-quinscape:before { + content: "\f459"; } + +.fa-quora:before { + content: "\f2c4"; } + +.fa-r-project:before { + content: "\f4f7"; } + +.fa-raspberry-pi:before { + content: "\f7bb"; } + +.fa-ravelry:before { + content: "\f2d9"; } + +.fa-react:before { + content: "\f41b"; } + +.fa-reacteurope:before { + content: "\f75d"; } + +.fa-readme:before { + content: "\f4d5"; } + +.fa-rebel:before { + content: "\f1d0"; } + +.fa-red-river:before { + content: "\f3e3"; } + +.fa-reddit:before { + content: "\f1a1"; } + +.fa-reddit-alien:before { + content: "\f281"; } + +.fa-reddit-square:before { + content: "\f1a2"; } + +.fa-redhat:before { + content: "\f7bc"; } + +.fa-renren:before { + content: "\f18b"; } + +.fa-replyd:before { + content: "\f3e6"; } + +.fa-researchgate:before { + content: "\f4f8"; } + +.fa-resolving:before { + content: "\f3e7"; } + +.fa-rev:before { + content: "\f5b2"; } + +.fa-rocketchat:before { + content: "\f3e8"; } + +.fa-rockrms:before { + content: "\f3e9"; } + +.fa-rust:before { + content: "\e07a"; } + +.fa-safari:before { + content: "\f267"; } + +.fa-salesforce:before { + content: "\f83b"; } + +.fa-sass:before { + content: "\f41e"; } + +.fa-schlix:before { + content: "\f3ea"; } + +.fa-screenpal:before { + content: "\e570"; } + +.fa-scribd:before { + content: "\f28a"; } + +.fa-searchengin:before { + content: "\f3eb"; } + +.fa-sellcast:before { + content: "\f2da"; } + +.fa-sellsy:before { + content: "\f213"; } + +.fa-servicestack:before { + content: "\f3ec"; } + +.fa-shirtsinbulk:before { + content: "\f214"; } + +.fa-shopify:before { + content: "\e057"; } + +.fa-shopware:before { + content: "\f5b5"; } + +.fa-simplybuilt:before { + content: "\f215"; } + +.fa-sistrix:before { + content: "\f3ee"; } + +.fa-sith:before { + content: "\f512"; } + +.fa-sitrox:before { + content: "\e44a"; } + +.fa-sketch:before { + content: "\f7c6"; } + +.fa-skyatlas:before { + content: "\f216"; } + +.fa-skype:before { + content: "\f17e"; } + +.fa-slack:before { + content: "\f198"; } + +.fa-slack-hash:before { + content: "\f198"; } + +.fa-slideshare:before { + content: "\f1e7"; } + +.fa-snapchat:before { + content: "\f2ab"; } + +.fa-snapchat-ghost:before { + content: "\f2ab"; } + +.fa-snapchat-square:before { + content: "\f2ad"; } + +.fa-soundcloud:before { + content: "\f1be"; } + +.fa-sourcetree:before { + content: "\f7d3"; } + +.fa-speakap:before { + content: "\f3f3"; } + +.fa-speaker-deck:before { + content: "\f83c"; } + +.fa-spotify:before { + content: "\f1bc"; } + +.fa-square-font-awesome:before { + content: "\f425"; } + +.fa-square-font-awesome-stroke:before { + content: "\f35c"; } + +.fa-font-awesome-alt:before { + content: "\f35c"; } + +.fa-squarespace:before { + content: "\f5be"; } + +.fa-stack-exchange:before { + content: "\f18d"; } + +.fa-stack-overflow:before { + content: "\f16c"; } + +.fa-stackpath:before { + content: "\f842"; } + +.fa-staylinked:before { + content: "\f3f5"; } + +.fa-steam:before { + content: "\f1b6"; } + +.fa-steam-square:before { + content: "\f1b7"; } + +.fa-steam-symbol:before { + content: "\f3f6"; } + +.fa-sticker-mule:before { + content: "\f3f7"; } + +.fa-strava:before { + content: "\f428"; } + +.fa-stripe:before { + content: "\f429"; } + +.fa-stripe-s:before { + content: "\f42a"; } + +.fa-studiovinari:before { + content: "\f3f8"; } + +.fa-stumbleupon:before { + content: "\f1a4"; } + +.fa-stumbleupon-circle:before { + content: "\f1a3"; } + +.fa-superpowers:before { + content: "\f2dd"; } + +.fa-supple:before { + content: "\f3f9"; } + +.fa-suse:before { + content: "\f7d6"; } + +.fa-swift:before { + content: "\f8e1"; } + +.fa-symfony:before { + content: "\f83d"; } + +.fa-teamspeak:before { + content: "\f4f9"; } + +.fa-telegram:before { + content: "\f2c6"; } + +.fa-telegram-plane:before { + content: "\f2c6"; } + +.fa-tencent-weibo:before { + content: "\f1d5"; } + +.fa-the-red-yeti:before { + content: "\f69d"; } + +.fa-themeco:before { + content: "\f5c6"; } + +.fa-themeisle:before { + content: "\f2b2"; } + +.fa-think-peaks:before { + content: "\f731"; } + +.fa-tiktok:before { + content: "\e07b"; } + +.fa-trade-federation:before { + content: "\f513"; } + +.fa-trello:before { + content: "\f181"; } + +.fa-tumblr:before { + content: "\f173"; } + +.fa-tumblr-square:before { + content: "\f174"; } + +.fa-twitch:before { + content: "\f1e8"; } + +.fa-twitter:before { + content: "\f099"; } + +.fa-twitter-square:before { + content: "\f081"; } + +.fa-typo3:before { + content: "\f42b"; } + +.fa-uber:before { + content: "\f402"; } + +.fa-ubuntu:before { + content: "\f7df"; } + +.fa-uikit:before { + content: "\f403"; } + +.fa-umbraco:before { + content: "\f8e8"; } + +.fa-uncharted:before { + content: "\e084"; } + +.fa-uniregistry:before { + content: "\f404"; } + +.fa-unity:before { + content: "\e049"; } + +.fa-unsplash:before { + content: "\e07c"; } + +.fa-untappd:before { + content: "\f405"; } + +.fa-ups:before { + content: "\f7e0"; } + +.fa-usb:before { + content: "\f287"; } + +.fa-usps:before { + content: "\f7e1"; } + +.fa-ussunnah:before { + content: "\f407"; } + +.fa-vaadin:before { + content: "\f408"; } + +.fa-viacoin:before { + content: "\f237"; } + +.fa-viadeo:before { + content: "\f2a9"; } + +.fa-viadeo-square:before { + content: "\f2aa"; } + +.fa-viber:before { + content: "\f409"; } + +.fa-vimeo:before { + content: "\f40a"; } + +.fa-vimeo-square:before { + content: "\f194"; } + +.fa-vimeo-v:before { + content: "\f27d"; } + +.fa-vine:before { + content: "\f1ca"; } + +.fa-vk:before { + content: "\f189"; } + +.fa-vnv:before { + content: "\f40b"; } + +.fa-vuejs:before { + content: "\f41f"; } + +.fa-watchman-monitoring:before { + content: "\e087"; } + +.fa-waze:before { + content: "\f83f"; } + +.fa-weebly:before { + content: "\f5cc"; } + +.fa-weibo:before { + content: "\f18a"; } + +.fa-weixin:before { + content: "\f1d7"; } + +.fa-whatsapp:before { + content: "\f232"; } + +.fa-whatsapp-square:before { + content: "\f40c"; } + +.fa-whmcs:before { + content: "\f40d"; } + +.fa-wikipedia-w:before { + content: "\f266"; } + +.fa-windows:before { + content: "\f17a"; } + +.fa-wirsindhandwerk:before { + content: "\e2d0"; } + +.fa-wsh:before { + content: "\e2d0"; } + +.fa-wix:before { + content: "\f5cf"; } + +.fa-wizards-of-the-coast:before { + content: "\f730"; } + +.fa-wodu:before { + content: "\e088"; } + +.fa-wolf-pack-battalion:before { + content: "\f514"; } + +.fa-wordpress:before { + content: "\f19a"; } + +.fa-wordpress-simple:before { + content: "\f411"; } + +.fa-wpbeginner:before { + content: "\f297"; } + +.fa-wpexplorer:before { + content: "\f2de"; } + +.fa-wpforms:before { + content: "\f298"; } + +.fa-wpressr:before { + content: "\f3e4"; } + +.fa-xbox:before { + content: "\f412"; } + +.fa-xing:before { + content: "\f168"; } + +.fa-xing-square:before { + content: "\f169"; } + +.fa-y-combinator:before { + content: "\f23b"; } + +.fa-yahoo:before { + content: "\f19e"; } + +.fa-yammer:before { + content: "\f840"; } + +.fa-yandex:before { + content: "\f413"; } + +.fa-yandex-international:before { + content: "\f414"; } + +.fa-yarn:before { + content: "\f7e3"; } + +.fa-yelp:before { + content: "\f1e9"; } + +.fa-yoast:before { + content: "\f2b1"; } + +.fa-youtube:before { + content: "\f167"; } + +.fa-youtube-square:before { + content: "\f431"; } + +.fa-zhihu:before { + content: "\f63f"; } +:root, :host { + --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-family: 'Font Awesome 6 Free'; + font-weight: 400; } +:root, :host { + --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-family: 'Font Awesome 6 Free'; + 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"); + unicode-range: U+F003,U+F006,U+F014,U+F016-F017,U+F01A-F01B,U+F01D,U+F022,U+F03E,U+F044,U+F046,U+F05C-F05D,U+F06E,U+F070,U+F087-F088,U+F08A,U+F094,U+F096-F097,U+F09D,U+F0A0,U+F0A2,U+F0A4-F0A7,U+F0C5,U+F0C7,U+F0E5-F0E6,U+F0EB,U+F0F6-F0F8,U+F10C,U+F114-F115,U+F118-F11A,U+F11C-F11D,U+F133,U+F147,U+F14E,U+F150-F152,U+F185-F186,U+F18E,U+F190-F192,U+F196,U+F1C1-F1C9,U+F1D9,U+F1DB,U+F1E3,U+F1EA,U+F1F7,U+F1F9,U+F20A,U+F247-F248,U+F24A,U+F24D,U+F255-F25B,U+F25D,U+F271-F274,U+F278,U+F27B,U+F28C,U+F28E,U+F29C,U+F2B5,U+F2B7,U+F2BA,U+F2BC,U+F2BE,U+F2C0-F2C1,U+F2C3,U+F2D0,U+F2D2,U+F2D4,U+F2DC; } + +@font-face { + font-family: "FontAwesome"; + font-display: block; + src: url("../webfonts/fa-v4compatibility.woff2") format("woff2"), url("../webfonts/fa-v4compatibility.ttf") format("truetype"); + unicode-range: U+F041,U+F047,U+F065-F066,U+F07D-F07E,U+F080,U+F08B,U+F08E,U+F090,U+F09A,U+F0AC,U+F0AE,U+F0B2,U+F0D0,U+F0D6,U+F0E4,U+F0EC,U+F10A-F10B,U+F123,U+F13E,U+F148-F149,U+F14C,U+F156,U+F15E,U+F160-F161,U+F163,U+F175-F178,U+F195,U+F1F8,U+F219,U+F250,U+F252,U+F27A; } diff --git a/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/css/latex-fontsize.css b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/css/latex-fontsize.css new file mode 100644 index 0000000..45545ec --- /dev/null +++ b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/css/latex-fontsize.css @@ -0,0 +1,30 @@ +.fa-tiny { + font-size: 0.5em; +} +.fa-scriptsize { + font-size: 0.7em; +} +.fa-footnotesize { + font-size: 0.8em; +} +.fa-small { + font-size: 0.9em; +} +.fa-normalsize { + font-size: 1em; +} +.fa-large { + font-size: 1.2em; +} +.fa-Large { + font-size: 1.5em; +} +.fa-LARGE { + font-size: 1.75em; +} +.fa-huge { + font-size: 2em; +} +.fa-Huge { + font-size: 2.5em; +} diff --git a/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-brands-400.ttf b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-brands-400.ttf new file mode 100644 index 0000000..430a02e Binary files /dev/null and b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-brands-400.ttf differ diff --git a/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-brands-400.woff2 b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-brands-400.woff2 new file mode 100644 index 0000000..4d904aa Binary files /dev/null and b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-brands-400.woff2 differ diff --git a/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-regular-400.ttf b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-regular-400.ttf new file mode 100644 index 0000000..23e3feb Binary files /dev/null and b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-regular-400.ttf differ diff --git a/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-regular-400.woff2 b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-regular-400.woff2 new file mode 100644 index 0000000..80e3b12 Binary files /dev/null and b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-regular-400.woff2 differ diff --git a/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-solid-900.ttf b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-solid-900.ttf new file mode 100644 index 0000000..da90824 Binary files /dev/null and b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-solid-900.ttf differ diff --git a/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-solid-900.woff2 b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-solid-900.woff2 new file mode 100644 index 0000000..360ba11 Binary files /dev/null and b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-solid-900.woff2 differ diff --git a/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-v4compatibility.ttf b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-v4compatibility.ttf new file mode 100644 index 0000000..e9545ed Binary files /dev/null and b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-v4compatibility.ttf differ diff --git a/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-v4compatibility.woff2 b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-v4compatibility.woff2 new file mode 100644 index 0000000..db5b0b9 Binary files /dev/null and b/2024-random-forests/_extensions/quarto-ext/fontawesome/assets/webfonts/fa-v4compatibility.woff2 differ diff --git a/2024-random-forests/_extensions/quarto-ext/fontawesome/fontawesome.lua b/2024-random-forests/_extensions/quarto-ext/fontawesome/fontawesome.lua new file mode 100644 index 0000000..ff64dca --- /dev/null +++ b/2024-random-forests/_extensions/quarto-ext/fontawesome/fontawesome.lua @@ -0,0 +1,84 @@ +local function ensureLatexDeps() + quarto.doc.use_latex_package("fontawesome5") +end + +local function ensureHtmlDeps() + quarto.doc.add_html_dependency({ + name = 'fontawesome6', + version = '0.1.0', + stylesheets = {'assets/css/all.css', 'assets/css/latex-fontsize.css'} + }) +end + +local function isEmpty(s) + return s == nil or s == '' +end + +local function isValidSize(size) + local validSizes = { + "tiny", + "scriptsize", + "footnotesize", + "small", + "normalsize", + "large", + "Large", + "LARGE", + "huge", + "Huge" + } + for _, v in ipairs(validSizes) do + if v == size then + return size + end + end + return "" +end + +return { + ["fa"] = function(args, kwargs) + + local group = "solid" + local icon = pandoc.utils.stringify(args[1]) + if #args > 1 then + group = icon + icon = pandoc.utils.stringify(args[2]) + end + + local title = pandoc.utils.stringify(kwargs["title"]) + if not isEmpty(title) then + title = " title=\"" .. title .. "\"" + end + + local label = pandoc.utils.stringify(kwargs["label"]) + if isEmpty(label) then + label = " aria-label=\"" .. icon .. "\"" + else + label = " aria-label=\"" .. label .. "\"" + end + + local size = pandoc.utils.stringify(kwargs["size"]) + + -- detect html (excluding epub which won't handle fa) + if quarto.doc.is_format("html:js") then + ensureHtmlDeps() + if not isEmpty(size) then + size = " fa-" .. size + end + return pandoc.RawInline( + 'html', + "" + ) + -- detect pdf / beamer / latex / etc + elseif quarto.doc.is_format("pdf") then + ensureLatexDeps() + if isEmpty(isValidSize(size)) then + return pandoc.RawInline('tex', "\\faIcon{" .. icon .. "}") + else + return pandoc.RawInline('tex', "{\\" .. size .. "\\faIcon{" .. icon .. "}}") + end + else + return pandoc.Null() + end + end +} diff --git a/2024-random-forests/assets/refs.bib b/2024-random-forests/assets/refs.bib new file mode 100644 index 0000000..e69de29 diff --git a/2024-random-forests/assets/zv-logo-192x192.png b/2024-random-forests/assets/zv-logo-192x192.png new file mode 100644 index 0000000..0638ba3 Binary files /dev/null and b/2024-random-forests/assets/zv-logo-192x192.png differ diff --git a/2024-random-forests/assets/zv-slides-theme.scss b/2024-random-forests/assets/zv-slides-theme.scss new file mode 100644 index 0000000..e03101d --- /dev/null +++ b/2024-random-forests/assets/zv-slides-theme.scss @@ -0,0 +1,100 @@ +/*-- scss:defaults --*/ + +// Text + +@import url("https://fonts.googleapis.com/css2?family=Oswald:wght@200;300;400;500;600;700&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Oxygen:wght@200;300;400;500;600;700;800;900&display=swap"); + +$body-font-family: 'Oxygen', Arial, sans-serif !important; +$title-font-family: 'Oswald', Georgia, serif !important; + +$presentation-font-size-root: 24pt; +$code-block-font-size: 0.8em; +$fig-caption-font-size: 0.6em; +$presentation-h1-font-size: 2.0em; +$presentation-h2-font-size: 1.6em; +$presentation-h3-font-size: 1.3em; +$presentation-h4-font-size: 1.1em; +$presentation-line-height: 1.5em; +$navlink-active-weight: 600; + +// Colours +$zv-black: #202020; +$zv-white: #FAFAFA; +$zv-grey: #EEEEEE; +$zv-teal: #0AB3C7; +$zv-fuchia: #C81E87; +$zv-blue: #3D52D5; +$zv-orange: #E87800; +$zv-navy: #003E74; + +$body-color: $zv-black; +$primary: $zv-black; +$link-color: $zv-orange; +$body-bg: $zv-white; +$code-block-bg: $zv-grey; +$code-block-border-color: $zv-black; +$code-color: $zv-fuchia; + + +h1, h2, h3, h4 { + font-family: $title-font-family; +} + +h2 { // Pad slide titles + padding-top: -0.1em; + padding-bottom: 0.7em; +} + +p, li { + font-family: $body-font-family; + font-weight: lighter; +} + +li { + padding-top: 0.6em; + padding-bottom: 0.6em; +} + +.slide-number { + font-family: $body-font-family; +} + +strong { + color: $zv-black; + font-weight: bolder; +} + +em { + color: $zv-orange; +} + +/*-- scss:rules --*/ + +.reveal .slide figure > figcaption{ + font-family: $body-font-family; + font-size: $fig-caption-font-size; +} + +.reveal .slide-logo { + max-height: 3.5% !important; +} + +.reveal .progress { + background: $zv-grey; + color: $zv-orange; + height: 0.7%; +} + +.code_class { +height: 700px; +width: 1200px; +} + +.vertical-center { + margin: 0; + position: absolute; + top: 50%; + -ms-transform: translateY(-50%); + transform: translateY(-50%); +} diff --git a/2024-random-forests/random-forest.R b/2024-random-forests/random-forest.R new file mode 100644 index 0000000..89b3574 --- /dev/null +++ b/2024-random-forests/random-forest.R @@ -0,0 +1,64 @@ +library(palmerpenguins) +library(dplyr) +library(ggplot2) +library(glue) +library(rpart) +library(rpart.plot) + +head(penguins) + +cols_to_keep +peng <- penguins %>% select(species, bill_length = bill_length_mm, bill_depth = bill_depth_mm) + +ggplot() + + geom_point(aes(x = bill_length, y = bill_depth, colour=species), data = peng) + + theme_minimal() + +tree <- rpart(species ~ bill_length + bill_depth, data = peng, method = "class") +rpart.plot(tree, main = "Decision Tree for the Palmer Penguins Dataset") + +peng_grid <- tibble( + bill_length = rep(seq(30, 60, by = 0.1), each = 131), + bill_depth = rep(seq(12, 25, by = 0.1), times = 301), +) + +peng_grid$prediction <- rpart.predict(tree, newdata = peng_grid, type = "class") + +ggplot() + + geom_raster(aes(x = bill_length, y = bill_depth, fill=prediction), data = peng_grid, alpha = 0.3) + + geom_point(aes(x = bill_length, y = bill_depth, colour=species), data = peng) + + theme_minimal() + + +#-------------- +set.seed(1234) +for (b in 1:3) { + i <- sample(1:nrow(peng), nrow(peng), replace = TRUE) + peng_b <- peng[i,] + + ggplot() + + geom_point(aes(x = bill_length, y = bill_depth, colour=species), data = peng, alpha = 0.5, size = 2) + + lims(x = c(30,60), y = c(12.5, 22.5)) + + theme_minimal() + + ggtitle("Original Data") + + ggplot() + + geom_point(aes(x = bill_length, y = bill_depth, colour=species), data = peng_b, alpha = 0.5, size = 2) + + lims(x = c(30,60), y = c(12.5, 22.5)) + + theme_minimal() + + ggtitle("Resampled Data", glue("bootstrap sample b={b}")) + + tree_b <- rpart(species ~ bill_length + bill_depth, data = peng_b, method = "class") + rpart.plot(tree_b, main = "Decision Tree for the Palmer Penguins Dataset", sub = glue("Bootstrap sample b={b}")) + + peng_grid[,b+3] <- rpart.predict(tree_b, newdata = peng_grid, type = "class") + names(peng_grid)[b + 3] <- glue("b_{b}") + + ggplot() + + geom_raster(aes(x = bill_length, y = bill_depth, fill = .data[[glue("b_{b}")]]), data = peng_grid, alpha = 0.3, ) + + geom_point(aes(x = bill_length, y = bill_depth, colour=species), data = peng_b, alpha = 0.5) + + theme_minimal() + + ggtitle("Decision Tree Predictions", glue("bootstrap sample b={b}")) + + +} diff --git a/2024-random-forests/readme.md b/2024-random-forests/readme.md new file mode 100644 index 0000000..541c77f --- /dev/null +++ b/2024-random-forests/readme.md @@ -0,0 +1,9 @@ +# Introduction to Random Forests (in ten minutes or less) + +## Description + + + + +### Abstract + diff --git a/zv-talk-refs.bib b/zv-talk-refs.bib new file mode 100644 index 0000000..25e4cea --- /dev/null +++ b/zv-talk-refs.bib @@ -0,0 +1,162 @@ +% Examples + +@inproceedings{vandePaper08, + author = {Alice {van de Paper} and Bob Authorson and Carrie Writerman}, + title = {A paper on writing papers}, + year = {2008}, + booktitle = {Advances in Good Paper Writing Processes}} + +@article{vandePaper09, + author = {Alice {van de Paper} and Bob Authorson}, + title = {A really long paper on writing papers}, + year = {2009}, + volume = {10}, + number = {3}, + pages = {1234--5678}, + journal = {The Annals of Paper Writing}} + +@article{vandePaper09b, + author = {Alice {van de Paper} and Bob Authorson}, + title = {A really long paper on writing papers}, + year = {2009}, + journal = {arXiv:0901.23456}} + +@book{vandePaper10, + author = {Alice {van de Paper}}, + title = {Writing Lots of Papers: A Book About It}, + year = {2009}, + edition = {$2^\text{nd}$}, + publisher = {Paper Writing Press}} + +@incollection{vandePaper10, + author = {Alice {van de Paper}}, + title = {A Chapter on Writing Papers}, + editor = {Bob Authorson and Carrie Writerman}, + booktitle = {The Handbook of Paper Writing}, + publisher = {Paper Writing Press}, + year = {2009}, + pages = {266--290}, + chapter = {10}} + + +%================================================================ +% A +%=============================================================== + +%================================================================ +% B +%=============================================================== + +%================================================================ +% C +%=============================================================== + +%================================================================ +% D +%=============================================================== + +%================================================================ +% E +%=============================================================== + +%================================================================ +% F +%=============================================================== + +%================================================================ +% G +%=============================================================== + +@techreport{gelman2013garden, + author = {Andrew Gelman and Eric Loken}, + title = {The garden of forking paths: Why multiple comparisons can be a problem, even when there is no “fishing expedition” or “p-hacking” and the research hypothesis was posited ahead of time}, + year={2013}, + institution = {Columbia University}, +} + +%================================================================ +% H +%=============================================================== + +%================================================================ +% I +%=============================================================== + +%================================================================ +% J +%=============================================================== + +%================================================================ +% K +%=============================================================== + +%================================================================ +% L +%=============================================================== + +%================================================================ +% M +%=============================================================== + +%================================================================ +% N +%=============================================================== + +%================================================================ +% O +%=============================================================== + +%================================================================ +% P +%=============================================================== + +%================================================================ +% Q +%=============================================================== + +%================================================================ +% R +%=============================================================== + +%================================================================ +% S +%=============================================================== + +%================================================================ +% T +%=============================================================== + +%================================================================ +% U +%=============================================================== + +%================================================================ +% V +%=============================================================== + +%================================================================ +% W +%=============================================================== + +%================================================================ +% X +%============================================================== + +%================================================================ +% Y +%=============================================================== + +%================================================================ +% Z +%=============================================================== + + +@article{gelman2013garden, + title={The garden of forking paths: Why multiple comparisons can be a problem, even when there is no “fishing expedition” or “p-hacking” and the research hypothesis was posited ahead of time}, + author={Gelman, Andrew and Loken, Eric}, + journal={Department of Statistics, Columbia University}, + volume={348}, + number={1-17}, + pages={3}, + year={2013} +}