diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..86fb5fd
Binary files /dev/null and b/.DS_Store differ
diff --git a/1 PA Decline/.DS_Store b/1 PA Decline/.DS_Store
new file mode 100644
index 0000000..d7f241e
Binary files /dev/null and b/1 PA Decline/.DS_Store differ
diff --git a/1 PA Decline/00master.R b/1 PA Decline/00master.R
new file mode 100644
index 0000000..2db076a
--- /dev/null
+++ b/1 PA Decline/00master.R
@@ -0,0 +1,252 @@
+##
+## Master script
+##
+## Based on the assignment work from the ISL-course
+##
+## Generation 2 - 02.december.2022
+## Code preparation for analysis on Denmarks Statistics server with enriched data set.
+##
+## Analysis plan:
+## Table 1
+## Figure 1: Sankey plot (drop & hop colored)
+## Table 2: Linear regression model of pase_6~.
+## Table 3: Elastic net prediction models of drop and hop. Performance measures referenced in text.
+##
+## A Rmarkdown file could be created to write the initial report with main results.
+## This code is a bit of a mess, as it is the result of several iterations. It works however.
+##
+
+## ====================================================================
+# Step 0: Primary outcome
+## ====================================================================
+
+# Script to run as hop and drop
+
+pout <- "drop" # Drop to first quartile
+
+# decl_rel
+# decl_abs
+# drop
+# hop
+
+## ====================================================================
+## Data
+## ====================================================================
+
+
+# setwd("/Users/au301842/PhysicalActivityandStrokeOutcome/1 PA Decline/")
+
+source(here::here("1 PA Decline/data_set.R"))
+# Loading data-set from USB, to not store on computer
+
+source(here::here("1 PA Decline/data_format.R"))
+
+## ====================================================================
+##
+## Baseline - by PASE group
+##
+## ====================================================================
+
+ts_q <- X_tbl |>
+ select(vars) |>
+ mutate(pase_0_cut = factor(quantile_cut(pase_0, groups = 4)[[1]],ordered = TRUE)) |>
+ select(-pase_6,-pase_0) |>
+ tbl_summary(missing = "no",
+ by="pase_0_cut",
+ value = list(where(is.factor) ~ "2"),
+ type = list(mrs_0 ~ "categorical",
+ all_continuous() ~ "continuous2"),
+ statistic = list(all_continuous() ~ c("{N_nonmiss}",
+ "{median} ({p25}, {p75})",
+ "{min}, {max}",
+ "{mean} ({sd})"))
+) |>
+ add_overall() |>
+ add_n ()
+
+ts_q
+
+tbl_one_rtf <- file("table1.RTF", "w")
+writeLines(ts_q%>%as_gt()%>%as_rtf(), tbl_one_rtf)
+close(tbl_one_rtf)
+
+## ====================================================================
+# Drops and hops
+## ====================================================================
+
+# TRUEs are patients dropping
+table(X_tbl$pase_0_cut!="1"&X_tbl$pase_6_cut=="1")/nrow(X_tbl[X_tbl$pase_0_cut!="1",])
+
+# TRUEs are percentage of patients inactive before stroke being more active after
+table(X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut!="1")/nrow(X_tbl[X_tbl$pase_0_cut=="1",])
+
+# TRUEs are percentage of patients being more active after that were inactive before stroke
+table(X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut!="1")/nrow(X_tbl[X_tbl$pase_6_cut!="1",])
+
+# Difference between hop/no-hop
+t.test(X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut!="1","pase_0"],X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_0"])
+
+summary(X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut!="1","pase_0"])
+
+summary(X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_0"])
+
+boxplot(X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut!="1","pase_0"],X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_0"])
+
+# Stationary low
+t.test(X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_0"],X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_6"])
+
+boxplot(X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_0"],X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_6"])
+
+## ====================================================================
+# Sankey plot
+## ====================================================================
+
+# source("sankey.R")
+# p_delta
+
+## ====================================================================
+# Six months PASE: Bivariate and multivariate analyses
+## ====================================================================
+
+dta_lmreg <- X_tbl |>
+ select(vars) |>
+ mutate(mrs_0=factor(ifelse(mrs_0==1,1,2)))
+
+Hmisc::label(dta_lmreg$mrs_0) <- "Pre-stroke mRS >0"
+
+uv_reg <- tbl_uvregression(data=dta_lmreg,
+ method=lm,
+ y="pase_6",
+ show_single_row = where(is.factor),
+ estimate_fun = ~style_sigfig(.x,digits = 3),
+ pvalue_fun = ~style_pvalue(.x, digits = 3)
+)
+
+mu_reg <- dta_lmreg |>
+ lm(formula=pase_6~.,data=_) |>
+ tbl_regression(show_single_row = where(is.factor),
+ estimate_fun = ~style_sigfig(.x,digits = 3),
+ pvalue_fun = ~style_pvalue(.x, digits = 3)
+ )|>
+ add_n()
+
+tbl_merge(list(uv_reg,mu_reg))
+
+
+## ====================================================================
+##
+## Data variance
+##
+## Illustrating principal components.
+##
+## ====================================================================
+
+
+# source("PCA.R")
+#
+#
+# pca22
+# ggsave("pc_plot.png",width = 18, height = 12, dpi = 300, limitsize = TRUE, units = "cm")
+
+
+## ====================================================================
+##
+## Models
+##
+## ====================================================================
+
+
+# source("assign_full.R")
+
+ls <- list()
+for (i in c("drop","hop")){
+ pout <- i
+ source("data_format.R")
+ source("regularisation_steps.R")
+}
+
+# Loop to run regularised model on both drop and hop.
+# Saved in list for printing and exporting the plot.
+
+## ====================================================================
+# Step 1: data merge
+## ====================================================================
+tbl<-merge(ls$drop$RegularisedCoefs$'_data',ls$hop$RegularisedCoefs$'_data',by="name",all.x=T, sort=F)
+
+## ====================================================================
+# Step 2: table
+## ====================================================================
+com_coef_tbl<-tbl%>%
+ gt()%>%
+ fmt_number(
+ columns=colnames(tbl)[sapply(tbl,is.numeric)], ## Selecting all numeric
+ rows = everything(),
+ decimals = 3)%>%
+ tab_spanner(
+ label = "DROP",
+ columns = 2:5
+ )%>%
+ tab_spanner(
+ label = "HOP",
+ columns = 6:9
+ )%>%
+ tab_header(
+ title = "Model coefficients",
+ subtitle = "Combined table of both full and regularised model coefficients"
+ )
+
+
+# paste0("Regularised model, (a=",
+# best_alph,
+# ", l=",
+# round(best_lamb,3),
+# ")")
+
+com_coef_tbl
+
+## ====================================================================
+# Step 3: export
+## ====================================================================
+com_coef_rtf <- file("table2.RTF", "w")
+writeLines(com_coef_tbl%>%as_rtf(), com_coef_rtf)
+close(com_coef_rtf)
+
+
+
+## ====================================================================
+##
+## Model performance
+##
+## Table with performance meassures for the two different models.
+##
+## ====================================================================
+
+## ====================================================================
+# Step 1: data set
+## ====================================================================
+
+tbl<-data.frame(Meassure=c(names(ls$drop$ConfusionMatrx$byClass),"Mean AUC"),
+ "Drop"=round(c(ls$drop$ConfusionMatrx$byClass,ls$drop$AUROC["Mean"]),3),
+ "Hop"=round(c(ls$hop$ConfusionMatrx$byClass,ls$hop$AUROC["Mean"]),3))
+
+## ====================================================================
+# Step 2: table
+## ====================================================================
+tbl_perf<-tbl%>%
+ gt()%>%
+ tab_header(
+ title = "Performance meassures",
+ subtitle = "Combined table of both drop and hop"
+ )
+
+tbl_perf
+
+## ====================================================================
+# Step 3: export
+## ====================================================================
+tbl_perf_rtf <- file("table3.RTF", "w")
+writeLines(tbl_perf%>%as_rtf(), tbl_perf_rtf)
+close(tbl_perf_rtf)
+
+
+
diff --git a/1 PA Decline/ESOC2023.qmd b/1 PA Decline/ESOC2023.qmd
new file mode 100644
index 0000000..3e9c75b
--- /dev/null
+++ b/1 PA Decline/ESOC2023.qmd
@@ -0,0 +1,42 @@
+---
+title: "ESOC2023"
+format: html
+editor: visual
+---
+
+```{r}
+library(plotly)
+
+df
+
+fig <- plot_ly(
+ type = "sankey",
+ orientation = "h",
+
+ node = list(
+ label = c("A1", "A2", "B1", "B2", "C1", "C2"),
+ color = c("blue", "blue", "blue", "blue", "blue", "blue"),
+ pad = 15,
+ thickness = 20,
+ line = list(
+ color = "black",
+ width = 0.5
+ )
+ ),
+
+ link = list(
+ source = c(0,1,0,2,3,3),
+ target = c(2,3,3,4,4,5),
+ value = c(8,4,2,8,4,2)
+ )
+ )
+fig <- fig %>% layout(
+ title = "Basic Sankey Diagram",
+ font = list(
+ size = 10
+ )
+)
+
+fig
+
+```
diff --git a/1 PA Decline/Fra DDV/.DS_Store b/1 PA Decline/Fra DDV/.DS_Store
new file mode 100644
index 0000000..6f49129
Binary files /dev/null and b/1 PA Decline/Fra DDV/.DS_Store differ
diff --git a/1 PA Decline/Fra DDV/240620/.DS_Store b/1 PA Decline/Fra DDV/240620/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/1 PA Decline/Fra DDV/240620/.DS_Store differ
diff --git a/1 PA Decline/Fra DDV/240620/calibration.png b/1 PA Decline/Fra DDV/240620/calibration.png
new file mode 100755
index 0000000..1520121
Binary files /dev/null and b/1 PA Decline/Fra DDV/240620/calibration.png differ
diff --git a/1 PA Decline/Fra DDV/240620/calibration_imp.png b/1 PA Decline/Fra DDV/240620/calibration_imp.png
new file mode 100755
index 0000000..03c1c2b
Binary files /dev/null and b/1 PA Decline/Fra DDV/240620/calibration_imp.png differ
diff --git a/1 PA Decline/Fra DDV/240620/pa_change_analyses.docx b/1 PA Decline/Fra DDV/240620/pa_change_analyses.docx
new file mode 100755
index 0000000..a67915a
Binary files /dev/null and b/1 PA Decline/Fra DDV/240620/pa_change_analyses.docx differ
diff --git a/1 PA Decline/Fra DDV/240620/pa_change_tbl1.docx b/1 PA Decline/Fra DDV/240620/pa_change_tbl1.docx
new file mode 100755
index 0000000..4be0389
Binary files /dev/null and b/1 PA Decline/Fra DDV/240620/pa_change_tbl1.docx differ
diff --git a/1 PA Decline/Fra DDV/240624/.DS_Store b/1 PA Decline/Fra DDV/240624/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/1 PA Decline/Fra DDV/240624/.DS_Store differ
diff --git a/1 PA Decline/Fra DDV/240624/calibration_imp.png b/1 PA Decline/Fra DDV/240624/calibration_imp.png
new file mode 100644
index 0000000..ec258ed
Binary files /dev/null and b/1 PA Decline/Fra DDV/240624/calibration_imp.png differ
diff --git a/1 PA Decline/Fra DDV/240624/pa_change_analyses.docx b/1 PA Decline/Fra DDV/240624/pa_change_analyses.docx
new file mode 100644
index 0000000..a52430c
Binary files /dev/null and b/1 PA Decline/Fra DDV/240624/pa_change_analyses.docx differ
diff --git a/1 PA Decline/Fra DDV/241002/.DS_Store b/1 PA Decline/Fra DDV/241002/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/1 PA Decline/Fra DDV/241002/.DS_Store differ
diff --git a/1 PA Decline/Fra DDV/241002/excluded.R b/1 PA Decline/Fra DDV/241002/excluded.R
new file mode 100755
index 0000000..b036bf5
--- /dev/null
+++ b/1 PA Decline/Fra DDV/241002/excluded.R
@@ -0,0 +1,9 @@
+targets::tar_read(df_all_data_formatted) |>
+ get_vars(c("clin","lifestyle","ses", "assess.pred")) |>
+ dplyr::mutate(exclude=ifelse(is.na(pase_0)|is.na(pase_4),"Excluded","Included"))|>
+ dplyr::select(-pase_0,-pase_4) |>
+ dplyr::select(exclude,soc_status_nowork, fam_indk_hl, edu_level_hl)|>
+ gtsummary::tbl_summary(by=exclude) |>
+ gtsummary::add_p() |>
+ fix_labels() |>
+ mask_micro_summary(micro.n = 5)
diff --git a/1 PA Decline/Fra DDV/241002/minimal_perf_all.docx b/1 PA Decline/Fra DDV/241002/minimal_perf_all.docx
new file mode 100755
index 0000000..0c34411
Binary files /dev/null and b/1 PA Decline/Fra DDV/241002/minimal_perf_all.docx differ
diff --git a/1 PA Decline/Fra DDV/241002/mmrm.docx b/1 PA Decline/Fra DDV/241002/mmrm.docx
new file mode 100644
index 0000000..78b50ae
Binary files /dev/null and b/1 PA Decline/Fra DDV/241002/mmrm.docx differ
diff --git a/1 PA Decline/Fra DDV/241002/mmrm_female.docx b/1 PA Decline/Fra DDV/241002/mmrm_female.docx
new file mode 100755
index 0000000..a71a782
Binary files /dev/null and b/1 PA Decline/Fra DDV/241002/mmrm_female.docx differ
diff --git a/1 PA Decline/Fra DDV/241002/mmrm_male.docx b/1 PA Decline/Fra DDV/241002/mmrm_male.docx
new file mode 100755
index 0000000..f9a6b80
Binary files /dev/null and b/1 PA Decline/Fra DDV/241002/mmrm_male.docx differ
diff --git a/1 PA Decline/Fra DDV/241002/pa_change_missings.docx b/1 PA Decline/Fra DDV/241002/pa_change_missings.docx
new file mode 100755
index 0000000..14326e3
Binary files /dev/null and b/1 PA Decline/Fra DDV/241002/pa_change_missings.docx differ
diff --git a/1 PA Decline/Fra DDV/241002/~$mmrm.docx b/1 PA Decline/Fra DDV/241002/~$mmrm.docx
new file mode 100644
index 0000000..b367b80
Binary files /dev/null and b/1 PA Decline/Fra DDV/241002/~$mmrm.docx differ
diff --git a/1 PA Decline/Fra DDV/calibration_imp.xlsx b/1 PA Decline/Fra DDV/calibration_imp.xlsx
new file mode 100644
index 0000000..1c18d1a
Binary files /dev/null and b/1 PA Decline/Fra DDV/calibration_imp.xlsx differ
diff --git a/1 PA Decline/Fra DDV/functions200411.R b/1 PA Decline/Fra DDV/functions200411.R
new file mode 100755
index 0000000..69cc30e
--- /dev/null
+++ b/1 PA Decline/Fra DDV/functions200411.R
@@ -0,0 +1,2627 @@
+# pop <- haven::read_sas(here::here("E:/rawdata/709203/Population/pop_talos.sas7bdat"))
+
+# sst <- list.files(here::here("E:/rawdata/709203/Eksterne data"), pattern = "*.sas7bdat", full.names = TRUE) |>
+# purrr::map(haven::read_sas)
+
+
+
+#' Read all sas files in folder to list
+#'
+#' @param path folder path
+#'
+#' @return list
+sas2list <- function(path) {
+ ls <- list.files(here::here(path), pattern = "*.sas7bdat", full.names = TRUE) |>
+ purrr::map(haven::read_sas)
+ names(ls) <- list.files(here::here(path), pattern = "*.sas7bdat") |>
+ gsub(".sas7bdat", "", x = _) |>
+ toupper()
+ ls
+}
+
+
+#' Flatten multilevel list
+#'
+#' @param paths character vector of folder paths
+#'
+#' @return flattened list
+flatmultiread <- function(paths) {
+ paths |>
+ purrr::map(sas2list) |>
+ purrr::list_flatten()
+}
+
+# ls <- targets::tar_read(reg_data)
+
+# Vectors are kept for compatibility. Calling functions can be done from within other functions. So much easier!
+
+date_cutter <- function() as.Date("2023-01-01")
+date.cut <- date_cutter() # The earliest date will define the overall date cut
+
+censor_cutter <- function() 8.5
+censor.cut <- censor_cutter() # years of maximum follow up, due to small numbers
+
+vasc.diags <- c("I21", "I61", "I63", "I64", "G45", "K28")
+
+#' Extract deaths from Dødsårsagsregiseret
+#'
+#' @param ls
+#' @param max.date
+#' @param diags.vasc
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(reg_data) |> get_deaths()
+get_deaths <- function(ls, max.date = date.cut, diags.vasc = vasc.diags) {
+
+
+ # vasc.death.tilg <- mapply(ls$DAR_T_DODSAARSAG_2[, "C_DODTILGRUNDL_ACME"],
+ # FUN = function(i) { # mapply inside apply call to handle rowvise matching in in matrix
+ # i_3 <- substr(i, 1, 3) # Substr only the 3 first characters to match by group
+ # i_3 %in% diags.vasc # Rowvise matching
+ # }
+ # )
+
+ vasc.death.tilg <- ls$DAR_T_DODSAARSAG_2[["C_DODTILGRUNDL_ACME"]] |> substr(1, 3) %in% diags.vasc
+
+
+ vasc.death.any <- apply(mapply(ls$DAR_T_DODSAARSAG_2[, c("C_DODTILGRUNDL_ACME", "C_DOD_1A", "C_DOD_1B", "C_DOD_1C", "C_DOD_1D")],
+ FUN = function(i) { # mapply inside apply call to handle rowvise matching in in matrix
+ i_3 <- substr(i, 1, 3) # Substr only the 3 first characters to match by group
+ i_3 %in% diags.vasc # Rowvise matching
+ }
+ ), 1, any) # Simplify to TRUE if any
+ #
+ vasc.death.other <- apply(mapply(ls$DAR_T_DODSAARSAG_2[, c("C_DOD_1A", "C_DOD_1B", "C_DOD_1C", "C_DOD_1D")],
+ FUN = function(i) { # mapply inside apply call to handle rowvise matching in in matrix
+ i_3 <- substr(i, 1, 3) # Substr only the 3 first characters to match by group
+ i_3 %in% diags.vasc # Rowvise matching
+ }
+ ), 1, any) # Simplify to TRUE if any
+
+ diag.either <- xor(vasc.death.other, vasc.death.tilg)
+ diag.both <- vasc.death.other & vasc.death.tilg
+
+ vasc.death.diags <-
+ apply(
+ mapply(
+ ls$DAR_T_DODSAARSAG_2[, c(
+ "C_DODTILGRUNDL_ACME",
+ "C_DOD_1A",
+ "C_DOD_1B",
+ "C_DOD_1C",
+ "C_DOD_1D"
+ )],
+ FUN = function(i) {
+ # mapply inside apply call to handle rowvise matching in in matrix
+ substr(i, 1, 3) # Substr only the 3 first characters to match by group
+ }
+ ),
+ 1,
+ paste,
+ collapse = ","
+ )
+
+ deaths.vasc <-
+ ls$DAR_T_DODSAARSAG_2 |>
+ dplyr::select(K_CPR, D_STATDATO) |>
+ dplyr::filter(vasc.death.tilg)
+
+ df.death.all <- ls$CPR3_T_PERSON |>
+ dplyr::filter(C_STATUS == 90) |> # People migrating are filtered (n ~ 1)
+ dplyr::select(c(
+ "V_PNR",
+ "D_STATUS_HEN_START"
+ )) |>
+ dplyr::left_join(deaths.vasc, by = c("V_PNR" = "K_CPR")) |>
+ dplyr::mutate(vasc_death = !is.na(D_STATDATO)) |>
+ dplyr::transmute(
+ PNR = V_PNR,
+ death_date = D_STATUS_HEN_START,
+ vasc_death = vasc_death
+ )
+
+ df.death.all |> dplyr::filter(death_date < max.date)
+}
+
+
+#' Title
+#'
+#' @param ls
+#' @param max.date
+#' @param diags.vasc
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' ls <- targets::tar_read(reg_list)
+get_events <- function(ls, max.date = date.cut, diags.vasc = vasc.diags) {
+ ident.vars <- toupper(c("_recnum", "_cpr"))
+
+ df.vasc.events.lpr <- ls$LPR_T_DIAG |>
+ dplyr::mutate(dia.f = substr(C_DIAG, 2, 4)) |> # Subsets only 2:4 chars, to get main group
+ dplyr::filter(
+ dia.f %in% diags.vasc
+ # & # Filters to only include pre-defined diagnoses
+ # C_DIAGTYPE=="A"
+ ) |> # Filters to only include if main diagnosis
+ dplyr::select(
+ ends_with(ident.vars),
+ "C_DIAG",
+ "C_DIAGTYPE"
+ ) |>
+ dplyr::left_join(
+ ls$LPR_T_ADM |> dplyr::select(
+ tidyselect::ends_with(ident.vars),
+ "D_INDDTO",
+ "C_INDM",
+ "D_UDDTO",
+ "C_UDM",
+ "C_SGH",
+ "C_AFD",
+ "C_ADIAG"
+ ),
+ by = c("V_RECNUM" = "K_RECNUM")
+ )
+
+ ## LPR-F - LPR 3
+
+ ident.vars.lpr3 <- toupper(c("cpr", "_kontakt", "DW_EK_FORLOEB"))
+
+ df.vasc.events.lpr3 <- ls$LPR_F_DIAGNOSER |>
+ dplyr::mutate(dia.f = substr(DIAGNOSEKODE, 2, 4)) |> # Subsets only 2:4 chars, to get main group
+ dplyr::filter(
+ dia.f %in% diags.vasc
+ # & # Filters to only include pre-defined diagnoses
+ # DIAGNOSETYPE=="A"
+ ) |> # Filters to only include if main diagnosis
+ dplyr::select(
+ ends_with(ident.vars.lpr3),
+ "DIAGNOSEKODE",
+ "DIAGNOSETYPE"
+ ) |>
+ dplyr::left_join(
+ ls$LPR_F_KONTAKTER |> dplyr::select(
+ ends_with(ident.vars.lpr3),
+ "DATO_START",
+ "DATO_SLUT",
+ "PRIORITET"
+ ),
+ by = c("DW_EK_KONTAKT")
+ ) |>
+ dplyr::mutate(PRIORITET = as.character((PRIORITET == "ATA1") + 1)) # If ATA1 then 1, if not (ATA3) then 2, cowboy coding
+
+ df.vasc.events <- dplyr::full_join(df.vasc.events.lpr, df.vasc.events.lpr3, by = c(
+ "V_CPR" = "CPR",
+ "C_DIAG" = "DIAGNOSEKODE",
+ "C_DIAGTYPE" = "DIAGNOSETYPE",
+ "D_INDDTO" = "DATO_START",
+ "D_UDDTO" = "DATO_SLUT",
+ "C_INDM" = "PRIORITET"
+ )) |>
+ dplyr::mutate(date.event = D_INDDTO)
+
+ df.vasc.events |> dplyr::filter(date.event < max.date)
+}
+
+
+# deaths <- targets::tar_read(df_deaths)
+# events <- targets::tar_read(df_events)
+# clinical <- targets::tar_read(pop_df)
+
+
+#' Filter only truly considered events
+#'
+#' @param data
+#'
+#' @return tibble
+define_events <- function(data) {
+ data |> dplyr::filter(
+ C_DIAGTYPE == "A", # Primary diagnosis
+ C_INDM == "1", # Acutely admitted
+ difftime(date.event, rdate, units = "days") > 5 # More than five (5) days after randomisation/primary stroke
+ )
+}
+
+#' The big merger and filter of events
+#'
+#' @param ls list of events, deaths and clinical
+#'
+#' @return tibble
+merge_events <- function(ls) {
+ df.events <- dplyr::full_join(
+ purrr::pluck(ls, "events"),
+ purrr::pluck(ls, "deaths") |>
+ dplyr::mutate(
+ # These are just added to ease later filtering
+ C_DIAGTYPE = "A",
+ C_INDM = "1"
+ ), # Ads diagtype=A, C_INDM=1 for easier sorting later
+ by = c(
+ "V_CPR" = "PNR",
+ "date.event" = "death_date",
+ "C_DIAGTYPE",
+ "C_INDM"
+ )
+ ) |>
+ dplyr::full_join(dplyr::select(purrr::pluck(ls, "clinical"), c("PNR", "rdate", "enddate")),
+ by = c("V_CPR" = "PNR")
+ ) |>
+ dplyr::arrange(date.event) |> # Sort by event date
+ dplyr::mutate(event.type = dplyr::if_else(
+ is.na(C_DIAG),
+ dplyr::if_else(vasc_death, "death.vasc", "death.other"),
+ substr(C_DIAG, 1, 4)
+ ))
+
+ df.events |>
+ dplyr::group_split(V_CPR) |> # Splits by CPR
+ purrr::map(define_events) |> # Custom function to specify criteria for events
+ purrr::discard(\(x) nrow(x) == 0) |> # Discard empty elements
+ purrr::modify(\(x) x[1, ]) |> # Select first event
+ purrr::list_rbind() |>
+ dplyr::transmute(
+ CPR = V_CPR,
+ date.event,
+ event.type
+ )
+}
+
+
+
+
+#' Count number of prescriptions of given ATC group for each CPR
+#'
+#' @param atc.code atc group
+#' @param data dataset from LMS
+#'
+#' @return tibble
+count_treat <- function(atc.code, data) {
+ data |>
+ dplyr::filter(grepl(atc.code, ATC)) |>
+ dplyr::count(CPR) |>
+ dplyr::filter(n > 1)
+}
+
+
+#' Get LMS data
+#'
+#' @param ls list of datasets
+#' @param max.date filter date for max inclusion
+#' @param atc.tbl tibble of atc codes
+#'
+#' @return tibble
+get_lms <- function(ls, max.date, atc.tbl) {
+ ls$LMS_EPIKUR |>
+ dplyr::filter(grepl(atc.tbl[1], ATC)) |>
+ dplyr::left_join(ls$LMS_LAEGEMIDDELOPLYSNINGER) |>
+ dplyr::filter(as.Date(ACTDATE) < max.date)
+}
+
+#' Get count of treated patients from LMS data
+#'
+#' @param ls list of datasets
+#' @param max.date filter date for max inclusion
+#' @param atc.tbl tibble of atc codes
+#'
+#' @return tibble
+get_treated <- function(ls,
+ max.date = date.cut,
+ atc.tbl = c(
+ atc.antidep = "N06A",
+ atc.ssri = "N06AB"
+ )) {
+ df <- atc.tbl |>
+ purrr::map(count_treat, get_lms(ls, max.date, atc.tbl)) |>
+ purrr::reduce(dplyr::full_join, by = "CPR")
+ colnames(df) <- c("CPR", paste0("n.", names(atc.tbl)))
+ df
+}
+
+#' BMI calc, drops
+#'
+#' @param w weight in kg
+#' @param h height in cm
+#' @param data data set
+#'
+#' @return tibble
+bmi_calc <- function(data, drop = TRUE) {
+ # After inspection, both h+w are missing if any is missing
+ out <- data |> dplyr::mutate(reg_bmi = suppressWarnings(as.numeric(dplyr::if_else(reg_vaegt == "NA", reg_vaegt_anslaaet, reg_vaegt)) / ((as.numeric(reg_hojde) / 100)^2)))
+
+ if (drop) {
+ out <- out |>
+ dplyr::select(-dplyr::all_of(c("reg_vaegt", "reg_vaegt_anslaaet", "reg_hojde")))
+ }
+ out
+}
+
+is_equal <- function(data, test) {
+ data == test
+}
+
+#' Load clinical population data
+#'
+#' @return tibble
+#' @examples
+#' get_clinical() |> colnames()
+#'
+get_clinical <- function() {
+ sas2list("E:/rawdata/709203/Population")[[2]] |>
+ correct_na() |>
+ dplyr::mutate(
+ reg_smoker = dplyr::case_match(
+ reg_rygning, "1" ~ TRUE,
+ c("2", "3", "4") ~ FALSE,
+ "9" ~ NA
+ ),
+ # Living alone defined as not together with somebody
+ reg_alone = dplyr::case_match(
+ reg_civil, "1" ~ FALSE,
+ c("2", "3") ~ TRUE,
+ "9" ~ NA
+ ),
+ reg_more_alc = dplyr::case_match(
+ reg_alkohol, "1" ~ FALSE,
+ "2" ~ TRUE,
+ "9" ~ NA
+ ),
+ reg_female = sex == "Kvinde",
+ dplyr::across(
+ .cols = c(
+ "reg_hyperten",
+ "reg_diabetes",
+ "reg_atriefli",
+ "reg_perifer_arteriel",
+ "reg_tidl_tci",
+ "reg_ami"
+ ),
+ ~ dplyr::case_match(
+ .x, "1" ~ TRUE,
+ "2" ~ FALSE,
+ "9" ~ NA
+ )
+ ),
+ dplyr::across(
+ .cols = c(
+ "reg_trombolyse",
+ "reg_trombektomi"
+ ),
+ ~ dplyr::case_match(
+ .x, "1" ~ TRUE,
+ c("3","4") ~ FALSE,
+ "9" ~ NA
+ )
+ ),
+ reg_any_perf = reg_trombolyse | reg_trombektomi
+ ) |>
+ bmi_calc()
+}
+
+# get_clinical() |> pragmatic_imputation() |> skimr::skim()
+
+# get_clinical <- function() {
+# sas2list("E:/rawdata/709203/Population")[[2]] |>
+# dplyr::mutate(
+# reg_smoker = reg_rygning == 1,
+# reg_cohabiting = reg_civil == 1,
+# reg_more_alc = reg_alkohol == 2,
+# reg_female = sex == "Kvinde",
+# dplyr::across(.cols = c("reg_hyperten", "reg_diabetes", "reg_atriefli", "reg_perifer_arteriel", "reg_tidl_tci", "reg_ami", "reg_trombolyse", "reg_trombektomi"), ~ .x == 1),
+# reg_any_perf = reg_trombolyse | reg_trombektomi
+# ) |>
+# bmi_calc()
+# }
+
+pragmatic_imputation <- function(data, vec=c("reg_smoker","reg_cohabiting","reg_more_alc","reg_hyperten", "reg_diabetes", "reg_atriefli", "reg_perifer_arteriel", "reg_tidl_tci", "reg_ami", "reg_trombolyse", "reg_trombektomi","reg_any_perf")) {
+ # Assumes, if not TRUE, then FALSE (gets rid of NAs)
+ data |> dplyr::mutate(dplyr::across(.cols = tidyselect::any_of(vec), ~dplyr::if_else(.x,TRUE,FALSE,missing = FALSE)))
+}
+
+#' Load all registry tables to list
+#'
+#' @return list
+get_reg_ls <- function() {
+ flatmultiread(c("E:/rawdata/709203/Eksterne data", "E:/rawdata/709203/Grunddata"))
+}
+
+
+#' Definition of relevant variables from DST tables
+#'
+#' @return
+define_dst_vars <- function() {
+ list(
+ bef = c("PNR", "FAMILIE_ID"),
+ faik = c("FAMILIE_ID", "FAMAEKVIVADISP_13", "FAMSOCIOGRUP_13"),
+ ras = c("PNR", "SOC_STATUS_KODE"),
+ uddf = c("PNR", "HFAUDD")
+ )
+}
+
+#' Simple wrapper of dplyr::select
+#'
+#' @param data
+#' @param vars
+#'
+#' @return
+select_vars <- function(data, vars) {
+ data |> dplyr::select({{ vars }})
+}
+
+#' Subset DST tables to only include relvant variables.
+#'
+#' @param ls List of all registry tables
+#'
+#' @return
+get_dst_tables <- function(ls) {
+ dst_vars <- define_dst_vars()
+ dst_tbl <- toupper(names(dst_vars))
+ ls.all <- purrr::map(seq_along(dst_vars), function(i) {
+ ls.reg <- ls[grepl(paste0("^", dst_tbl[i]), names(ls))] |> purrr::map(select_vars, vars = dst_vars[[i]])
+ names(ls.reg) <- paste0("y", stringr::str_extract(names(ls.reg), "[0-9]{4}"))
+ ls.reg
+ })
+ names(ls.all) <- dst_tbl
+ ls.all
+}
+
+#' Wrapper to generate string matching pattern for stringr::str_detect()
+#'
+#' @param data
+#'
+#' @return
+match_str <- function(data) {
+ paste0("[", paste0(data, collapse = ","), "]")
+}
+
+#' Wrapper to generate string matching pattern for grepl()
+#'
+#' @param data character vector
+#'
+#' @return
+match_str_grepl <- function(data) {
+ paste0("(", paste0(data, collapse = "|"), ")")
+}
+
+# get_dst_tables(ls)
+
+#' Generate sequence of previous N length
+#'
+#' @param data numeric vector of length 1
+#'
+#' @return
+#'
+#' @examples
+#' last5y(10)
+#' last5y(c(10, 6, 3))
+lastNy <- function(data, n = 5) {
+ paste0("y", seq((data - n), data) - 1)
+}
+
+#' Filter PNR (cpr) across list elements
+#'
+#' @param data list of tibbles to pass through
+#' @param index index number (PNR/CPR)
+#'
+#' @return tibble
+filterCPRacross <- function(data, index) {
+ data |>
+ purrr::map(function(i) {
+ i[i$PNR == index, ]
+ }) |>
+ purrr::list_rbind()
+}
+
+#' Summarise data from last 5 years prior to inclusion
+#'
+#' @param data list with
+#' @param v.median variables to get median
+#' @param v.latest variables to get latest
+#' @param v.mean variables to get mean
+#'
+#' @return tibble
+previousNyears <- function(data, data.clin, n.years = 5, v.median = NULL, v.latest = c("FAMSOCIOGRUP_13", "SOC_STATUS_KODE"), v.mean = c("FAMAEKVIVADISP_13")) {
+ df.cpryear <- data.clin |> dplyr::transmute(
+ CPR = PNR,
+ year = as.numeric(format(as.Date(rdate), "%Y"))
+ )
+
+ seqs <- purrr::map(df.cpryear$year, lastNy, n = n.years)
+
+ seq_along(seqs) |>
+ purrr::map(function(i) {
+ df <- data[c(seqs[[i]])] |>
+ filterCPRacross(index = df.cpryear$CPR[i]) |>
+ dplyr::group_by(PNR) |>
+ dplyr::summarise(
+ dplyr::across(tidyselect::any_of(v.latest), \(x) tail(x, n = 1), .names = "{.col}.latest"),
+ dplyr::across(tidyselect::any_of(v.mean), \(x) mean(x, na.rm = TRUE), .names = "{.col}.{n.years}.mean"),
+ dplyr::across(tidyselect::any_of(v.median), \(x) median(x, na.rm = TRUE), .names = "{.col}.{n.years}.median")
+ )
+ }) |>
+ purrr::list_rbind()
+}
+
+
+#' Extract relevant and summarised data from BAF and FAIK
+#'
+#' @param data list of dst data tables
+#'
+#' @return tibble
+#'
+#' @examples
+#' get_reg_ls() |>
+#' get_dst_tables() |>
+#' get_beffaikras()
+get_beffaikras <- function(data, clin.data = get_clinical()) {
+ data <- data[stringr::str_detect(match_str(c("BEF", "FAIK", "RAS")), names(data))] |> purrr::list_flatten()
+
+ years <- stringr::str_extract(names(data), "y[0-9]{4}")
+
+ years[duplicated(years)] |>
+ purrr::map(grep, years) |>
+ purrr::map(function(i) {
+ data[c(i)] |> purrr::reduce(dplyr::full_join)
+ }) |>
+ purrr::set_names(years[duplicated(years)]) |>
+ previousNyears(data.clin = clin.data)
+
+ ## BEF
+ ## # Befolkningsoversigt. Data skal bruges for at kunne udtrække husstandsindkomst.
+ ## FAIK
+ ## # Familieindkomst. Familie id skal flættes med ID fra BEF for hvert år for at tage hensyn til evt skifte i status.
+ ## FAMAEKVIVADISP_13 er relevante variabel for ækvivaleret indkomst
+ ## Der findes også familiesocioøkonomisk status. Gør som Sine. Be done with it!
+}
+
+#' Title
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- read_edu_level()
+#' data |> dplyr::count(ISCED)
+read_edu_level <- function() {
+ haven::read_dta("E:/Formater/SAS formater i Danmarks Statistik/STATA_datasaet/Disced/c_audd_level_l1l4_k.dta") |>
+ dplyr::transmute(
+ HFAUDD = start,
+ ISCED = AUDD_LEVEL_L1L4_K
+ )
+}
+
+# haven::read_dta(
+# "E:/Formater/SAS formater i Danmarks Statistik/STATA_datasaet/Disced/c_audd_level_l1l3_k.dta") |>
+# dplyr::count(AUDD_LEVEL_L1L3_K)
+
+# ls <- get_reg_ls() |> get_dst_tables()
+
+get_uddf <- function(ls) {
+ ls |>
+ purrr::pluck("UDDF") |>
+ purrr::pluck(1) |>
+ dplyr::mutate(HFAUDD = as.character(HFAUDD)) |>
+ dplyr::left_join(read_edu_level()) |>
+ dplyr::group_by(PNR) |>
+ dplyr::summarise(ISCED = max(ISCED), .groups = "keep") |>
+ dplyr::mutate(
+ ISCED = as.numeric(ISCED),
+ ISCED_lvl = dplyr::case_match(ISCED, 0:2 ~ "low",
+ 3:4 ~ "medium",
+ 5:9 ~ "high",
+ .default = NA
+ ),
+ ISCED_bin = dplyr::case_match(ISCED, 0:3 ~ "low",
+ 4:9 ~ "high",
+ .default = NA
+ )
+ )
+}
+
+
+#' Collects all relevant variables from DST tables
+#'
+#' @param ls list of all registry tables
+#' @param df.clin clinical data set
+#'
+#' @return tibble
+#' @examples
+#' get_reg_ls() |> get_dst(df.clin = get_clinical())
+get_dst <- function(ls, df.clin) {
+ ls_dst <- get_dst_tables(ls)
+ ls_dst |>
+ ## BEFxFAIKxRAS
+ get_beffaikras(clin.data = df.clin) |>
+ dplyr::full_join(
+ ## UDDF
+ get_uddf(ls_dst)
+ )
+}
+
+#' Eases pipe renaming of columns
+#'
+#' @param data tibble, list or other object, for which names() makes sense. see ?setNames
+#' @param prefix prefix to add
+#' @param exclude names not to modify
+#' @param new.names character vector of all new names
+#'
+#' @return object of same class as data
+#'
+#' @examples
+#' set_colnames(data = mtcars, prefix = "WOW", exclude = "mpg")
+set_colnames <- function(data, new.names = NULL, prefix = NULL, exclude = c("PNR", "CPR"), prefix.sep = "_") {
+ if (is.null(new.names)) {
+ nms <- names(data)
+ } else {
+ nms <- new.names
+ }
+
+ if (is.null(prefix)) {
+ nms.mod <- nms
+ } else {
+ nms.mod <- paste(prefix, nms, sep = prefix.sep)
+ }
+
+ setNames(
+ object = data,
+ nm = dplyr::if_else(stringr::str_detect(match_str(exclude), nms),
+ nms,
+ nms.mod
+ )
+ )
+}
+
+
+#' Store of variable names for data sub-setting
+#'
+#' @return list
+#' @examples
+#' define_variables()
+define_variables <- function() {
+ list(
+ clin = c(
+ "age",
+ "reg_female",
+ "nihss_0",
+ "reg_trombolyse",
+ "reg_trombektomi",
+ # "rtreat",
+ "rtreat_placebo"),
+ lifestyle=c(
+ "pase_0",
+ "pase_4",
+ "reg_alone",
+ "reg_bmi",
+ # "reg_hojde",
+ # "reg_vaegt_alt",
+ "reg_smoker",
+ "reg_more_alc",
+ "reg_hyperten",
+ "reg_diabetes",
+ "reg_tidl_tci",
+ "reg_atriefli",
+ "reg_ami",
+ "reg_perifer_arteriel"),
+ ses=c(
+ # "soc_status",
+ # "soc_status_work",
+ "soc_status_nowork",
+ # "fam_indk",
+ "fam_indk_hl",
+ # "fam_indk_high",
+ # "fam_indk_low",
+ # "edu_level",
+ # "edu_high",
+ # "edu_low",
+ "edu_level_hl"
+ ),
+ assess.events = c(
+ "who_4",
+ "mdi_4",
+ "mrs_4_above1",
+ "mfi_gen_4",
+ "time",
+ "status",
+ "event.include"
+ ),
+ assess.pred = c(
+ "who_0",
+ "mrs_0_above0"
+ ),
+ extra = c(
+ "soc_status",
+ "pase_0",
+ "pase_4"
+ )
+ )
+}
+
+#' Get var names in vector from group names. Possibility to keep all vars for as log as possible. Can be supplied to `gtsummary` functions
+#'
+#' @param groups vector of group names. See names(define_variables()) for options
+#'
+#' @return
+#' @export
+#'
+#' @examples
+get_var_vec <- function(v.groups){
+ define_variables()[{{ v.groups }}] |> purrr::list_c()
+}
+
+#' SUbsets dataset based on variable group names as defined
+#'
+#' @param vector character vector of category names
+#'
+#' @return character vector
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> get_vars(c("universal", "events"))
+get_vars <- function(data, vars.groups) {
+ data |> dplyr::select(tidyselect::all_of(get_var_vec(vars.groups)))
+}
+
+
+
+#' Collect all relevant data for the events analysis data set
+#'
+#' @param ls ls of tibbles
+#'
+#' @return tibble
+collectall <- function(ls) {
+ purrr::pluck(ls, "clinical") |>
+ dplyr::left_join(purrr::pluck(ls, "all_events") |> set_colnames(prefix = "event"), by = c("PNR" = "CPR")) |>
+ dplyr::left_join(purrr::pluck(ls, "dst") |> set_colnames(prefix = "dst"), by = "PNR")
+}
+
+
+## Formatting for analysis
+
+#' Function to cut and group PASE data
+#'
+#' @param data data set including pase_0 and _4
+#'
+#' @return tibble
+pase_cutter <- function(data, pase.rev = TRUE, drop.pase = FALSE, drop.nas=FALSE) {
+ data.classes <- class(data)
+ if ("mids" %in% data.classes) {
+ data <- data |> mice::complete(action = "long", include = TRUE)
+ }
+
+ data <- data |>
+ dplyr::mutate(dplyr::across(.cols = c("pase_0", "pase_4"), \(i) {
+ cut(x = i, breaks = quantile(pase_0, na.rm = TRUE), labels = 1:4, include.lowest = TRUE)
+ }, .names = "{.col}_quartile")) |>
+ dplyr::mutate(pase_change = factor(dplyr::case_when(
+ pase_0_quartile == 1 & pase_4_quartile == 1 ~ "Persistently low",
+ pase_0_quartile %in% 2:4 &
+ pase_4_quartile %in% 2:4 ~ "Persistently high",
+ pase_0_quartile == 1 &
+ pase_4_quartile %in% 2:4 ~ "Increase",
+ pase_0_quartile %in% 2:4 &
+ pase_4_quartile == 1 ~ "Decrease"
+ ), ordered = FALSE),
+ pase_change=factor(pase_change,levels=c("Increase", "Persistently low", "Decrease", "Persistently high")))
+
+ if (drop.pase) {
+ data <- data |> dplyr::select(-tidyselect::all_of(c("pase_0_quartile", "pase_4_quartile", "pase_0", "pase_4")))
+ }
+
+
+ if (pase.rev) {
+ data <- data |> dplyr::mutate(
+ pase_change = factor(pase_change, levels = c("Persistently high", "Decrease", "Persistently low", "Increase"))
+ )
+ }
+
+ if (drop.nas) {
+ data <- data |>
+ dplyr::filter(!is.na(pase_change))
+ }
+
+
+ if ("mids" %in% data.classes) {
+ data |> mice::as.mids()
+ } else {
+ data
+ }
+}
+
+# as.Date(data$event_date.event)
+define_status_time <- function(data) {
+ data |> dplyr::mutate(dplyr::across(c("rdate", "enddate", "event_date.event"), ~ as.Date(.x)),
+ time = difftime(dplyr::if_else(is.na(event_date.event), date_cutter(), event_date.event), enddate) |> lubridate::time_length("years"),
+ status = as.integer(!is.na(event_event.type)),
+ time = dplyr::if_else(time > censor_cutter(), censor_cutter(), time),
+ status = dplyr::if_else(time > censor_cutter(), FALSE, status),
+ # status= dplyr::if_else(status,1,0),
+ event.include = time > 0
+ )
+}
+
+# as.integer(c(TRUE,FALSE))
+
+#' Grouping soc status
+#'
+#' @param data tibble
+#'
+#' @return tibble
+group_soc_status <- function(data) {
+ data |>
+ dplyr::mutate(
+ soc_status = factor(dplyr::case_when(
+ soc_status < 200 ~ "work",
+ soc_status == 200 ~ "off",
+ # only ~4 in the data set off work
+ soc_status >= 200 ~ "outside"
+ )),
+ soc_status_work = soc_status == "work",
+ soc_status_nowork = !soc_status_work
+ )
+}
+
+#' Correction of character NA
+#'
+#' @param data tibble
+#' @param char.missing character vector of entries to consider as NA
+#'
+#' @return tibble
+correct_na <- function(data, char.missing = "NA") {
+ data |> dplyr::mutate(dplyr::across(dplyr::where(is.character), ~ dplyr::na_if(.x, char.missing)))
+}
+
+#' Formatting the complete data set
+#'
+#' @param data the merged raw data set
+#'
+#' @return tibble
+#' @examples
+#' ds <- targets::tar_read(df_all_data) |>
+#' data_formatting() |>
+#' subset_df("mdi")
+#' ds |> skimr::skim()
+#' ds |> View()
+data_formatting <- function(data) {
+ to_logical <- grep(match_str_grepl(c("missings", "incompletes")), names(data))
+
+ suppressWarnings(
+ data |>
+ correct_na() |>
+ dplyr::mutate(dplyr::across(all_of(to_logical), ~ .x == "TRUE")) |>
+ dplyr::mutate(
+ # This uses the work-corrected score
+ # pase_0 = dplyr::if_else(pase_score_missings_w_0 | is.na(talos_pase10_0), NA, pase_score_sum_w_0),
+ # pase_4 = dplyr::if_else(pase_score_missings_w_4 | is.na(talos_pase10_4), NA, pase_score_sum_w_4),
+ # Below is the plain PASE scor used according to the manual used with TALOS
+ pase_0 = dplyr::if_else(pase_score_missings_0, NA,pase_score_sum_0),
+ pase_4 = dplyr::if_else(pase_score_missings_4, NA,pase_score_sum_4),
+ who_0 = as.numeric(talos_who07_0),
+ who_4 = as.numeric(talos_who07_4),
+ mrs_0 = factor(substr(talos_mrs01_0, 1, 1), ordered = FALSE),
+ mrs_0_above0 = (as.numeric(mrs_0) - 1) > 0,
+ mrs_4 = factor(substr(talos_mrs01_4, 1, 1), ordered = FALSE),
+ mrs_4_above1 = (as.numeric(mrs_4) - 1) > 1,
+ mdi_4 = as.numeric(talos_mdi12_4),
+ mfi_gen_4 = as.numeric(talos_mfi_gen_4),
+ nihss_0 = as.numeric(talos_nihss16_0),
+ soc_status = dst_SOC_STATUS_KODE.latest,
+ fam_indk = cut(dst_FAMAEKVIVADISP_13.5.mean,
+ breaks = quantile(dst_FAMAEKVIVADISP_13.5.mean, probs = seq(0, 1, 1 / 3), na.rm = TRUE),
+ ordered_results = FALSE,
+ labels = c("low", "medium", "high"),
+ include.lowest = TRUE
+ ),
+ fam_indk_bin = cut(dst_FAMAEKVIVADISP_13.5.mean,
+ breaks = quantile(dst_FAMAEKVIVADISP_13.5.mean, probs = seq(0, 1, 1 / 2), na.rm = TRUE),
+ ordered_results = FALSE,
+ labels = c("low", "high"),
+ include.lowest = TRUE
+ ),
+ fam_indk_hl=forcats::fct_rev(fam_indk),
+ fam_indk_high = dplyr::if_else(fam_indk_bin=="high",TRUE,FALSE),
+ fam_indk_low = dplyr::if_else(fam_indk_bin=="low",TRUE,FALSE),
+ edu_level = factor(dst_ISCED_lvl, ordered = FALSE, levels = c("low", "medium", "high")),
+ edu_high = dplyr::if_else(dst_ISCED_bin=="high",TRUE,FALSE),
+ edu_low = dplyr::if_else(dst_ISCED_lvl=="low",TRUE,FALSE),
+ edu_level_hl=forcats::fct_rev(edu_level),
+ rtreat_placebo=rtreat=="Placebo"
+ ) |>
+ group_soc_status() |>
+ define_status_time()
+ )
+}
+
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |>
+#' events_ready() |>
+#' View()
+events_ready <- function(data,v.groups=c("clin","lifestyle","ses", "assess.events")) {
+ data |>
+ get_vars(vars.groups = v.groups) |>
+ dplyr::filter(event.include) |>
+ dplyr::select(-tidyselect::all_of("event.include"))# |>
+ # labelling_data()
+}
+
+
+#' Title
+#'
+#' @param date
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted)
+#'
+#' data |>
+#' prediction_ready() |>
+#' View()
+prediction_ready <- function(data) {
+ data |>
+ get_vars(c("clin","lifestyle","ses", "assess.pred"))|>
+ dplyr::filter(!is.na(pase_0),!is.na(pase_4))#|>
+ # labelling_data()
+}
+
+## Data inspection and exploration
+##
+##
+#' Title
+#'
+#' @param data
+#' @param subdf
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data) |>
+#' subset_df() |>
+#' View()
+subset_df <- function(data, subdf = "pase") {
+ data[grepl(paste0("^(", paste("PNR", subdf, paste0("talos_", subdf), sep = "|"), ")"), names(data))]
+}
+
+#' Imputation as a function, includes "pragmatic imputation"
+#'
+#' @param data
+#' @param outcome.vars
+#' @param ignore
+#' @param pragmatic.reg
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted) |> events_ready()
+#' data |> labelling_data() |> fun_impute()
+fun_impute <- function(data, outcome.vars = c("status", "time"), ignore = NULL,pragmatic.reg=TRUE,pase.mod=FALSE) {
+ # data |> mice::md.pattern()
+ if (pragmatic.reg){
+ data <- data |> pragmatic_imputation()
+ }
+
+ ## Excluding entries with missing outcome measures
+ data <- data |>
+ dplyr::filter(!dplyr::if_any(tidyselect::all_of(c(outcome.vars)), ~ is.na(.x)))
+
+ init <- data |>
+ mice::mice(maxit = 0)
+
+ meth <- init$method
+ meth[ignore] <- ""
+
+ pred <- init$predictorMatrix
+ pred[, c(outcome.vars)] <- 0
+
+ # data_out <- data |> mice::futuremice(
+ # pred = pred,
+ # method = meth,
+ # print = FALSE,
+ # parallelseed = 8123,
+ # use.logical = FALSE,
+ # maxit = 20,
+ # m = 10
+ # )
+
+ data_out <- data |> mice::mice(
+ pred = pred,
+ method = meth,
+ print = FALSE,
+ seed = 8123,
+ maxit = 20,
+ m = 10
+ )
+
+ if (pase.mod){
+ data_out <- data_out |> pase_cutter_mids()
+ }
+
+ data_out
+
+ # lattice::densityplot(imp_data)
+ # Regarding EVENTS
+ #
+ # On inspection/eye-balling densityplots looks reasonable with the current settings
+ #
+}
+
+#' Function to cut PASE in mids object
+#'
+#' @param data mids object
+#'
+#' @return mids object
+#' @export
+#'
+pase_cutter_mids <- function(data){
+data |>
+ mice::complete(action = "long", include = TRUE) |>
+ pase_cutter(drop.pase = TRUE, drop.nas = TRUE)|>
+ mice::as.mids()
+ }
+
+
+#' Completes events data set, option to impute
+#'
+#' @param data
+#' @param impute
+#'
+#' @return mids or tibble
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> events_dataset() |>
+#' targets::tar_read(df_all_data_formatted) |>
+events_dataset <- function(data, impute = TRUE) {
+ data <- data |> events_ready()
+ if (impute) {
+ data |>
+ fun_impute(ignore = c("pase_0","pase_4"),pase.mod = TRUE)
+ } else {
+ data |>
+ dplyr::select(-tidyselect::all_of("reg_bmi")) |>
+ pase_cutter(drop.pase = TRUE,drop.nas = TRUE)
+ }
+}
+
+#' Title
+#'
+#' @param data
+#' @param all.vars
+#' @param outcome.var
+#' @param use.strata
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> events_ready() |> subset_df("pase")
+#' data <- targets::tar_read(df_all_data_formatted) |> events_dataset(FALSE)
+#' data |> cox_regression()
+cox_regression <- function(data, all.vars = TRUE,outcome.var="pase_change",use.strata=TRUE) {
+ if ("mids" %in% class(data)) {
+ nms <- names(data$data)
+ } else {
+ nms <- names(data)
+ data <- data |>
+ labelling_data()
+ # BMI meassure is excluded from non-imputed dataset
+ # data <- data |> dplyr::select(-tidyselect::all_of(c("reg_bmi")))
+ }
+
+ vars <- nms[!nms %in% c("time", "status", outcome.var)]
+
+ form.prefix <- "survival::Surv(time, status) ~"
+
+ if (use.strata) {
+ reg.form <- glue::glue("{form.prefix} strata({outcome.var})")
+ } else {
+ reg.form <- glue::glue("{form.prefix} {outcome.var}")
+ }
+
+ if (all.vars) reg.form <- paste0(reg.form, " + ", paste(vars, collapse = " + "))
+
+ require(survival)
+ out <- with(data, survival::coxph(
+ as.formula(reg.form)
+ ))
+
+ out$call$formula <- as.formula(reg.form)
+
+ out
+}
+
+
+#' Wrapper to print summary table with extended info
+#'
+#' @param data formatted and subset data set
+#' @param by.var stratify by
+#'
+#' @return
+#' @examples
+#' targets::tar_read(df_pred_data)|>print_table_summary(by="reg_female")
+print_table_summary <- function(data, by.var = "pase_change") {
+ data |>
+ labelling_data() |>
+ # pase_cutter(drop.pase = TRUE) |>
+ gtsummary::tbl_summary(
+ missing = "ifany",
+ by = tidyselect::all_of(by.var),
+ value = list(where(is.logical) ~ TRUE)#,
+ # type = list(gtsummary::all_continuous() ~ "continuous2"),
+ # statistic = list(gtsummary::all_continuous() ~ c(
+ # # "{N_nonmiss} ({p_nonmiss}%)",
+ # "{median} ({p25}, {p75})",
+ # # "{min}, {max}",
+ # "{mean} ({sd})"#,
+ # # "{N_miss} ({p_miss}%)"
+ # )#,
+ # gtsummary::all_categorical() ~ c(
+ # "{N_obs} ({p_nonmiss}%)"#,
+ # # "{N_miss} ({p_miss})"
+ # )
+ # )
+ ) |>
+ gtsummary::add_overall() |>
+ gtsummary::add_n() |>
+ gtsummary::add_p()
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted)
+#' targets::tar_read(df_all_data_formatted) |> events_tblone()
+events_tblone <- function(data) {
+ data |>
+ events_ready() |>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::select(-tidyselect::all_of(c("status", "time"))) |>
+ dplyr::filter(!is.na(pase_change)) |>
+ print_table_summary()
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> View()
+#' targets::tar_read(df_pred_data)|>
+#' dplyr::transmute(stRoke::quantile_cut(pase_0,4,group.names = 1:4),soc_status_work,fam_indk,edu_level) |>
+#' summary_tblone()
+summary_tblone <- function(data,by=names(data)[1]) {
+ # data <- targets::tar_read(df_pred_data)
+ data |>
+ labelling_data() |>
+ # prediction_ready() |>
+ # dplyr::select(-reg_bmi) |>
+ # pase_cutter(drop.pase = TRUE) |>
+ # dplyr::filter(!is.na(pase_change)) |>
+ # dplyr::mutate(pase_change=forcats::fct_rev(pase_change)) |>
+ print_table_summary(by.var = by)
+}
+
+#
+#' Summaries of DST data for PASE quartiles at 0 and 4
+#'
+#' @param data
+#' @param vars
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_pred_data) |> sum_pase_tables()
+sum_pase_tables <- function(data,vars=c("pase_0","pase_4")){
+ vars |> lapply(function(.x){
+ dplyr::tibble(stRoke::quantile_cut(data[[.x]],y=data[["pase_0"]],4,group.names = 1:4),
+ dplyr::select(data,soc_status_nowork,fam_indk_hl,edu_level_hl)) |>
+ summary_tblone()
+ })
+}
+
+
+#' Creating a truthful stratified table for predictions
+#'
+#' @param data data frame
+#'
+#' @return list
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_pred_data) |> true_pred_sum_plot()
+true_pred_sum_plot <- function(data){
+ true_sum <- data |>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::mutate(pase_change=forcats::fct_rev(pase_change))
+
+ list(true_sum,true_sum |> (function(.x){
+ split(.x,.x$pase_change %in% c("Persistently low","Increase"))
+ })() |> purrr::map(function(.y){.y |> dplyr::mutate(pase_change=factor(pase_change))})) |>
+ purrr::list_flatten() |> purrr::map(summary_tblone,by="pase_change") |>
+ gtsummary::tbl_merge()
+}
+
+#' Get quick summary of missing vs non-missing for each given variable
+#'
+#' @param data data set
+#' @param var variable to summarise over
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_pred_data) |> dplyr::select(soc_status_work,fam_indk,edu_level) |> who_is_missing()
+#' targets::tar_read(df_pred_data) |> who_is_missing(var="reg_bmi")
+who_is_missing <- function(data, var = "edu_level") {
+ data |>
+ dplyr::mutate(log = factor(c("non-missing","missing")[is.na(data[[var]])+1])) |>
+ dplyr::select(log, tidyselect::everything(),-tidyselect::all_of(var)) |>
+ summary_tblone() |> gtsummary::bold_p()
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> View()
+#' targets::tar_read(df_pred_data) |> preds_tblone()
+preds_tblone <- function(data) {
+ # data <- targets::tar_read(df_pred_data)
+ data |>
+ labelling_data() |>
+ # prediction_ready() |>
+ # dplyr::select(-reg_bmi) |>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::filter(!is.na(pase_change)) |>
+ dplyr::mutate(pase_change=forcats::fct_rev(pase_change)) |>
+ print_table_summary()
+}
+
+#' Title
+#'
+#' @param data
+#' @param b.cols
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' gt <- targets::tar_read(ls_pred_summary)[[1]]
+#' gt |> add_var_groups_gt()
+#'
+#' # For this to work, the function would need to handle labels and levels
+#' gt <- targets::tar_read(tbl_pred_summary)|> gtsummary::as_gt()
+#' gt |> add_var_groups_gt()
+add_var_groups_gt <- function(gt){
+ b.cols <- names(gt$`_data`)
+
+ if (b.cols[[1]]!="variable"){
+ # Flag to indicate if format is native gt or not. Simple assumption
+ # class(gt) gt is not enough
+ labels <- gt$`_data`[[1]]
+ group.var <- names(gt$`_data`[[1]])
+ } else {
+ labels <- gt$`_data`[["label"]][gt$`_data`[["row_type"]]=="label"]
+ group.var <- gt$`_data`[["variable"]]
+ }
+
+ groups <- matrix(ncol=length(labels)) |>
+ data.frame() |>
+ setNames(ifelse(labels=="","unknown_var",labels)) |>
+ tibble::tibble() |> groups_in_ds(labels = TRUE)
+
+ group.labels <- names(groups) |> subset_named_labels(labels.raw = group_labels())
+
+ labels.all <- group.labels |> purrr::imap(function(.x,.y){
+ c(.x,groups[[.y]][["label"]])
+ }) |> purrr::list_c()
+
+ for (i in rev(seq_along(group.labels))){
+ gt <- gt |> gt::tab_row_group(label=gt::md(glue::glue("*{group.labels[[i]]}*")),
+ rows=which(group.var %in% groups[[names(group.labels)[[i]]]][["var"]]))
+
+ }
+
+ gt
+}
+
+
+#' Title
+#'
+#' @param data
+#' @param b.cols
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' tbl <- targets::tar_read(ls_pred_summary)[[1]]
+add_var_groups_pre_calc <- function(data,b.cols){
+
+ groups <- data |> groups_in_ds()
+
+ group.labels <- names(groups) |> subset_named_labels(labels.raw = group_labels())
+
+ t0 <- data.frame(matrix(ncol=length(b.cols))) |>
+ setNames(b.cols) |>
+ tibble::tibble()
+ list(ext = group.labels |> purrr::imap(function(.x,.y){
+ t0 |> dplyr::mutate(
+ variable=.y,
+ val_label=.x,
+ row_type="group",
+ label=.x
+ )
+ }) |> dplyr::bind_rows(),
+ lvls = group.labels |> purrr::imap(function(.x,.y){
+ c(.y,groups[[.y]][["var"]])
+ }) |> purrr::list_c()
+ )
+}
+
+#' Adds variable grouping and formatting to gtsummary tables
+#'
+#' @param tbl
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#'
+#' tbl <- targets::tar_read(tbl_pred_summary)
+#' targets::tar_read(tbl_pred_summary) |> add_var_groups()
+#'
+add_var_groups <- function(tbl,
+ pre_ls=add_var_groups_pre_calc(tbl$inputs$data,
+ names(tbl$table_body))){
+
+
+ tbl |> gtsummary::modify_table_body(
+ ~.x |> dplyr::bind_rows(pre_ls[["ext"]]) |>
+ dplyr::arrange(factor(variable,levels=pre_ls[["lvls"]]))
+ ) |>
+ gtsummary::modify_table_styling(columns=label,
+ rows= row_type%in%"level",text_format = "indent2") |>
+ gtsummary::modify_table_styling(columns=label,rows= row_type%in%"label",text_format = "indent")|>
+ gtsummary::modify_table_styling(columns=label,rows= row_type%in%"group",text_format = c("italic"))
+}
+
+#' Functionalised character vector of all labels
+#'
+#' @return
+#' @export
+#'
+#' @examples
+var_labels <- function(){
+ c(
+ age = "Age",
+ reg_female = "Female sex",
+ reg_bmi = "Body mass index",
+ reg_smoker = "Current smoker",
+ reg_alone = "Living alone",
+ reg_more_alc = "High alcohol consumption",
+ reg_hyperten = "Hypertension",
+ reg_diabetes = "Diabetes",
+ reg_atriefli = "Atrial fibrillation",
+ reg_perifer_arteriel = "Peripheral arterial disease",
+ reg_tidl_tci = "Previous TIA",
+ reg_ami = "Previous MI",
+ reg_trombolyse = "Treated with IVT",
+ reg_trombektomi = "Treated with EVT",
+ # reg_any_perf,
+ # rtreat = "Study group allocation",
+ rtreat_placebo = "Placebo trial treatment",
+ pase_0 = "Pre-stroke PASE score",
+ pase_4 = "6 months post-stroke PASE score",
+ # pase_change,
+ nihss_0 = "Admission NIHSS",
+ # soc_status,
+ soc_status_work = "Employed",
+ soc_status_nowork = "Not employed",
+ fam_indk = "Family income group",
+ fam_indk_hl = "Lower family income",
+ fam_indk_high = "Higher family income",
+ fam_indk_low = "Lower family income",
+ edu_level = "Educational level group",
+ edu_level_hl = "Lower educational level",
+ edu_high = "Higher educational level",
+ edu_low = "Low educational level",
+ who_4 = "WHO-5 score 6 months post-stroke",
+ mdi_4 = "MDI score 6 months post-stroke",
+ mrs_4_above1 = "mRS > 1 at 6 months post-stroke",
+ mfi_gen_4 = "General fatigue (MFI domain) 6 months post-stroke",
+ time = "Time",
+ status = "Status",
+ event.include = "Include event",
+ who_0 = "Pre-stroke WHO-5 score",
+ mrs_0_above0 = "Pre-stroke mRS > 0",
+ pase_change = "PA change group"
+ )
+}
+
+
+group_labels <- function(data){
+ c("clin" = "Clinical data",
+ "lifestyle" = "Lifestyle and chronic diseases",
+ "ses" = "Socio-economic factors",
+ "assess.events" = "Assessments",
+ "assess.pred" = "Assessments",
+ "extra" = "extras")
+}
+
+rev_naming <- function(x){
+ setNames(names(x),x)
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_pred_data)
+groups_in_ds <- function(data, labels=FALSE){
+ groups <- define_variables() |> purrr::imap(function(.x,.y){
+ tibble::tibble(group=.y,var=.x)
+ }) |>
+ dplyr::bind_rows()
+
+ if (labels){
+ matching <- subset_named_labels(names(data),
+ rev_naming(var_labels()))
+ }else {
+ matching <- names(data)
+ }
+ groups[match(matching,groups[["var"]]),] |>
+ (\(.x){
+ .x |> dplyr::mutate(group=factor(group,levels=unique(.x[["group"]])))
+ })() |>
+ cbind(
+ tibble::tibble(
+ label=labelling_data(data) |> labelled::var_label() |> purrr::list_c()
+ )
+ )|>
+ (\(.x){
+ split(.x,.x[["group"]])
+ })()
+}
+
+
+#' Subset labels
+#'
+#' @param data
+#' @param labels.raw
+#'
+#' @return character vector
+#' @export
+#'
+subset_named_labels <- function(data,labels.raw){
+ labels.raw[match(data,names(labels.raw))]
+}
+
+#' Assign labels to data.frame or tibble
+#'
+#' @param data
+#' @param labels
+#'
+#' @return
+#' @export
+#'
+#' @examples
+assign_labels <- function(data,labels){
+ # data |> labelled::set_variable_labels(labels)
+
+ labelled::var_label(data) <- labels
+
+ data
+}
+
+#' Flexible labelling using labelled for nicer tables
+#'
+#' @param data data set
+#'
+#' @return
+#' @export labelled data.frame/tibble
+#'
+#' @examples
+#' data <- targets::tar_read(df_pred_data)
+#' data <- data |> dplyr::mutate(test="test")
+#' data |> labelling_data() |> labelled::var_label()
+labelling_data <- function(data,label.list=var_labels()){
+
+ labs <- subset_named_labels(names(data),label.list)
+ labs[is.na(labs)] <- names(data)[is.na(labs)]
+
+ data |> assign_labels(labels = labs)
+}
+
+
+
+#' Print regression table
+#'
+#' @param data cox regression ready data set
+#'
+#' @return gtsummary tbl_regression list object
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> show_table_regression()
+#' targets::tar_read(df_all_data_formatted) |> show_table_regression(use.mice=TRUE)
+show_table_regression <- function(data, use.mice=FALSE, by.var="pase_change") {
+ data |>
+ events_dataset(impute = use.mice) |>
+ cox_regression(all.vars = TRUE, use.strata = FALSE,outcome.var = by.var) |>
+ gtsummary::tbl_regression(exponentiate = TRUE, add_estimate_to_reference_rows = TRUE) |>
+ # gtsummary::add_n() |>
+ gtsummary::bold_p()
+}
+
+#' Splitting df to list by PA trajectory
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_pred_data) |> pred_ls_split()
+pred_ls_split <- function(data, excluded.vars = "reg_bmi"){
+ data |>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::group_split(pase_split = pase_change %in% c("Increase", "Persistently low")) |>
+ setNames(c("drop", "hop")) |>
+ purrr::map2(.y = c("Decrease", "Increase"), .f = \(x, y){
+ x |>
+ dplyr::mutate(pase_bin = pase_change == y) |>
+ dplyr::select(-tidyselect::all_of(c(excluded.vars, c("pase_change", "pase_split")))) |>
+ na.omit()
+ })
+}
+
+#' Run regularisation steps for split data set
+#'
+#' @param data selected data set
+#'
+#' @return list
+#'
+#' @examples
+#' data <- targets::tar_read(df_pred_data)
+#' targets::tar_read(df_pred_data) |> pred_models()
+pred_models <- function(data, excludes = "reg_bmi") {
+ ls <- data |>
+ pred_ls_split(excluded.vars = excludes) |>
+ purrr::map(regularisation_steps)
+
+ class(ls) <- c("regular_list", class(ls))
+ ls
+}
+
+cross_mean_median_exp_table <- function(data) {
+ nms <- paste0("v", seq_len(ncol(data)))
+
+ cross_calcs <- data |>
+ as.data.frame() |>
+ setNames(nms) |>
+ dplyr::rowwise() |>
+ dplyr::transmute(
+ median = median(dplyr::c_across(tidyselect::all_of(nms))),
+ medianOR = exp(median),
+ mean = mean(dplyr::c_across(tidyselect::all_of(nms))),
+ meanOR = exp(mean)
+ )
+
+ dplyr::tibble(names = rownames(data), cross_calcs) |>
+ dplyr::select(-tidyselect::all_of(c("mean","median")))
+}
+
+
+gather_coefs_step1 <- function(data) {
+ data |>
+ list3levelpluck(lvl1 = "model", lvl2 = "B") |>
+ purrr::map(purrr::reduce, cbind)
+}
+
+gather_coefs <- function(data) {
+ # imputed.list <- "mids_regular_list" %in% class(data)
+
+ if ("mids_regular_list" %in% class(data)) {
+ data_step1 <- data |>
+ purrr::map(gather_coefs_step1) |>
+ purrr::map(purrr::reduce, cbind)
+ } else if ("regular_list" %in% class(data)) {
+ data_step1 <- data |> gather_coefs_step1()
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data_step1 |>
+ purrr::map(cross_mean_median_exp_table) |>
+ purrr::reduce(dplyr::full_join, by = "names", suffix = paste0("_", names(data)))
+}
+
+
+#' Merge and print model coefficients. Pools datafrom mids analyses.
+#'
+#' @param data list
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(ls_pred_models)
+#' targets::tar_read(ls_pred_models) |> print_pred_coefs()
+#' targets::tar_read(ls_pred_mids_reg) |> print_pred_coefs() |> add_var_groups_gt()
+print_pred_coefs <- function(data) {
+ # data <- targets::tar_read(ls_pred_mids_reg)
+ # nms <- names(data)
+
+ if ("mids_regular_list" %in% class(data)) {
+ type.table <- "Pooled regularised models"
+ } else if ("regular_list" %in% class(data)) {
+ type.table <- "Single regularised model"
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ merged_tbl <- data |>
+ gather_coefs() |>
+ ## Leaving out the intercept
+ (function(.x) .x[-1,])()
+
+ sel_mean_med <- colnames(merged_tbl)[!grepl(pattern = "OR",colnames(merged_tbl))][-1]
+ sel_or <- colnames(merged_tbl)[grepl(pattern = "OR",colnames(merged_tbl))]
+
+ news <- subset_named_labels(merged_tbl$names,var_labels())
+
+ merged_tbl <- merged_tbl |> dplyr::mutate(names=dplyr::if_else(is.na(news),names,news))
+
+ gt_merged_tbl <- merged_tbl|>
+ gt::gt() |>
+ gt::fmt_number(decimals = 5)
+
+ merged_tbl_log <- merged_tbl |> dplyr::mutate(dplyr::across(tidyselect::all_of(sel_or), ~.x!=1),
+ dplyr::across(tidyselect::all_of(sel_mean_med), ~.x!=0))
+
+ for (j in colnames(merged_tbl)[-1]) {
+
+ i <- merged_tbl_log[[j]]
+
+ gt_merged_tbl <- gt_merged_tbl |> gt::tab_style(style = list(
+ gt::cell_text(weight="bold")
+ ),
+ locations = gt::cells_body(
+ columns=j,
+ rows = i
+ )
+ )}
+
+ for (i in names(data)) {
+ gt_merged_tbl <- gt_merged_tbl |>
+ gt::tab_spanner(label = i, columns = tidyselect::ends_with(i))
+ }
+
+ gt_merged_tbl |> gt::tab_spanner(
+ label = type.table,
+ columns = -1
+ )
+}
+
+#' Calculates confusionMatrix from contingency tables. Pools if object class is .
+#'
+#' @param data
+#'
+#' @return list
+#'
+#' @examples
+#' targets::tar_read(ls_pred_mids_reg) |> multi_table_cfm()
+#' targets::tar_read(ls_pred_models) |> multi_table_cfm()
+multi_table_cfm <- function(data) {
+ # data <- targets::tar_read(ls_pred_mids_reg)
+ if ("mids_regular_list" %in% class(data)) {
+ data <- data |> purrr::map(\(x){
+ x |>
+ # Test tables are plucked
+ # purrr::map(\(y) y |> purrr::pluck("model") |> purrr::pluck("cMatTest"))|>
+ list3levelpluck(lvl1 = "model", lvl2 = "cMatTest") |>
+ # All tables are add together
+ purrr::reduce(\(i, j) i + j)
+ })
+ } else if ("regular_list" %in% class(data)) {
+ data <- data |> list3levelpluck(lvl1 = "model", lvl2 = "cMatTest")
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data |>
+ purrr::map(caret::confusionMatrix)
+}
+
+#' Collect and summarise auc meassures. Pools if "mids_regular_list" object
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(ls_pred_mids_reg) |> multi_auc_summary()
+#' targets::tar_read(ls_pred_models) |> multi_auc_summary()
+multi_auc_summary <- function(data) {
+ if ("mids_regular_list" %in% class(data)) {
+ data_step <- data |> purrr::map(\(x){
+ x |>
+ # Test tables are plucked
+ list3levelpluck(lvl1 = "model", lvl2 = "auc_test") |>
+ # All tables are add together
+ purrr::reduce(c)
+ })
+ } else if ("regular_list" %in% class(data)) {
+ data_step <- data |>
+ list3levelpluck(lvl1 = "model", lvl2 = "auc_test") |>
+ purrr::map(c)
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data_step |>
+ purrr::map(summary)
+}
+
+#' Map and 2 level recursive purrr::pluck to ease regular_list subsetting
+#'
+#' @param data
+#' @param lvl1
+#' @param lvl2
+#'
+#' @return
+#' @export
+#'
+#' @examples
+list3levelpluck <- function(data, lvl1 = "model", lvl2 = "cMatTest") {
+ data |> purrr::map(\(y) y |>
+ purrr::pluck(lvl1) |>
+ purrr::pluck(lvl2))
+}
+
+#' Plot performance curve from glmnet regularisation
+#'
+#' @param data list of cvs.glmnet objects
+#'
+#' @return ggplot list object
+#' @export
+#'
+#' @examples
+plot_roc_curve <- function(data, title.text) {
+ ggplot2::ggplot() +
+ purrr::map(data, function(i) {
+ ggplot2::geom_step(data = i, ggplot2::aes(x = FPR, y = TPR))
+ }) +
+ ggplot2::coord_cartesian(xlim = c(0, 1), ylim = c(0, 1)) +
+ ggplot2::geom_abline() +
+ ggplot2::theme_bw() +
+ ggplot2::ggtitle(title.text)
+}
+
+roc_gather_step <- function(x) {
+ with(x, glmnet::roc.glmnet(cvs[[1]]$fit.preval, newy = y1)[match(bestL, lambdas)])
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(ls_pred_mids_reg) |> multi_roc_plot()
+#' targets::tar_read(ls_pred_models) |> multi_roc_plot()
+multi_roc_plot <- function(data) {
+ if ("mids_regular_list" %in% class(data)) {
+ data_step1 <- data |>
+ purrr::map(purrr::map, roc_gather_step) |>
+ purrr::map(purrr::list_flatten)
+ } else if ("regular_list" %in% class(data)) {
+ data_step1 <- data |> purrr::map(roc_gather_step)
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data_step1 |>
+ purrr::map2(.y = names(data), plot_roc_curve) |>
+ patchwork::wrap_plots()
+}
+
+#' Title
+#'
+#' @param tuning.param
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+multi_tuning_gather <- function(tuning.param = "bestA", data) {
+ if ("mids_regular_list" %in% class(data)) {
+ data_step1 <- data |>
+ purrr::map(purrr::map, \(x) x |> purrr::pluck(tuning.param)) |>
+ purrr::map(purrr::reduce, c)
+ } else if ("regular_list" %in% class(data)) {
+ data_step1 <- data |>
+ purrr::map(purrr::pluck, tuning.param)
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data_step1 |> purrr::map(summary)
+}
+
+
+#' Tidied tuning summary call
+#'
+#' @param data
+#'
+#' @return
+#'
+#' @examples
+#' targets::tar_read(ls_pred_mids_reg) |> tuning_summary()
+#' targets::tar_read(ls_pred_models) |> tuning_summary()
+tuning_summary <- function(data) {
+ c(ALPHA = "bestA", LAMBDA = "bestL") |> purrr::map(\(x) x |> multi_tuning_gather(data = data))
+}
+
+#' Apply regularisation steps to MIDS object, output arranged by grouping
+#'
+#' @param data mids object from mice package
+#'
+#' @return list
+#'
+#' @examples
+#' targets::tar_read(df_pred_mids) |> mids_regularisation()
+mids_regularisation <- function(data) {
+ ls <- data |>
+ mice::complete(action = "long") |>
+ dplyr::group_split(.imp) |>
+ purrr::modify(\(x){
+ x |> dplyr::select(-tidyselect::all_of(c(".imp", ".id")))
+ }) |>
+ purrr::map(pred_models)
+
+ nms <- ls |>
+ purrr::map(names) |>
+ unique() |>
+ purrr::reduce(c)
+
+ # As a consequence of the above code each "set" of analyses are together.
+ # Here the same group analyses are subset and grouped
+ ls_n <- purrr::map(nms, function(i) {
+ ls |> purrr::map(purrr::pluck, i)
+ }) |>
+ setNames(nms)
+
+ # Special class is applied to ease future handling
+ class(ls_n) <- c("mids_regular_list", class(ls_n))
+ ls_n
+}
+
+#' A collection of all the summary functions to be applied to list of
+#' pred_models() output
+#'
+#' @param data list of data
+#'
+#' @return list
+#' @export
+#'
+multi_summary <- function(data){
+ list( "coefTable" = print_pred_coefs(data) |> gt::fmt_number(n_sigfig = 4) |> add_var_groups_gt(),
+ "confusionMatrices" = multi_table_cfm(data),
+ "summaryAUC" = multi_auc_summary(data),
+ "rocPlots" = multi_roc_plot(data),
+ "tuningSummaries" = tuning_summary(data))
+}
+
+# funs <-list(
+# "coefTable" = print_pred_coefs,
+# "confusionMatrices" = multi_table_cfm,
+# "summaryAUC" = multi_auc_summary,
+# "rocPlots" = multi_roc_plot,
+# "tuningSummaries" = tuning_summary
+# )
+
+# multi_summary <- plyr::each(
+# "coefTable" = print_pred_coefs,
+# "confusionMatrices" = multi_table_cfm,
+# "summaryAUC" = multi_auc_summary,
+# "rocPlots" = multi_roc_plot,
+# "tuningSummaries" = tuning_summary
+# )
+
+#' Subset multiple elements from list
+#'
+#' @param data list
+#' @param indices numeric or character vector
+#'
+#' @return list
+#' @examples
+#' targets::tar_read(ls_pred_summary)$confusionMatrices |> purrr::map(list_subset)
+list_subset <- function(data,indices=c("overall","byClass")){
+ data[indices]
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(ls_pred_summary) |> print_model_resutls()
+print_model_resutls <- function(data){
+ par(mfrow=c(1,2))
+
+ list(data$coefTable,
+ invisible(data$confusionMatrices |> purrr::map(\(x) x |> purrr::pluck("table") |> fourfoldplot())),
+ data$confusionMatrices |> purrr::map(list_subset),
+ data$summaryAUC,
+ data$tuningSummaries
+ )
+}
+
+
+#' Classic logistic regression on prediction covariates
+#'
+#' @param data data frame
+#'
+#' @return
+#' @export
+#'
+#' @examples gtsummary list elemnt
+#' targets::tar_read(df_pred_data) |> pred_log_reg()
+#' targets::tar_read(df_pred_data) |> pred_ls_split()
+pred_log_reg <- function(data){
+ data |> pred_ls_split() |>
+ purrr::map(\(x) {
+ gtsummary::tbl_regression(glm(pase_bin~.,family = binomial,data = x),
+ exponentiate= TRUE)|>
+ gtsummary::bold_p()
+ }
+ ) |> (\(x){gtsummary::tbl_merge(tbls = x,
+ tab_spanner = names(x))})() }
+
+#' Classic linear regression on 6 months PASE score. Uni and multi.
+#'
+#' @param data data frame
+#'
+#' @return
+#' @export
+#'
+#' @examples gtsummary list elemnt
+#' data <- targets::tar_read(df_pred_data)
+#' data <- targets::tar_read(df_pred_mids)
+#' targets::tar_read(df_pred_data) |> pred_lin_reg()
+#' targets::tar_read(df_pred_mids) |> pred_lin_reg()
+pred_lin_reg <- function(data){
+
+ # list("tbl_regression-str:ref_row_text"="Reference") |>
+ # gtsummary::set_gtsummary_theme()
+
+ if ("mids" %in% class(data)){
+ cols <- names(data$data)
+
+ } else {
+ cols <- names(data)
+ data <- data |>
+ labelling_data()
+ }
+
+ vars <- cols[cols!="pase_4"]
+
+ formula_pase <- paste("pase_4",paste(vars,collapse = "+"),sep="~" )
+
+ # multi <- with(data=data,lm(pase_4~.)) |>
+ # gtsummary::tbl_regression(add_estimate_to_reference_rows = TRUE)|>
+ # gtsummary::bold_p() |> gtsummary::add_n()
+
+ if (!"mids" %in% class(data)){
+ ls <- list("Univariate"=data |>
+ gtsummary::tbl_uvregression(method=lm, show_single_row = dplyr::where(is.logical),
+ y=pase_4,
+ add_estimate_to_reference_rows = TRUE)|>
+ gtsummary::bold_p(),
+ "Multivariate (no BMI)"=lm(pase_4~.,data=dplyr::select(data,-reg_bmi)) |>
+ gtsummary::tbl_regression(add_estimate_to_reference_rows = TRUE, show_single_row = dplyr::where(is.logical))|>
+ gtsummary::bold_p() |> gtsummary::add_n(),
+ "Multivariate (ALL)"= lm(pase_4~.,data=data) |>
+ gtsummary::tbl_regression(add_estimate_to_reference_rows = TRUE, show_single_row = dplyr::where(is.logical))|>
+ gtsummary::bold_p() |> gtsummary::add_n()
+ )
+
+ } else {
+ ls <- list("Multivariate (ALL)"= suppressWarnings(mice::lm.mids(pase_4~.,data=data) |>
+ gtsummary::tbl_regression(add_estimate_to_reference_rows = TRUE, show_single_row = dplyr::where(is.logical))|>
+ gtsummary::bold_p() |> gtsummary::add_n()))
+ }
+
+ ls |> (\(x){gtsummary::tbl_merge(tbls = x,
+ tab_spanner = names(x))})()
+}
+
+#' Simple standard plot
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> events_dataset(impute = FALSE)|> cox_regression() |> plot_survival()
+plot_survival <- function(data){
+ data |>
+ ggsurvfit::survfit2() |>
+ ggsurvfit::ggsurvfit(linetype_aes = TRUE, size = 0.8) +
+ ggsurvfit::add_confidence_interval() +
+ ggsurvfit::add_risktable(
+ risktable_stats = c("n.risk", "cum.event"),
+ stats_label = list(cum.event = "Cumulative Observed Events",
+ n.risk = "Number at Risk"),
+ theme =
+ list(
+ ggsurvfit::theme_risktable_default(axis.text.y.size = 11,
+ plot.title.size = 11),
+ ggplot2::theme(plot.title = ggplot2::element_text(face = "bold"))
+ )
+ ) +
+ ggplot2::scale_y_continuous(
+ limits = c(0, 1),
+ labels = scales::percent,
+ expand = c(0.01, 0)
+ ) +
+ ggplot2::scale_x_continuous(breaks = 0:9, expand = c(0.02, 0))
+}
+
+
+#' Smooth tidy survfit object
+#'
+#' @param data survfit object
+#'
+#' @return tibble
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted) |> events_dataset(impute = FALSE)|> cox_regression()
+#' data |> ggsurvfit::survfit2(robust=TRUE) |>
+#' ggsurvfit::tidy_survfit(type="survival") |>
+#' dplyr::group_split(strata) |>
+#' purrr::map(smooth_col)
+smooth_col <- function(data){
+ smoothed <- lapply(c("estimate","conf.high","conf.low"),function(i){
+ stats::predict(mgcv::gam(data=data,formula = as.formula(glue::glue("{i}~s(time,bs='cs')")))) |>
+ as.data.frame()|>
+ setNames(glue::glue("{i}_smooth"))
+ }) |> purrr::list_cbind()
+
+ dplyr::tibble(data,
+ smoothed)
+
+}
+
+#' Prepare cox regression for smooth survival plot
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> events_dataset(impute = FALSE)|> cox_regression() |> smooth_cox_data()
+smooth_cox_data <- function(data){
+ data |>
+ ggsurvfit::survfit2(robust=TRUE) |>
+ ggsurvfit::tidy_survfit(type="survival") |>
+ dplyr::group_split(strata) |>
+ purrr::map(smooth_col) |>
+ purrr::list_rbind()
+}
+
+#' Plot smooth survival plot
+#'
+#' @param data df from cox regression
+#'
+#' @return ggplot list object
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted) |> events_dataset(impute = FALSE)|> cox_regression(use.strata=TRUE)
+#' data |> plot_survival_smooth()
+plot_survival_smooth <- function(data){
+ if ("mira" %in% class(data)) stop("Only plots non-imputed survival data")
+
+ n.level <- length(data$xlevels[[1]])
+
+ # data |>
+ # ggsurvfit::survfit2() |>
+ # ggsurvfit::tidy_survfit()
+
+ if (data |> ggsurvfit::survfit2() |> purrr::pluck("n") |> length() ==1 ){
+ ds <- data |>
+ ggsurvfit::survfit2() |>
+ ggsurvfit::tidy_survfit()
+ p <- ds |>
+ ggplot2::ggplot(ggplot2::aes(x=time, y=estimate))+
+ ggplot2::geom_smooth(se=TRUE, method="loess", formula = "y~x", linewidth=2, color="grey10")
+ # Added auto max for y axis removed again to ensure same y axis
+ # max_y <- max(ds$conf.high)
+
+ } else {
+ ds <- data |>
+ smooth_cox_data()
+ p <- ds |>
+ ggplot2::ggplot()+
+ ggplot2::geom_line(ggplot2::aes(x=time, y=estimate_smooth, color=strata, linetype=strata), linewidth=2)+
+ ggplot2::geom_ribbon(ggplot2::aes(x=time, ymin=conf.low_smooth,ymax=conf.high_smooth, fill=strata), alpha=.2)
+ # Added auto max for y axis removed again to ensure same y axis
+ # max_y <- max(ds$conf.high_smooth)
+
+ }
+ p+
+ ggplot2::scale_y_continuous(limits = c(0,1.02),
+ breaks = seq(0,1,.25),
+ labels = scales::percent,
+ expand = c(0.01, 0)
+ ) +
+ ggplot2::scale_x_continuous(breaks = 0:9, expand = c(0.02, 0))+
+ ggplot2::scale_fill_manual(values=viridisLite::turbo(n=n.level,direction = 1))+
+ ggplot2::scale_color_manual(values=viridisLite::turbo(n=n.level,direction = 1))+
+ ggplot2::theme_minimal()+
+ ggplot2::theme(axis.title.x = ggplot2::element_blank(),
+ axis.title.y = ggplot2::element_blank(),
+ # axis.text = ggplot2::element_blank(),
+ # legend.position = "none",
+ panel.grid.minor.y = ggplot2::element_blank(),
+ panel.grid.major.y = ggplot2::element_line(color="grey45",linewidth = 1))
+
+}
+
+cluster_rank <- function(data){
+ data |> cox_regression(outcome.var = "clust",use.strata = TRUE) |> ggsurvfit::survfit2(robust=TRUE) |>
+ ggsurvfit::tidy_survfit(type="survival") |>
+ dplyr::group_split(strata) |>
+ purrr::map(\(x){
+ min(x[["estimate"]])
+ }) |> purrr::list_c() |> rank() |> rev()
+}
+
+cox_relevel <- function(data){
+ data |> dplyr::mutate(clust=factor(clust,levels=cluster_rank(data)))
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted)
+complete_preds_data <- function(data){
+ data |> events_ready() |>
+ fun_impute(ignore = c("pase_0","pase_4"),pase.mod = FALSE) |>
+ mice::complete() |>
+ dplyr::filter((!is.na(pase_0)&!is.na(pase_4)))
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> add_kamila_cluster()
+#' data_kam <- targets::tar_read(df_all_data_formatted) |> add_kamila_cluster()
+#' data_kam |>print_table_summary(by.var = "kam_grp")
+#' data_kam |> cox_regression(outcome.var="kam_grp")|> plot_survival_smooth()
+#' data_kam |> cox_regression(outcome.var="kam_grp",use.strata = FALSE)|> gtsummary::tbl_regression(exponentiate = TRUE, add_estimate_to_reference_rows = TRUE) |> gtsummary::bold_p()
+#' targets::tar_read(df_events_complete) |> kamila_cluster(n.clusters=3)
+kamila_cluster <- function(data, n.clusters=3,include.out=FALSE){
+ # An index number could be added to later join pack. Of input a complete data set from imputation and pooling??
+ data_orig <- data
+
+
+ if (!include.out){
+ data <- data |>
+ dplyr::select(-tidyselect::one_of(c("time","status")))
+ }
+
+
+ catInd <- data |> lapply(\(x) is.character(x)|is.logical(x)) |> purrr::list_c()
+ conInd <- data |> lapply(\(x) is.numeric(x)|is.integer(x)) |> purrr::list_c()
+
+ catVars <- data[,catInd]
+ catVars <- catVars |> lapply(factor) |> dplyr::bind_cols() |> as.data.frame()
+ conVars <- data[,conInd] |> scale()|> as.data.frame()
+
+ if (is.null(n.clusters)){
+ out <- kamila::kamila(conVar = conVars, catFactor = catVars, numClust = 2:7, numInit = 10,
+ calcNumClust = "ps"
+ )
+ }else {
+ out <- kamila::kamila(conVar = conVars, catFactor = catVars, numClust = n.clusters, numInit = 10)
+ }
+
+ ls <- list("out"=out,"data_orig"=data_orig)
+
+ class(ls) <- c("kamila_cluster",class(ls))
+
+ ls
+
+}
+
+
+#' VarSelLCM wrapper
+#'
+#' @param data complete dataset with no missings
+#' @param n.clusters number of clusters (if length 1, n is fixed, in n>1 given clusters are tested)
+#' @param include.out flag to include outcome variables or not
+#' @param memb.out output data frame with final membership or not (then outputs standard model output)
+#'
+#' @return list with VarSelLCM output and original dataset with cluster appended
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' data |> lcm_cluster()
+lcm_cluster <- function(data, n.clusters=3, include.out=FALSE, var.sel=FALSE){
+ data_orig <- data
+
+ if (!include.out){
+ data <- data |>
+ dplyr::select(-c("time", "status"))
+ }
+
+
+ set.seed(5432)
+
+ out <- data |>
+ dplyr::mutate(dplyr::across(where(is.logical)|where(is.character),~factor(.x))) |>
+ as.data.frame() |>
+ VarSelLCM::VarSelCluster(
+ gvals=n.clusters,
+ crit.varsel="BIC",
+ vbleSelec = var.sel,
+ nbcores = round(parallel::detectCores()*.8)
+ )
+
+ ls <- list("out"=out,"data_orig"=data_orig)
+
+ class(ls) <- c("lcm_cluster",class(ls))
+
+ ls
+
+}
+
+#' Kmeans clustering
+#'
+#' @param data
+#' @param n.clusters
+#' @param include.out
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' data |> kmeans_cluster()
+#' data |> kmeans_cluster(n.clusters=3)
+kmeans_cluster <- function(data, n.clusters=3, include.out=FALSE, memb.out=TRUE){
+ data_orig <- data
+
+ if (!include.out){
+ data <- data |>
+ dplyr::select(!tidyselect::one_of(c("time", "status")))
+ }
+
+ out <- data |>
+ dplyr::mutate(dplyr::across(where(is.double),~scale(.x)),
+ dplyr::across(where(is.logical)|where(is.character),~factor(.x)),
+ dplyr::across(where(is.factor),~as.numeric(.x))) |>
+ stats::kmeans(
+ centers=n.clusters
+ )
+
+ ls <- list("out"=out,"data_orig"=data_orig)
+
+ class(ls) <- c("kmeans_cluster",class(ls))
+
+ ls
+
+}
+
+#' dbscan clustering
+#'
+#' @param data
+#' @param n.clusters
+#' @param include.out
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' data |> dbscan_cluster()
+#' data |> dbscan_cluster(n.clusters=3)
+dbscan_cluster <- function(data, n.clusters=3, include.out=FALSE, memb.out=TRUE){
+ data_orig <- data
+
+ if (!include.out){
+ data <- data |>
+ dplyr::select(!tidyselect::one_of(c("time", "status")))
+ }
+
+ data <- data |> na.omit() |> dplyr::mutate(rtreat=rtreat!="Placebo",
+ dplyr::across(dplyr::everything(), as.numeric))
+
+
+ ## This plot indicates that eps should be set around 60, but at this value everything is one cluster.
+ dbscan::kNNdistplot(data,k = 5)
+
+ ## Performing hierachical clustering, it is clear, that the algorithm is not able to seperate clusters.
+ hds <- dbscan::hdbscan(data,minPts = 5)
+
+ plot(hds,show_flat = TRUE)
+
+ ## Clustering with set eps value and minPts
+ ds <- dbscan::dbscan(data,eps = 25,minPts = 2)
+
+ ds[["cluster"]]
+
+ ## dbscan is not an interesting approach, apparently
+
+ #
+ #
+ #
+ #
+ # out <- data |>
+ # dplyr::mutate(dplyr::across(where(is.double),~scale(.x)),
+ # dplyr::across(where(is.logical)|where(is.character),~factor(.x)),
+ # dplyr::across(where(is.factor),~as.numeric(.x))) |>
+ # stats::kmeans(
+ # centers=n.clusters
+ # )
+ #
+ # ls <- list("out"=out,"data_orig"=data_orig)
+ #
+ # class(ls) <- c("kmeans_cluster",class(ls))
+ #
+ # ls
+
+}
+
+#' Title
+#'
+#' @param ls
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' ls <- data |> lcm_cluster()
+#' ls |> final_membership()
+final_membership <- function(ls){
+ cls <- class(ls)
+ if ("kamila_cluster" %in% cls) {
+
+ tibble::tibble(clust=factor(ls$out$finalMemb),
+ ls$data_orig)
+
+ } else if ("lcm_cluster" %in% cls) {
+
+ tibble::tibble(clust=factor(ls$out@partitions@zMAP),
+ ls$data_orig)
+
+ } else if ("kmeans_cluster" %in% cls) {
+
+ tibble::tibble(clust=factor(ls$out$cluster),
+ ls$data_orig)
+
+ } else stop("Class not recognised")
+
+}
+
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' data |> get_clusters()
+#' data |> get_clusters(n.cl=2:7)
+get_clusters <- function(data,n.cl=4,rm.out=TRUE){
+ set.seed(1123)
+
+ if (length(n.cl)>1){
+ list(
+ # "kmeans"=data |> kmeans_cluster(n.clusters = n.cl,include.out = !rm.out),
+ "lcm"= data |> lcm_cluster(n.clusters = n.cl,include.out = !rm.out),
+ "kamila"=data |> kamila_cluster(n.clusters = n.cl,include.out = !rm.out)
+ )
+ } else {
+ list(
+ "kmeans"=data |> kmeans_cluster(n.clusters = n.cl,include.out = !rm.out),
+ "lcm"= data |> lcm_cluster(n.clusters = n.cl,include.out = !rm.out),
+ "kamila"=data |> kamila_cluster(n.clusters = n.cl,include.out = !rm.out)
+ )
+ }
+
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(list_pred_clusters)
+#' data |> final_clusters()
+final_clusters <- function(data,new.levels=NULL){
+ out <- data |> lapply(final_membership) |> lapply(labelling_data)
+
+ if (is.null(new.levels)){
+ out
+ } else {
+ out |>
+ purrr::map2(relevels,function(x,y){
+ # x$clust <- factor(factor(x$clust,levels=y),labels=1:4)
+ x$clust <- factor(x$clust,levels=y)
+ x #|>
+ # dplyr::filter(clust %in% range(as.numeric(clust))) |>
+ # dplyr::mutate(clust=factor(clust))
+ })
+ }
+
+ }
+
+
+
+#' Title
+#'
+#' @param data
+#' @param by
+#'
+#' @return
+#' @export
+#'
+#' @examples
+merged_summary_tbl <- function(data,by="clust"){
+ data |>
+ purrr::map(function(x){
+ x |>
+ # print_table_summary(by.var = by)
+ gtsummary::tbl_summary(by=by) |>
+ gtsummary::add_p() |> gtsummary::bold_p()
+ }
+ ) |> (\(x){
+ x |> gtsummary::tbl_merge(tab_spanner = names(x))
+ })()
+}
+
+#' Easy cox regression tbl for uniform results
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+cox2tbl <- function(data,by="clust"){
+data|> cox_regression(outcome.var = by,use.strata = FALSE,all.vars = FALSE) |>
+ gtsummary::tbl_regression(exponentiate =TRUE) |> gtsummary::bold_p()
+}
+
+#' Title
+#'
+#' @param data
+#' @param by
+#'
+#' @return
+#' @export
+#'
+#' @examples
+merged_cox_reg_tbl <- function(data,by="clust"){
+ data |>
+ purrr::map(function(x){
+ x |> cox2tbl(by=by)
+ }
+ ) |> (\(x){
+ x |> gtsummary::tbl_merge(tab_spanner = names(x))
+ })()
+}
+
+#' Title
+#'
+#' @param data
+#' @param by
+#'
+#' @return
+#' @export
+#'
+#' @examples
+wrapped_surv_plot <- function(data,by="clust"){
+data |>
+ purrr::map(function(x){
+ x |> cox_regression(outcome.var = by,use.strata = TRUE,all.vars = FALSE) |>
+ plot_survival_smooth()+ggplot2::labs(color="Cluster",fill="Cluster",linetype="Cluster")
+ }
+ ) |> (\(x){
+ x |> patchwork::wrap_plots(ncol=1) + patchwork::plot_annotation(tag_levels = list(names(x)))
+ })()
+}
+
+
+# Ranking by most events
+relevel_by_rank <- function(data){
+ ## Assigning clusters to each dataset
+data <- targets::tar_read(list_pred_clusters) |>
+ final_clusters(new.levels = NULL)
+
+## Calculating cox regressions and ranking by the final point on the survival plot
+relevels <- data |>
+ purrr::map(function(x){
+ x |> cox_regression(outcome.var = "clust",use.strata = TRUE,all.vars = FALSE) |>
+ ggsurvfit::survfit2() |>
+ ggsurvfit::tidy_survfit() |>
+ (\(x){
+ split(x,x[["strata"]]) |>
+ purrr::map(function(.y){
+ .y[["estimate"]][nrow(.y)]
+ })
+ })() |> purrr::reduce(c) |> rank()
+ }
+ )
+
+#3 Assigning the new, ranked levels
+targets::tar_read(list_pred_clusters) |>
+ final_clusters(new.levels = relevels)
+}
+
+## TODO
+## Verify definitions
+## Do remaining documentation of functions
+##
+##
+## How does elastic net work with imputed dataset?
+## Functionalise to allow for imputed and non-imputed (both analyses) - in both cases with and without BMI - include department of inclusion to investigate reason of missing BMI data
+##
+## tidymodels does not allow pmm in mice. Thy're out!
diff --git a/1 PA Decline/Fra DDV/functions240418.R b/1 PA Decline/Fra DDV/functions240418.R
new file mode 100644
index 0000000..b9a1267
--- /dev/null
+++ b/1 PA Decline/Fra DDV/functions240418.R
@@ -0,0 +1,2688 @@
+# pop <- haven::read_sas(here::here("E:/rawdata/709203/Population/pop_talos.sas7bdat"))
+
+# sst <- list.files(here::here("E:/rawdata/709203/Eksterne data"), pattern = "*.sas7bdat", full.names = TRUE) |>
+# purrr::map(haven::read_sas)
+
+
+
+#' Read all sas files in folder to list
+#'
+#' @param path folder path
+#'
+#' @return list
+sas2list <- function(path) {
+ ls <- list.files(here::here(path), pattern = "*.sas7bdat", full.names = TRUE) |>
+ purrr::map(haven::read_sas)
+ names(ls) <- list.files(here::here(path), pattern = "*.sas7bdat") |>
+ gsub(".sas7bdat", "", x = _) |>
+ toupper()
+ ls
+}
+
+
+#' Flatten multilevel list
+#'
+#' @param paths character vector of folder paths
+#'
+#' @return flattened list
+flatmultiread <- function(paths) {
+ paths |>
+ purrr::map(sas2list) |>
+ purrr::list_flatten()
+}
+
+# ls <- targets::tar_read(reg_data)
+
+# Vectors are kept for compatibility. Calling functions can be done from within other functions. So much easier!
+
+date_cutter <- function() as.Date("2023-01-01")
+date.cut <- date_cutter() # The earliest date will define the overall date cut
+
+censor_cutter <- function() 8.5
+censor.cut <- censor_cutter() # years of maximum follow up, due to small numbers
+
+vasc.diags <- c("I21", "I61", "I63", "I64", "G45", "K28")
+
+#' Extract deaths from Dødsårsagsregiseret
+#'
+#' @param ls
+#' @param max.date
+#' @param diags.vasc
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(reg_data) |> get_deaths()
+get_deaths <- function(ls, max.date = date.cut, diags.vasc = vasc.diags) {
+
+
+ # vasc.death.tilg <- mapply(ls$DAR_T_DODSAARSAG_2[, "C_DODTILGRUNDL_ACME"],
+ # FUN = function(i) { # mapply inside apply call to handle rowvise matching in in matrix
+ # i_3 <- substr(i, 1, 3) # Substr only the 3 first characters to match by group
+ # i_3 %in% diags.vasc # Rowvise matching
+ # }
+ # )
+
+ vasc.death.tilg <- ls$DAR_T_DODSAARSAG_2[["C_DODTILGRUNDL_ACME"]] |> substr(1, 3) %in% diags.vasc
+
+
+ vasc.death.any <- apply(mapply(ls$DAR_T_DODSAARSAG_2[, c("C_DODTILGRUNDL_ACME", "C_DOD_1A", "C_DOD_1B", "C_DOD_1C", "C_DOD_1D")],
+ FUN = function(i) { # mapply inside apply call to handle rowvise matching in in matrix
+ i_3 <- substr(i, 1, 3) # Substr only the 3 first characters to match by group
+ i_3 %in% diags.vasc # Rowvise matching
+ }
+ ), 1, any) # Simplify to TRUE if any
+ #
+ vasc.death.other <- apply(mapply(ls$DAR_T_DODSAARSAG_2[, c("C_DOD_1A", "C_DOD_1B", "C_DOD_1C", "C_DOD_1D")],
+ FUN = function(i) { # mapply inside apply call to handle rowvise matching in in matrix
+ i_3 <- substr(i, 1, 3) # Substr only the 3 first characters to match by group
+ i_3 %in% diags.vasc # Rowvise matching
+ }
+ ), 1, any) # Simplify to TRUE if any
+
+ diag.either <- xor(vasc.death.other, vasc.death.tilg)
+ diag.both <- vasc.death.other & vasc.death.tilg
+
+ vasc.death.diags <-
+ apply(
+ mapply(
+ ls$DAR_T_DODSAARSAG_2[, c(
+ "C_DODTILGRUNDL_ACME",
+ "C_DOD_1A",
+ "C_DOD_1B",
+ "C_DOD_1C",
+ "C_DOD_1D"
+ )],
+ FUN = function(i) {
+ # mapply inside apply call to handle rowvise matching in in matrix
+ substr(i, 1, 3) # Substr only the 3 first characters to match by group
+ }
+ ),
+ 1,
+ paste,
+ collapse = ","
+ )
+
+ deaths.vasc <-
+ ls$DAR_T_DODSAARSAG_2 |>
+ dplyr::select(K_CPR, D_STATDATO) |>
+ dplyr::filter(vasc.death.tilg)
+
+ df.death.all <- ls$CPR3_T_PERSON |>
+ dplyr::filter(C_STATUS == 90) |> # People migrating are filtered (n ~ 1)
+ dplyr::select(c(
+ "V_PNR",
+ "D_STATUS_HEN_START"
+ )) |>
+ dplyr::left_join(deaths.vasc, by = c("V_PNR" = "K_CPR")) |>
+ dplyr::mutate(vasc_death = !is.na(D_STATDATO)) |>
+ dplyr::transmute(
+ PNR = V_PNR,
+ death_date = D_STATUS_HEN_START,
+ vasc_death = vasc_death
+ )
+
+ df.death.all |> dplyr::filter(death_date < max.date)
+}
+
+
+#' Title
+#'
+#' @param ls
+#' @param max.date
+#' @param diags.vasc
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' ls <- targets::tar_read(reg_list)
+get_events <- function(ls, max.date = date.cut, diags.vasc = vasc.diags) {
+ ident.vars <- toupper(c("_recnum", "_cpr"))
+
+ df.vasc.events.lpr <- ls$LPR_T_DIAG |>
+ dplyr::mutate(dia.f = substr(C_DIAG, 2, 4)) |> # Subsets only 2:4 chars, to get main group
+ dplyr::filter(
+ dia.f %in% diags.vasc
+ # & # Filters to only include pre-defined diagnoses
+ # C_DIAGTYPE=="A"
+ ) |> # Filters to only include if main diagnosis
+ dplyr::select(
+ ends_with(ident.vars),
+ "C_DIAG",
+ "C_DIAGTYPE"
+ ) |>
+ dplyr::left_join(
+ ls$LPR_T_ADM |> dplyr::select(
+ tidyselect::ends_with(ident.vars),
+ "D_INDDTO",
+ "C_INDM",
+ "D_UDDTO",
+ "C_UDM",
+ "C_SGH",
+ "C_AFD",
+ "C_ADIAG"
+ ),
+ by = c("V_RECNUM" = "K_RECNUM")
+ )
+
+ ## LPR-F - LPR 3
+
+ ident.vars.lpr3 <- toupper(c("cpr", "_kontakt", "DW_EK_FORLOEB"))
+
+ df.vasc.events.lpr3 <- ls$LPR_F_DIAGNOSER |>
+ dplyr::mutate(dia.f = substr(DIAGNOSEKODE, 2, 4)) |> # Subsets only 2:4 chars, to get main group
+ dplyr::filter(
+ dia.f %in% diags.vasc
+ # & # Filters to only include pre-defined diagnoses
+ # DIAGNOSETYPE=="A"
+ ) |> # Filters to only include if main diagnosis
+ dplyr::select(
+ ends_with(ident.vars.lpr3),
+ "DIAGNOSEKODE",
+ "DIAGNOSETYPE"
+ ) |>
+ dplyr::left_join(
+ ls$LPR_F_KONTAKTER |> dplyr::select(
+ ends_with(ident.vars.lpr3),
+ "DATO_START",
+ "DATO_SLUT",
+ "PRIORITET"
+ ),
+ by = c("DW_EK_KONTAKT")
+ ) |>
+ dplyr::mutate(PRIORITET = as.character((PRIORITET == "ATA1") + 1)) # If ATA1 then 1, if not (ATA3) then 2, cowboy coding
+
+ df.vasc.events <- dplyr::full_join(df.vasc.events.lpr, df.vasc.events.lpr3, by = c(
+ "V_CPR" = "CPR",
+ "C_DIAG" = "DIAGNOSEKODE",
+ "C_DIAGTYPE" = "DIAGNOSETYPE",
+ "D_INDDTO" = "DATO_START",
+ "D_UDDTO" = "DATO_SLUT",
+ "C_INDM" = "PRIORITET"
+ )) |>
+ dplyr::mutate(date.event = D_INDDTO)
+
+ df.vasc.events |> dplyr::filter(date.event < max.date)
+}
+
+
+# deaths <- targets::tar_read(df_deaths)
+# events <- targets::tar_read(df_events)
+# clinical <- targets::tar_read(pop_df)
+
+
+#' Filter only truly considered events
+#'
+#' @param data
+#'
+#' @return tibble
+define_events <- function(data) {
+ data |> dplyr::filter(
+ C_DIAGTYPE == "A", # Primary diagnosis
+ C_INDM == "1", # Acutely admitted
+ difftime(date.event, rdate, units = "days") > 5 # More than five (5) days after randomisation/primary stroke
+ )
+}
+
+#' The big merger and filter of events
+#'
+#' @param ls list of events, deaths and clinical
+#'
+#' @return tibble
+merge_events <- function(ls) {
+ df.events <- dplyr::full_join(
+ purrr::pluck(ls, "events"),
+ purrr::pluck(ls, "deaths") |>
+ dplyr::mutate(
+ # These are just added to ease later filtering
+ C_DIAGTYPE = "A",
+ C_INDM = "1"
+ ), # Ads diagtype=A, C_INDM=1 for easier sorting later
+ by = c(
+ "V_CPR" = "PNR",
+ "date.event" = "death_date",
+ "C_DIAGTYPE",
+ "C_INDM"
+ )
+ ) |>
+ dplyr::full_join(dplyr::select(purrr::pluck(ls, "clinical"), c("PNR", "rdate", "enddate")),
+ by = c("V_CPR" = "PNR")
+ ) |>
+ dplyr::arrange(date.event) |> # Sort by event date
+ dplyr::mutate(event.type = dplyr::if_else(
+ is.na(C_DIAG),
+ dplyr::if_else(vasc_death, "death.vasc", "death.other"),
+ substr(C_DIAG, 1, 4)
+ ))
+
+ df.events |>
+ dplyr::group_split(V_CPR) |> # Splits by CPR
+ purrr::map(define_events) |> # Custom function to specify criteria for events
+ purrr::discard(\(x) nrow(x) == 0) |> # Discard empty elements
+ purrr::modify(\(x) x[1, ]) |> # Select first event
+ purrr::list_rbind() |>
+ dplyr::transmute(
+ CPR = V_CPR,
+ date.event,
+ event.type
+ )
+}
+
+
+
+
+#' Count number of prescriptions of given ATC group for each CPR
+#'
+#' @param atc.code atc group
+#' @param data dataset from LMS
+#'
+#' @return tibble
+count_treat <- function(atc.code, data) {
+ data |>
+ dplyr::filter(grepl(atc.code, ATC)) |>
+ dplyr::count(CPR) |>
+ dplyr::filter(n > 1)
+}
+
+
+#' Get LMS data
+#'
+#' @param ls list of datasets
+#' @param max.date filter date for max inclusion
+#' @param atc.tbl tibble of atc codes
+#'
+#' @return tibble
+get_lms <- function(ls, max.date, atc.tbl) {
+ ls$LMS_EPIKUR |>
+ dplyr::filter(grepl(atc.tbl[1], ATC)) |>
+ dplyr::left_join(ls$LMS_LAEGEMIDDELOPLYSNINGER) |>
+ dplyr::filter(as.Date(ACTDATE) < max.date)
+}
+
+#' Get count of treated patients from LMS data
+#'
+#' @param ls list of datasets
+#' @param max.date filter date for max inclusion
+#' @param atc.tbl tibble of atc codes
+#'
+#' @return tibble
+get_treated <- function(ls,
+ max.date = date.cut,
+ atc.tbl = c(
+ atc.antidep = "N06A",
+ atc.ssri = "N06AB"
+ )) {
+ df <- atc.tbl |>
+ purrr::map(count_treat, get_lms(ls, max.date, atc.tbl)) |>
+ purrr::reduce(dplyr::full_join, by = "CPR")
+ colnames(df) <- c("CPR", paste0("n.", names(atc.tbl)))
+ df
+}
+
+#' BMI calc, drops
+#'
+#' @param w weight in kg
+#' @param h height in cm
+#' @param data data set
+#'
+#' @return tibble
+bmi_calc <- function(data, drop = TRUE) {
+ # After inspection, both h+w are missing if any is missing
+ out <- data |> dplyr::mutate(reg_bmi = suppressWarnings(as.numeric(dplyr::if_else(reg_vaegt == "NA", reg_vaegt_anslaaet, reg_vaegt)) / ((as.numeric(reg_hojde) / 100)^2)))
+
+ if (drop) {
+ out <- out |>
+ dplyr::select(-dplyr::all_of(c("reg_vaegt", "reg_vaegt_anslaaet", "reg_hojde")))
+ }
+ out
+}
+
+is_equal <- function(data, test) {
+ data == test
+}
+
+#' Load clinical population data
+#'
+#' @return tibble
+#' @examples
+#' get_clinical() |> colnames()
+#'
+get_clinical <- function() {
+ sas2list("E:/rawdata/709203/Population")[[2]] |>
+ correct_na() |>
+ dplyr::mutate(
+ reg_smoker = dplyr::case_match(
+ reg_rygning, "1" ~ TRUE,
+ c("2", "3", "4") ~ FALSE,
+ "9" ~ NA
+ ),
+ # Living alone defined as not together with somebody
+ reg_alone = dplyr::case_match(
+ reg_civil, "1" ~ FALSE,
+ c("2", "3") ~ TRUE,
+ "9" ~ NA
+ ),
+ reg_more_alc = dplyr::case_match(
+ reg_alkohol, "1" ~ FALSE,
+ "2" ~ TRUE,
+ "9" ~ NA
+ ),
+ reg_female = sex == "Kvinde",
+ dplyr::across(
+ .cols = c(
+ "reg_hyperten",
+ "reg_diabetes",
+ "reg_atriefli",
+ "reg_perifer_arteriel",
+ "reg_tidl_tci",
+ "reg_ami"
+ ),
+ ~ dplyr::case_match(
+ .x, "1" ~ TRUE,
+ "2" ~ FALSE,
+ "9" ~ NA
+ )
+ ),
+ dplyr::across(
+ .cols = c(
+ "reg_trombolyse",
+ "reg_trombektomi"
+ ),
+ ~ dplyr::case_match(
+ .x, "1" ~ TRUE,
+ c("3","4") ~ FALSE,
+ "9" ~ NA
+ )
+ ),
+ reg_any_perf = reg_trombolyse | reg_trombektomi
+ ) |>
+ bmi_calc()
+}
+
+# get_clinical() |> pragmatic_imputation() |> skimr::skim()
+
+# get_clinical <- function() {
+# sas2list("E:/rawdata/709203/Population")[[2]] |>
+# dplyr::mutate(
+# reg_smoker = reg_rygning == 1,
+# reg_cohabiting = reg_civil == 1,
+# reg_more_alc = reg_alkohol == 2,
+# reg_female = sex == "Kvinde",
+# dplyr::across(.cols = c("reg_hyperten", "reg_diabetes", "reg_atriefli", "reg_perifer_arteriel", "reg_tidl_tci", "reg_ami", "reg_trombolyse", "reg_trombektomi"), ~ .x == 1),
+# reg_any_perf = reg_trombolyse | reg_trombektomi
+# ) |>
+# bmi_calc()
+# }
+
+pragmatic_imputation <- function(data, vec=c("reg_smoker","reg_cohabiting","reg_more_alc","reg_hyperten", "reg_diabetes", "reg_atriefli", "reg_perifer_arteriel", "reg_tidl_tci", "reg_ami", "reg_trombolyse", "reg_trombektomi","reg_any_perf")) {
+ # Assumes, if not TRUE, then FALSE (gets rid of NAs)
+ data |> dplyr::mutate(dplyr::across(.cols = tidyselect::any_of(vec), ~dplyr::if_else(.x,TRUE,FALSE,missing = FALSE)))
+}
+
+#' Load all registry tables to list
+#'
+#' @return list
+get_reg_ls <- function() {
+ flatmultiread(c("E:/rawdata/709203/Eksterne data", "E:/rawdata/709203/Grunddata"))
+}
+
+
+#' Definition of relevant variables from DST tables
+#'
+#' @return
+define_dst_vars <- function() {
+ list(
+ bef = c("PNR", "FAMILIE_ID"),
+ faik = c("FAMILIE_ID", "FAMAEKVIVADISP_13", "FAMSOCIOGRUP_13"),
+ ras = c("PNR", "SOC_STATUS_KODE"),
+ uddf = c("PNR", "HFAUDD")
+ )
+}
+
+#' Simple wrapper of dplyr::select
+#'
+#' @param data
+#' @param vars
+#'
+#' @return
+select_vars <- function(data, vars) {
+ data |> dplyr::select({{ vars }})
+}
+
+#' Subset DST tables to only include relvant variables.
+#'
+#' @param ls List of all registry tables
+#'
+#' @return
+get_dst_tables <- function(ls) {
+ dst_vars <- define_dst_vars()
+ dst_tbl <- toupper(names(dst_vars))
+ ls.all <- purrr::map(seq_along(dst_vars), function(i) {
+ ls.reg <- ls[grepl(paste0("^", dst_tbl[i]), names(ls))] |> purrr::map(select_vars, vars = dst_vars[[i]])
+ names(ls.reg) <- paste0("y", stringr::str_extract(names(ls.reg), "[0-9]{4}"))
+ ls.reg
+ })
+ names(ls.all) <- dst_tbl
+ ls.all
+}
+
+#' Wrapper to generate string matching pattern for stringr::str_detect()
+#'
+#' @param data
+#'
+#' @return
+match_str <- function(data) {
+ paste0("[", paste0(data, collapse = ","), "]")
+}
+
+#' Wrapper to generate string matching pattern for grepl()
+#'
+#' @param data character vector
+#'
+#' @return
+match_str_grepl <- function(data) {
+ paste0("(", paste0(data, collapse = "|"), ")")
+}
+
+# get_dst_tables(ls)
+
+#' Generate sequence of previous N length
+#'
+#' @param data numeric vector of length 1
+#'
+#' @return
+#'
+#' @examples
+#' last5y(10)
+#' last5y(c(10, 6, 3))
+lastNy <- function(data, n = 5) {
+ paste0("y", seq((data - n), data) - 1)
+}
+
+#' Filter PNR (cpr) across list elements
+#'
+#' @param data list of tibbles to pass through
+#' @param index index number (PNR/CPR)
+#'
+#' @return tibble
+filterCPRacross <- function(data, index) {
+ data |>
+ purrr::map(function(i) {
+ i[i$PNR == index, ]
+ }) |>
+ purrr::list_rbind()
+}
+
+#' Summarise data from last 5 years prior to inclusion
+#'
+#' @param data list with
+#' @param v.median variables to get median
+#' @param v.latest variables to get latest
+#' @param v.mean variables to get mean
+#'
+#' @return tibble
+previousNyears <- function(data, data.clin, n.years = 5, v.median = NULL, v.latest = c("FAMSOCIOGRUP_13", "SOC_STATUS_KODE"), v.mean = c("FAMAEKVIVADISP_13")) {
+ df.cpryear <- data.clin |> dplyr::transmute(
+ CPR = PNR,
+ year = as.numeric(format(as.Date(rdate), "%Y"))
+ )
+
+ seqs <- purrr::map(df.cpryear$year, lastNy, n = n.years)
+
+ seq_along(seqs) |>
+ purrr::map(function(i) {
+ df <- data[c(seqs[[i]])] |>
+ filterCPRacross(index = df.cpryear$CPR[i]) |>
+ dplyr::group_by(PNR) |>
+ dplyr::summarise(
+ dplyr::across(tidyselect::any_of(v.latest), \(x) tail(x, n = 1), .names = "{.col}.latest"),
+ dplyr::across(tidyselect::any_of(v.mean), \(x) mean(x, na.rm = TRUE), .names = "{.col}.{n.years}.mean"),
+ dplyr::across(tidyselect::any_of(v.median), \(x) median(x, na.rm = TRUE), .names = "{.col}.{n.years}.median")
+ )
+ }) |>
+ purrr::list_rbind()
+}
+
+
+#' Extract relevant and summarised data from BAF and FAIK
+#'
+#' @param data list of dst data tables
+#'
+#' @return tibble
+#'
+#' @examples
+#' get_reg_ls() |>
+#' get_dst_tables() |>
+#' get_beffaikras()
+get_beffaikras <- function(data, clin.data = get_clinical()) {
+ data <- data[stringr::str_detect(match_str(c("BEF", "FAIK", "RAS")), names(data))] |> purrr::list_flatten()
+
+ years <- stringr::str_extract(names(data), "y[0-9]{4}")
+
+ years[duplicated(years)] |>
+ purrr::map(grep, years) |>
+ purrr::map(function(i) {
+ data[c(i)] |> purrr::reduce(dplyr::full_join)
+ }) |>
+ purrr::set_names(years[duplicated(years)]) |>
+ previousNyears(data.clin = clin.data)
+
+ ## BEF
+ ## # Befolkningsoversigt. Data skal bruges for at kunne udtrække husstandsindkomst.
+ ## FAIK
+ ## # Familieindkomst. Familie id skal flættes med ID fra BEF for hvert år for at tage hensyn til evt skifte i status.
+ ## FAMAEKVIVADISP_13 er relevante variabel for ækvivaleret indkomst
+ ## Der findes også familiesocioøkonomisk status. Gør som Sine. Be done with it!
+}
+
+#' Title
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- read_edu_level()
+#' data |> dplyr::count(ISCED)
+read_edu_level <- function() {
+ haven::read_dta("E:/Formater/SAS formater i Danmarks Statistik/STATA_datasaet/Disced/c_audd_level_l1l4_k.dta") |>
+ dplyr::transmute(
+ HFAUDD = start,
+ ISCED = AUDD_LEVEL_L1L4_K
+ )
+}
+
+# haven::read_dta(
+# "E:/Formater/SAS formater i Danmarks Statistik/STATA_datasaet/Disced/c_audd_level_l1l3_k.dta") |>
+# dplyr::count(AUDD_LEVEL_L1L3_K)
+
+# ls <- get_reg_ls() |> get_dst_tables()
+
+get_uddf <- function(ls) {
+ ls |>
+ purrr::pluck("UDDF") |>
+ purrr::pluck(1) |>
+ dplyr::mutate(HFAUDD = as.character(HFAUDD)) |>
+ dplyr::left_join(read_edu_level()) |>
+ dplyr::group_by(PNR) |>
+ dplyr::summarise(ISCED = max(ISCED), .groups = "keep") |>
+ dplyr::mutate(
+ ISCED = as.numeric(ISCED),
+ ISCED_lvl = dplyr::case_match(ISCED, 0:2 ~ "low",
+ 3:4 ~ "medium",
+ 5:9 ~ "high",
+ .default = NA
+ ),
+ ISCED_bin = dplyr::case_match(ISCED, 0:3 ~ "low",
+ 4:9 ~ "high",
+ .default = NA
+ )
+ )
+}
+
+
+#' Collects all relevant variables from DST tables
+#'
+#' @param ls list of all registry tables
+#' @param df.clin clinical data set
+#'
+#' @return tibble
+#' @examples
+#' get_reg_ls() |> get_dst(df.clin = get_clinical())
+get_dst <- function(ls, df.clin) {
+ ls_dst <- get_dst_tables(ls)
+ ls_dst |>
+ ## BEFxFAIKxRAS
+ get_beffaikras(clin.data = df.clin) |>
+ dplyr::full_join(
+ ## UDDF
+ get_uddf(ls_dst)
+ )
+}
+
+#' Eases pipe renaming of columns
+#'
+#' @param data tibble, list or other object, for which names() makes sense. see ?setNames
+#' @param prefix prefix to add
+#' @param exclude names not to modify
+#' @param new.names character vector of all new names
+#'
+#' @return object of same class as data
+#'
+#' @examples
+#' set_colnames(data = mtcars, prefix = "WOW", exclude = "mpg")
+set_colnames <- function(data, new.names = NULL, prefix = NULL, exclude = c("PNR", "CPR"), prefix.sep = "_") {
+ if (is.null(new.names)) {
+ nms <- names(data)
+ } else {
+ nms <- new.names
+ }
+
+ if (is.null(prefix)) {
+ nms.mod <- nms
+ } else {
+ nms.mod <- paste(prefix, nms, sep = prefix.sep)
+ }
+
+ setNames(
+ object = data,
+ nm = dplyr::if_else(stringr::str_detect(match_str(exclude), nms),
+ nms,
+ nms.mod
+ )
+ )
+}
+
+
+#' Store of variable names for data sub-setting
+#'
+#' @return list
+#' @examples
+#' define_variables()
+define_variables <- function() {
+ list(
+ clin = c(
+ "age",
+ "reg_female",
+ "nihss_0",
+ "reg_trombolyse",
+ "reg_trombektomi",
+ # "rtreat",
+ "rtreat_placebo"),
+ lifestyle=c(
+ "pase_0",
+ "pase_4",
+ "reg_alone",
+ "reg_bmi",
+ # "reg_hojde",
+ # "reg_vaegt_alt",
+ "reg_smoker",
+ "reg_more_alc",
+ "reg_hyperten",
+ "reg_diabetes",
+ "reg_tidl_tci",
+ "reg_atriefli",
+ "reg_ami",
+ "reg_perifer_arteriel"),
+ ses=c(
+ # "soc_status",
+ # "soc_status_work",
+ "soc_status_nowork",
+ # "fam_indk",
+ "fam_indk_hl",
+ # "fam_indk_high",
+ # "fam_indk_low",
+ # "edu_level",
+ # "edu_high",
+ # "edu_low",
+ "edu_level_hl"
+ ),
+ assess.events = c(
+ "who_4",
+ "mdi_4",
+ "mrs_4_above1",
+ "mfi_gen_4",
+ "time",
+ "status",
+ "event.include"
+ ),
+ assess.pred = c(
+ "who_0",
+ "mrs_0_above0"
+ ),
+ extra = c(
+ "soc_status",
+ "pase_0",
+ "pase_4"
+ )
+ )
+}
+
+#' Get var names in vector from group names. Possibility to keep all vars for as log as possible. Can be supplied to `gtsummary` functions
+#'
+#' @param groups vector of group names. See names(define_variables()) for options
+#'
+#' @return
+#' @export
+#'
+#' @examples
+get_var_vec <- function(v.groups){
+ define_variables()[{{ v.groups }}] |> purrr::list_c()
+}
+
+#' SUbsets dataset based on variable group names as defined
+#'
+#' @param vector character vector of category names
+#'
+#' @return character vector
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> get_vars(c("universal", "events"))
+get_vars <- function(data, vars.groups) {
+ data |> dplyr::select(tidyselect::all_of(get_var_vec(vars.groups)))
+}
+
+
+
+#' Collect all relevant data for the events analysis data set
+#'
+#' @param ls ls of tibbles
+#'
+#' @return tibble
+collectall <- function(ls) {
+ purrr::pluck(ls, "clinical") |>
+ dplyr::left_join(purrr::pluck(ls, "all_events") |> set_colnames(prefix = "event"), by = c("PNR" = "CPR")) |>
+ dplyr::left_join(purrr::pluck(ls, "dst") |> set_colnames(prefix = "dst"), by = "PNR")
+}
+
+
+## Formatting for analysis
+
+#' Function to cut and group PASE data
+#'
+#' @param data data set including pase_0 and _4
+#'
+#' @return tibble
+pase_cutter <- function(data, pase.rev = TRUE, drop.pase = FALSE, drop.nas=FALSE) {
+ data.classes <- class(data)
+ if ("mids" %in% data.classes) {
+ data <- data |> mice::complete(action = "long", include = TRUE)
+ }
+
+ data <- data |>
+ dplyr::mutate(dplyr::across(.cols = c("pase_0", "pase_4"), \(i) {
+ cut(x = i, breaks = quantile(pase_0, na.rm = TRUE), labels = 1:4, include.lowest = TRUE)
+ }, .names = "{.col}_quartile")) |>
+ dplyr::mutate(pase_change = factor(dplyr::case_when(
+ pase_0_quartile == 1 & pase_4_quartile == 1 ~ "Low-low",
+ pase_0_quartile %in% 2:4 &
+ pase_4_quartile %in% 2:4 ~ "High-high",
+ pase_0_quartile == 1 &
+ pase_4_quartile %in% 2:4 ~ "Increase",
+ pase_0_quartile %in% 2:4 &
+ pase_4_quartile == 1 ~ "Decrease"
+ ), ordered = FALSE),
+ pase_change=factor(pase_change,levels=c("Increase", "Low-low", "Decrease", "High-high")))
+
+ if (drop.pase) {
+ data <- data |> dplyr::select(-tidyselect::all_of(c("pase_0_quartile", "pase_4_quartile", "pase_0", "pase_4")))
+ }
+
+
+ if (pase.rev) {
+ data <- data |> dplyr::mutate(
+ pase_change = factor(pase_change, levels = c("High-high", "Decrease", "Low-low", "Increase"))
+ )
+ }
+
+ if (drop.nas) {
+ data <- data |>
+ dplyr::filter(!is.na(pase_change))
+ }
+
+
+ if ("mids" %in% data.classes) {
+ data |> mice::as.mids()
+ } else {
+ data
+ }
+}
+
+# as.Date(data$event_date.event)
+define_status_time <- function(data) {
+ data |> dplyr::mutate(dplyr::across(c("rdate", "enddate", "event_date.event"), ~ as.Date(.x)),
+ time = difftime(dplyr::if_else(is.na(event_date.event), date_cutter(), event_date.event), enddate) |> lubridate::time_length("years"),
+ status = as.integer(!is.na(event_event.type)),
+ time = dplyr::if_else(time > censor_cutter(), censor_cutter(), time),
+ status = dplyr::if_else(time > censor_cutter(), FALSE, status),
+ # status= dplyr::if_else(status,1,0),
+ event.include = time > 0
+ )
+}
+
+# as.integer(c(TRUE,FALSE))
+
+#' Grouping soc status
+#'
+#' @param data tibble
+#'
+#' @return tibble
+group_soc_status <- function(data) {
+ data |>
+ dplyr::mutate(
+ soc_status = factor(dplyr::case_when(
+ soc_status < 200 ~ "work",
+ soc_status == 200 ~ "off",
+ # only ~4 in the data set off work
+ soc_status >= 200 ~ "outside"
+ )),
+ soc_status_work = soc_status == "work",
+ soc_status_nowork = !soc_status_work
+ )
+}
+
+#' Correction of character NA
+#'
+#' @param data tibble
+#' @param char.missing character vector of entries to consider as NA
+#'
+#' @return tibble
+correct_na <- function(data, char.missing = "NA") {
+ data |> dplyr::mutate(dplyr::across(dplyr::where(is.character), ~ dplyr::na_if(.x, char.missing)))
+}
+
+#' Formatting the complete data set
+#'
+#' @param data the merged raw data set
+#'
+#' @return tibble
+#' @examples
+#' ds <- targets::tar_read(df_all_data) |>
+#' data_formatting() |>
+#' subset_df("mdi")
+#' ds |> skimr::skim()
+#' ds |> View()
+data_formatting <- function(data) {
+ to_logical <- grep(match_str_grepl(c("missings", "incompletes")), names(data))
+
+ suppressWarnings(
+ data |>
+ correct_na() |>
+ dplyr::mutate(dplyr::across(all_of(to_logical), ~ .x == "TRUE")) |>
+ dplyr::mutate(
+ # This uses the work-corrected score
+ # pase_0 = dplyr::if_else(pase_score_missings_w_0 | is.na(talos_pase10_0), NA, pase_score_sum_w_0),
+ # pase_4 = dplyr::if_else(pase_score_missings_w_4 | is.na(talos_pase10_4), NA, pase_score_sum_w_4),
+ # Below is the plain PASE scor used according to the manual used with TALOS
+ pase_0 = dplyr::if_else(pase_score_missings_0, NA,pase_score_sum_0),
+ pase_4 = dplyr::if_else(pase_score_missings_4, NA,pase_score_sum_4),
+ who_0 = as.numeric(talos_who07_0),
+ who_4 = as.numeric(talos_who07_4),
+ mrs_0 = factor(substr(talos_mrs01_0, 1, 1), ordered = FALSE),
+ mrs_0_above0 = (as.numeric(mrs_0) - 1) > 0,
+ mrs_4 = factor(substr(talos_mrs01_4, 1, 1), ordered = FALSE),
+ mrs_4_above1 = (as.numeric(mrs_4) - 1) > 1,
+ mdi_4 = as.numeric(talos_mdi12_4),
+ mfi_gen_4 = as.numeric(talos_mfi_gen_4),
+ nihss_0 = as.numeric(talos_nihss16_0),
+ soc_status = dst_SOC_STATUS_KODE.latest,
+ fam_indk = cut(dst_FAMAEKVIVADISP_13.5.mean,
+ breaks = quantile(dst_FAMAEKVIVADISP_13.5.mean, probs = seq(0, 1, 1 / 3), na.rm = TRUE),
+ ordered_results = FALSE,
+ labels = c("low", "medium", "high"),
+ include.lowest = TRUE
+ ),
+ fam_indk_bin = cut(dst_FAMAEKVIVADISP_13.5.mean,
+ breaks = quantile(dst_FAMAEKVIVADISP_13.5.mean, probs = seq(0, 1, 1 / 2), na.rm = TRUE),
+ ordered_results = FALSE,
+ labels = c("low", "high"),
+ include.lowest = TRUE
+ ),
+ fam_indk_hl=forcats::fct_rev(fam_indk),
+ fam_indk_high = dplyr::if_else(fam_indk_bin=="high",TRUE,FALSE),
+ fam_indk_low = dplyr::if_else(fam_indk_bin=="low",TRUE,FALSE),
+ edu_level = factor(dst_ISCED_lvl, ordered = FALSE, levels = c("low", "medium", "high")),
+ edu_high = dplyr::if_else(dst_ISCED_bin=="high",TRUE,FALSE),
+ edu_low = dplyr::if_else(dst_ISCED_lvl=="low",TRUE,FALSE),
+ edu_level_hl=forcats::fct_rev(edu_level),
+ rtreat_placebo=rtreat=="Placebo"
+ ) |>
+ group_soc_status() |>
+ define_status_time()
+ )
+}
+
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |>
+#' events_ready() |>
+#' View()
+events_ready <- function(data,v.groups=c("clin","lifestyle","ses", "assess.events")) {
+ data |>
+ get_vars(vars.groups = v.groups) |>
+ dplyr::filter(event.include) |>
+ dplyr::select(-tidyselect::all_of("event.include"))# |>
+ # labelling_data()
+}
+
+
+#' Title
+#'
+#' @param date
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted)
+#'
+#' data |>
+#' prediction_ready() |>
+#' View()
+prediction_ready <- function(data) {
+ data |>
+ get_vars(c("clin","lifestyle","ses", "assess.pred"))|>
+ dplyr::filter(!is.na(pase_0),!is.na(pase_4))#|>
+ # labelling_data()
+}
+
+## Data inspection and exploration
+##
+##
+#' Title
+#'
+#' @param data
+#' @param subdf
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data) |>
+#' subset_df() |>
+#' View()
+subset_df <- function(data, subdf = "pase") {
+ data[grepl(paste0("^(", paste("PNR", subdf, paste0("talos_", subdf), sep = "|"), ")"), names(data))]
+}
+
+#' Imputation as a function, includes "pragmatic imputation"
+#'
+#' @param data
+#' @param outcome.vars
+#' @param ignore
+#' @param pragmatic.reg
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted) |> events_ready()
+#' data |> labelling_data() |> fun_impute()
+fun_impute <- function(data, outcome.vars = c("status", "time"), ignore = NULL,pragmatic.reg=TRUE,pase.mod=FALSE) {
+ # data |> mice::md.pattern()
+ if (pragmatic.reg){
+ data <- data |> pragmatic_imputation()
+ }
+
+ ## Excluding entries with missing outcome measures
+ data <- data |>
+ dplyr::filter(!dplyr::if_any(tidyselect::all_of(c(outcome.vars)), ~ is.na(.x)))
+
+ init <- data |>
+ mice::mice(maxit = 0)
+
+ meth <- init$method
+ meth[ignore] <- ""
+
+ pred <- init$predictorMatrix
+ pred[, c(outcome.vars)] <- 0
+
+ # data_out <- data |> mice::futuremice(
+ # pred = pred,
+ # method = meth,
+ # print = FALSE,
+ # parallelseed = 8123,
+ # use.logical = FALSE,
+ # maxit = 20,
+ # m = 10
+ # )
+
+ data_out <- data |> mice::mice(
+ pred = pred,
+ method = meth,
+ print = FALSE,
+ seed = 8123,
+ maxit = 20,
+ m = 10
+ )
+
+ if (pase.mod){
+ data_out <- data_out |> pase_cutter_mids()
+ }
+
+ data_out
+
+ # lattice::densityplot(imp_data)
+ # Regarding EVENTS
+ #
+ # On inspection/eye-balling densityplots looks reasonable with the current settings
+ #
+}
+
+#' Function to cut PASE in mids object
+#'
+#' @param data mids object
+#'
+#' @return mids object
+#' @export
+#'
+pase_cutter_mids <- function(data){
+data |>
+ mice::complete(action = "long", include = TRUE) |>
+ pase_cutter(drop.pase = TRUE, drop.nas = TRUE)|>
+ mice::as.mids()
+ }
+
+
+#' Completes events data set, option to impute
+#'
+#' @param data
+#' @param impute
+#'
+#' @return mids or tibble
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> events_dataset() |>
+#' targets::tar_read(df_all_data_formatted) |>
+events_dataset <- function(data, impute = TRUE) {
+ data <- data |> events_ready()
+ if (impute) {
+ data |>
+ fun_impute(ignore = c("pase_0","pase_4"),pase.mod = TRUE)
+ } else {
+ data |>
+ dplyr::select(-tidyselect::all_of("reg_bmi")) |>
+ pase_cutter(drop.pase = TRUE,drop.nas = TRUE)
+ }
+}
+
+#' Title
+#'
+#' @param data
+#' @param all.vars
+#' @param outcome.var
+#' @param use.strata
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> events_ready() |> subset_df("pase")
+#' data <- targets::tar_read(df_all_data_formatted) |> events_dataset(FALSE)
+#' data |> cox_regression()
+cox_regression <- function(data, all.vars = TRUE,outcome.var="pase_change",use.strata=TRUE) {
+ if ("mids" %in% class(data)) {
+ nms <- names(data$data)
+ } else {
+ nms <- names(data)
+ data <- data |>
+ labelling_data()
+ # BMI meassure is excluded from non-imputed dataset
+ # data <- data |> dplyr::select(-tidyselect::all_of(c("reg_bmi")))
+ }
+
+ vars <- nms[!nms %in% c("time", "status", outcome.var)]
+
+ form.prefix <- "survival::Surv(time, status) ~"
+
+ if (use.strata) {
+ reg.form <- glue::glue("{form.prefix} strata({outcome.var})")
+ } else {
+ reg.form <- glue::glue("{form.prefix} {outcome.var}")
+ }
+
+ if (all.vars) reg.form <- paste0(reg.form, " + ", paste(vars, collapse = " + "))
+
+ require(survival)
+ out <- with(data, survival::coxph(
+ as.formula(reg.form)
+ ))
+
+ out$call$formula <- as.formula(reg.form)
+
+ out
+}
+
+
+#' Wrapper to print summary table with extended info
+#'
+#' @param data formatted and subset data set
+#' @param by.var stratify by
+#'
+#' @return
+#' @examples
+#' targets::tar_read(df_pred_data)|>print_table_summary(by="reg_female")
+print_table_summary <- function(data, by.var = "pase_change") {
+ data |>
+ labelling_data() |>
+ # pase_cutter(drop.pase = TRUE) |>
+ gtsummary::tbl_summary(
+ missing = "no",
+ by = tidyselect::all_of(by.var),
+ value = list(where(is.logical) ~ TRUE),
+ type = list(gtsummary::all_continuous() ~ "continuous2"),
+ statistic = list(gtsummary::all_continuous() ~ c(
+ # "{N_nonmiss} ({p_nonmiss}%)",
+ "{median} ({p25}, {p75})",
+ # "{min}, {max}",
+ "{mean} ({sd})"#,
+ # "{N_miss} ({p_miss}%)"
+ )#,
+ # gtsummary::all_categorical() ~ c(
+ # "{N_obs} ({p_nonmiss}%)"#,
+ # # "{N_miss} ({p_miss})"
+ # )
+ )
+ ) |>
+ gtsummary::add_overall() |>
+ gtsummary::add_n() #|>
+ # gtsummary::add_p()
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted)
+#' targets::tar_read(df_all_data_formatted) |> events_tblone()
+events_tblone <- function(data) {
+ data |>
+ events_ready() |>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::select(-tidyselect::all_of(c("status", "time"))) |>
+ dplyr::filter(!is.na(pase_change)) |>
+ print_table_summary()
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> View()
+#' targets::tar_read(df_pred_data)|>
+#' dplyr::transmute(stRoke::quantile_cut(pase_0,4,group.names = 1:4),soc_status_work,fam_indk,edu_level) |>
+#' summary_tblone()
+summary_tblone <- function(data,by=names(data)[1]) {
+ # data <- targets::tar_read(df_pred_data)
+ data |>
+ labelling_data() |>
+ # prediction_ready() |>
+ # dplyr::select(-reg_bmi) |>
+ # pase_cutter(drop.pase = TRUE) |>
+ # dplyr::filter(!is.na(pase_change)) |>
+ # dplyr::mutate(pase_change=forcats::fct_rev(pase_change)) |>
+ print_table_summary(by.var = by)
+}
+
+#
+#' Summaries of DST data for PASE quartiles at 0 and 4
+#'
+#' @param data
+#' @param vars
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_pred_data) |> sum_pase_tables()
+sum_pase_tables <- function(data,vars=c("pase_0","pase_4")){
+ vars |> lapply(function(.x){
+ dplyr::tibble(stRoke::quantile_cut(data[[.x]],y=data[["pase_0"]],4,group.names = 1:4),
+ dplyr::select(data,soc_status_nowork,fam_indk_hl,edu_level_hl)) |>
+ summary_tblone()
+ })
+}
+
+
+#' Creating a truthful stratified table for predictions
+#'
+#' @param data data frame
+#'
+#' @return list
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_pred_data) |> true_pred_sum_plot()
+true_pred_sum_plot <- function(data){
+ true_sum <- data |>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::mutate(pase_change=forcats::fct_rev(pase_change))
+
+ list(true_sum,true_sum |> (function(.x){
+ split(.x,.x$pase_change %in% c("Low-low","Increase"))
+ })() |> purrr::map(function(.y){.y |> dplyr::mutate(pase_change=factor(pase_change))})) |>
+ purrr::list_flatten() |> purrr::map(summary_tblone,by="pase_change") |>
+ gtsummary::tbl_merge()
+}
+
+#' Get quick summary of missing vs non-missing for each given variable
+#'
+#' @param data data set
+#' @param var variable to summarise over
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_pred_data) |> dplyr::select(soc_status_work,fam_indk,edu_level) |> who_is_missing()
+#' targets::tar_read(df_pred_data) |> who_is_missing(var="reg_bmi")
+who_is_missing <- function(data, var = "edu_level") {
+ data |>
+ dplyr::mutate(log = factor(c("non-missing","missing")[is.na(data[[var]])+1])) |>
+ dplyr::select(log, tidyselect::everything(),-tidyselect::all_of(var)) |>
+ summary_tblone() #|> gtsummary::bold_p()
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> View()
+#' targets::tar_read(df_pred_data) |> preds_tblone()
+preds_tblone <- function(data) {
+ # data <- targets::tar_read(df_pred_data)
+ data |>
+ labelling_data() |>
+ # prediction_ready() |>
+ # dplyr::select(-reg_bmi) |>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::filter(!is.na(pase_change)) |>
+ dplyr::mutate(pase_change=forcats::fct_rev(pase_change)) |>
+ print_table_summary()
+}
+
+#' Title
+#'
+#' @param data
+#' @param b.cols
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' gt <- targets::tar_read(ls_pred_summary)[[1]]
+#' gt |> add_var_groups_gt()
+#'
+#' # For this to work, the function would need to handle labels and levels
+#' gt <- targets::tar_read(tbl_pred_summary)|> gtsummary::as_gt()
+#' gt |> add_var_groups_gt()
+add_var_groups_gt <- function(gt){
+ # gt <- sex_ls |> purrr::pluck(2) |> gtsummary::as_gt()
+ # gt <- fix_labels(gt)
+ cls <- class(gt)
+
+ b.cols <- names(gt$`_data`)
+
+ if (b.cols[[1]]!="variable"){
+ # Flag to indicate if format is native gt or not. Simple assumption
+ # class(gt) gt is not enough
+ labels <- gt$`_data`[[1]]
+ group.var <- names(gt$`_data`[[1]])
+ } else {
+ labels <- gt$`_data`[["label"]][gt$`_data`[["row_type"]]=="label"]
+ group.var <- gt$`_data`[["variable"]]
+ }
+
+
+
+ groups <- matrix(ncol=length(labels)) |>
+ data.frame() |>
+ setNames(ifelse(labels=="","unknown_var",labels)) |>
+ tibble::as_tibble() |> groups_in_ds(labels = TRUE)
+
+ group.labels <- names(groups) |> subset_named_labels(labels.raw = group_labels())
+
+ labels.all <- group.labels |> purrr::imap(function(.x,.y){
+ c(.x,groups[[.y]][["label"]])
+ }) |> purrr::list_c()
+
+ for (i in rev(seq_along(group.labels))){
+ gt <- gt |> gt::tab_row_group(label=gt::md(glue::glue("*{group.labels[[i]]}*")),
+ rows=which(group.var %in% groups[[names(group.labels)[[i]]]][["var"]]))
+
+ }
+
+ class(gt) <- cls
+ gt
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(tbl_preds_lin_imp_reg)
+#' data |> fix_labels()
+fix_labels <- function(data){
+ cls <- class(data)
+ data[[1]][["variable"]][data[[1]][["row_type"]]=="label"] |>
+ subset_named_labels(var_labels()) |>
+ unname() -> data[[1]][["label"]][data[[1]][["row_type"]]=="label"]
+ class(data) <- cls
+ data
+}
+
+
+#' Title
+#'
+#' @param data
+#' @param b.cols
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' tbl <- targets::tar_read(ls_pred_summary)[[1]]
+add_var_groups_pre_calc <- function(data,b.cols){
+
+ groups <- data |> groups_in_ds()
+
+ group.labels <- names(groups) |> subset_named_labels(labels.raw = group_labels())
+
+ t0 <- data.frame(matrix(ncol=length(b.cols))) |>
+ setNames(b.cols) |>
+ tibble::tibble()
+ list(ext = group.labels |> purrr::imap(function(.x,.y){
+ t0 |> dplyr::mutate(
+ variable=.y,
+ val_label=.x,
+ row_type="group",
+ label=.x
+ )
+ }) |> dplyr::bind_rows(),
+ lvls = group.labels |> purrr::imap(function(.x,.y){
+ c(.y,groups[[.y]][["var"]])
+ }) |> purrr::list_c()
+ )
+}
+
+#' Adds variable grouping and formatting to gtsummary tables
+#'
+#' @param tbl
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#'
+#' tbl <- targets::tar_read(tbl_pred_summary)
+#' targets::tar_read(tbl_pred_summary) |> add_var_groups()
+#'
+add_var_groups <- function(tbl,
+ pre_ls=add_var_groups_pre_calc(tbl$inputs$data,
+ names(tbl$table_body))){
+
+
+ tbl |> gtsummary::modify_table_body(
+ ~.x |> dplyr::bind_rows(pre_ls[["ext"]]) |>
+ dplyr::arrange(factor(variable,levels=pre_ls[["lvls"]]))
+ ) |>
+ gtsummary::modify_table_styling(columns=label,
+ rows= row_type%in%"level",text_format = "indent2") |>
+ gtsummary::modify_table_styling(columns=label,rows= row_type%in%"label",text_format = "indent")|>
+ gtsummary::modify_table_styling(columns=label,rows= row_type%in%"group",text_format = c("italic"))
+}
+
+#' Functionalised character vector of all labels
+#'
+#' @return
+#' @export
+#'
+#' @examples
+var_labels <- function(){
+ c(
+ age = "Age",
+ reg_female = "Female sex",
+ reg_bmi = "Body mass index",
+ reg_smoker = "Current smoker",
+ reg_alone = "Living alone",
+ reg_more_alc = "High alcohol consumption",
+ reg_hyperten = "Hypertension",
+ reg_diabetes = "Diabetes",
+ reg_atriefli = "Atrial fibrillation",
+ reg_perifer_arteriel = "Peripheral arterial disease",
+ reg_tidl_tci = "Previous TIA",
+ reg_ami = "Previous MI",
+ reg_trombolyse = "Treated with IVT",
+ reg_trombektomi = "Treated with EVT",
+ # reg_any_perf,
+ # rtreat = "Study group allocation",
+ rtreat_placebo = "Placebo trial treatment",
+ pase_0 = "Pre-stroke PASE score",
+ pase_4 = "6 months post-stroke PASE score",
+ # pase_change,
+ nihss_0 = "Admission NIHSS",
+ # soc_status,
+ soc_status_work = "Employed",
+ soc_status_nowork = "Not employed",
+ fam_indk = "Family income group",
+ fam_indk_hl = "Lower family income",
+ fam_indk_high = "Higher family income",
+ fam_indk_low = "Lower family income",
+ edu_level = "Educational level group",
+ edu_level_hl = "Lower educational level",
+ edu_high = "Higher educational level",
+ edu_low = "Low educational level",
+ who_4 = "WHO-5 score 6 months post-stroke",
+ mdi_4 = "MDI score 6 months post-stroke",
+ mrs_4_above1 = "mRS > 1 at 6 months post-stroke",
+ mfi_gen_4 = "General fatigue (MFI domain) 6 months post-stroke",
+ time = "Time",
+ status = "Status",
+ event.include = "Include event",
+ who_0 = "Pre-stroke WHO-5 score",
+ mrs_0_above0 = "Pre-stroke mRS > 0"
+ )
+}
+
+
+group_labels <- function(data){
+ c("clin" = "Clinical data",
+ "lifestyle" = "Lifestyle and chronic diseases",
+ "ses" = "Socio-economic factors",
+ "assess.events" = "Assessments",
+ "assess.pred" = "Assessments",
+ "extra" = "extras")
+}
+
+rev_naming <- function(x){
+ setNames(names(x),x)
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_pred_data)
+groups_in_ds <- function(data, labels=FALSE){
+ groups <- define_variables() |> purrr::imap(function(.x,.y){
+ tibble::tibble(group=.y,var=.x)
+ }) |>
+ dplyr::bind_rows()
+
+ if (labels){
+ matching <- subset_named_labels(names(data),
+ rev_naming(var_labels()))
+ }else {
+ matching <- names(data)
+ }
+ groups[match(matching,groups[["var"]]),] |>
+ (\(.x){
+ .x |> dplyr::mutate(group=factor(group,levels=unique(.x[["group"]])))
+ })() |>
+ cbind(
+ tibble::tibble(
+ label=labelling_data(data) |> labelled::var_label() |> purrr::list_c()
+ )
+ )|>
+ (\(.x){
+ split(.x,.x[["group"]])
+ })()
+}
+
+
+#' Subset labels
+#'
+#' @param data
+#' @param labels.raw
+#'
+#' @return character vector
+#' @export
+#'
+subset_named_labels <- function(data,labels.raw){
+ labels.raw[match(data,names(labels.raw))]
+}
+
+#' Assign labels to data.frame or tibble
+#'
+#' @param data
+#' @param labels
+#'
+#' @return
+#' @export
+#'
+#' @examples
+assign_labels <- function(data,labels){
+ # data |> labelled::set_variable_labels(labels)
+
+ labelled::var_label(data) <- labels
+
+ data
+}
+
+#' Flexible labelling using labelled for nicer tables
+#'
+#' @param data data set
+#'
+#' @return
+#' @export labelled data.frame/tibble
+#'
+#' @examples
+#' data <- targets::tar_read(df_pred_data)
+#' data <- data |> dplyr::mutate(test="test")
+#' data |> labelling_data() |> labelled::var_label()
+labelling_data <- function(data,label.list=var_labels()){
+
+ labs <- subset_named_labels(names(data),label.list)
+ labs[is.na(labs)] <- names(data)[is.na(labs)]
+
+ data |> assign_labels(labels = labs)
+}
+
+
+
+#' Print regression table
+#'
+#' @param data cox regression ready data set
+#'
+#' @return gtsummary tbl_regression list object
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> show_table_regression()
+#' targets::tar_read(df_all_data_formatted) |> show_table_regression(use.mice=TRUE)
+show_table_regression <- function(data, use.mice=FALSE, by.var="pase_change") {
+ data |>
+ events_dataset(impute = use.mice) |>
+ cox_regression(all.vars = TRUE, use.strata = FALSE,outcome.var = by.var) |>
+ gtsummary::tbl_regression(exponentiate = TRUE, add_estimate_to_reference_rows = TRUE) #|>
+ # gtsummary::add_n() |>
+ # gtsummary::bold_p()
+}
+
+#' Splitting df to list by PA trajectory
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_pred_data) |> pred_ls_split()
+pred_ls_split <- function(data, excluded.vars = "reg_bmi"){
+ data |>
+ pase_cutter(drop.pase = FALSE) |>
+ dplyr::select(-tidyselect::all_of(c("pase_4","pase_0_quartile","pase_4_quartile"))) |>
+ dplyr::group_split(pase_split = pase_change %in% c("Increase", "Low-low")) |>
+ setNames(c("drop", "hop")) |>
+ purrr::map2(.y = c("Decrease", "Increase"), .f = \(x, y){
+ x |>
+ dplyr::mutate(pase_bin = pase_change == y) |>
+ dplyr::select(-tidyselect::all_of(c(excluded.vars, c("pase_change", "pase_split")))) |>
+ na.omit()
+ })
+}
+
+#' Run regularisation steps for split data set
+#'
+#' @param data selected data set
+#'
+#' @return list
+#'
+#' @examples
+#' data <- targets::tar_read(df_pred_data)
+#' targets::tar_read(df_pred_data) |> pred_models()
+pred_models <- function(data, excludes = "reg_bmi") {
+ ls <- data |>
+ pred_ls_split(excluded.vars = excludes) |>
+ purrr::map(regularisation_steps)
+
+ class(ls) <- c("regular_list", class(ls))
+ ls
+}
+
+cross_mean_median_exp_table <- function(data) {
+ nms <- paste0("v", seq_len(ncol(data)))
+
+ cross_calcs <- data |>
+ as.data.frame() |>
+ setNames(nms) |>
+ dplyr::rowwise() |>
+ dplyr::transmute(
+ median = median(dplyr::c_across(tidyselect::all_of(nms))),
+ medianOR = exp(median),
+ mean = mean(dplyr::c_across(tidyselect::all_of(nms))),
+ meanOR = exp(mean)
+ )
+
+ dplyr::tibble(names = rownames(data), cross_calcs) |>
+ dplyr::select(-tidyselect::all_of(c("mean","median")))
+}
+
+
+gather_coefs_step1 <- function(data) {
+ data |>
+ list3levelpluck(lvl1 = "model", lvl2 = "B") |>
+ purrr::map(purrr::reduce, cbind)
+}
+
+gather_coefs <- function(data) {
+ # imputed.list <- "mids_regular_list" %in% class(data)
+
+ if ("mids_regular_list" %in% class(data)) {
+ data_step1 <- data |>
+ purrr::map(gather_coefs_step1) |>
+ purrr::map(purrr::reduce, cbind)
+ } else if ("regular_list" %in% class(data)) {
+ data_step1 <- data |> gather_coefs_step1()
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data_step1 |>
+ purrr::map(cross_mean_median_exp_table) |>
+ purrr::reduce(dplyr::full_join, by = "names", suffix = paste0("_", names(data)))
+}
+
+
+#' Merge and print model coefficients. Pools datafrom mids analyses.
+#'
+#' @param data list
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(ls_pred_models)
+#' targets::tar_read(ls_pred_models) |> print_pred_coefs()
+#' targets::tar_read(ls_pred_mids_reg) |> print_pred_coefs() |> add_var_groups_gt()
+print_pred_coefs <- function(data) {
+ # data <- targets::tar_read(ls_pred_mids_reg)
+ # nms <- names(data)
+
+ if ("mids_regular_list" %in% class(data)) {
+ type.table <- "Pooled regularised models"
+ } else if ("regular_list" %in% class(data)) {
+ type.table <- "Single regularised model"
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ merged_tbl <- data |>
+ gather_coefs() |>
+ ## Leaving out the intercept
+ (function(.x) .x[-1,])()
+
+ sel_mean_med <- colnames(merged_tbl)[!grepl(pattern = "OR",colnames(merged_tbl))][-1]
+ sel_or <- colnames(merged_tbl)[grepl(pattern = "OR",colnames(merged_tbl))]
+
+ news <- subset_named_labels(merged_tbl$names,var_labels())
+
+ merged_tbl <- merged_tbl |> dplyr::mutate(names=dplyr::if_else(is.na(news),names,news))
+
+ gt_merged_tbl <- merged_tbl|>
+ gt::gt() |>
+ gt::fmt_number(decimals = 5)
+
+ merged_tbl_log <- merged_tbl |> dplyr::mutate(dplyr::across(tidyselect::all_of(sel_or), ~.x!=1),
+ dplyr::across(tidyselect::all_of(sel_mean_med), ~.x!=0))
+
+ for (j in colnames(merged_tbl)[-1]) {
+
+ i <- merged_tbl_log[[j]]
+
+ gt_merged_tbl <- gt_merged_tbl |> gt::tab_style(style = list(
+ gt::cell_text(weight="bold")
+ ),
+ locations = gt::cells_body(
+ columns=j,
+ rows = i
+ )
+ )}
+
+ for (i in names(data)) {
+ gt_merged_tbl <- gt_merged_tbl |>
+ gt::tab_spanner(label = i, columns = tidyselect::ends_with(i))
+ }
+
+ gt_merged_tbl |> gt::tab_spanner(
+ label = type.table,
+ columns = -1
+ )
+}
+
+#' Calculates confusionMatrix from contingency tables. Pools if object class is .
+#'
+#' @param data
+#'
+#' @return list
+#'
+#' @examples
+#' targets::tar_read(ls_pred_mids_reg) |> multi_table_cfm()
+#' targets::tar_read(ls_pred_models) |> multi_table_cfm()
+multi_table_cfm <- function(data) {
+ # data <- targets::tar_read(ls_pred_mids_reg)
+ if ("mids_regular_list" %in% class(data)) {
+ data <- data |> purrr::map(\(x){
+ x |>
+ # Test tables are plucked
+ # purrr::map(\(y) y |> purrr::pluck("model") |> purrr::pluck("cMatTest"))|>
+ list3levelpluck(lvl1 = "model", lvl2 = "cMatTest") |>
+ # All tables are add together
+ purrr::reduce(\(i, j) i + j)
+ })
+ } else if ("regular_list" %in% class(data)) {
+ data <- data |> list3levelpluck(lvl1 = "model", lvl2 = "cMatTest")
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data |>
+ purrr::map(caret::confusionMatrix)
+}
+
+#' Collect and summarise auc meassures. Pools if "mids_regular_list" object
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(ls_pred_mids_reg) |> multi_auc_summary()
+#' targets::tar_read(ls_pred_models) |> multi_auc_summary()
+multi_auc_summary <- function(data) {
+ if ("mids_regular_list" %in% class(data)) {
+ data_step <- data |> purrr::map(\(x){
+ x |>
+ # Test tables are plucked
+ list3levelpluck(lvl1 = "model", lvl2 = "auc_test") |>
+ # All tables are add together
+ purrr::reduce(c)
+ })
+ } else if ("regular_list" %in% class(data)) {
+ data_step <- data |>
+ list3levelpluck(lvl1 = "model", lvl2 = "auc_test") |>
+ purrr::map(c)
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data_step |>
+ purrr::map(summary)
+}
+
+#' Map and 2 level recursive purrr::pluck to ease regular_list subsetting
+#'
+#' @param data
+#' @param lvl1
+#' @param lvl2
+#'
+#' @return
+#' @export
+#'
+#' @examples
+list3levelpluck <- function(data, lvl1 = "model", lvl2 = "cMatTest") {
+ data |> purrr::map(\(y) y |>
+ purrr::pluck(lvl1) |>
+ purrr::pluck(lvl2))
+}
+
+#' Plot performance curve from glmnet regularisation
+#'
+#' @param data list of cvs.glmnet objects
+#'
+#' @return ggplot list object
+#' @export
+#'
+#' @examples
+plot_roc_curve <- function(data, title.text) {
+ ggplot2::ggplot() +
+ purrr::map(data, function(i) {
+ ggplot2::geom_step(data = i, ggplot2::aes(x = FPR, y = TPR))
+ }) +
+ ggplot2::coord_cartesian(xlim = c(0, 1), ylim = c(0, 1)) +
+ ggplot2::geom_abline() +
+ ggplot2::theme_bw() +
+ ggplot2::ggtitle(title.text)
+}
+
+roc_gather_step <- function(x) {
+ with(x, glmnet::roc.glmnet(cvs[[1]]$fit.preval, newy = y1)[match(bestL, lambdas)])
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(ls_pred_mids_reg) |> multi_roc_plot()
+#' targets::tar_read(ls_pred_models) |> multi_roc_plot()
+multi_roc_plot <- function(data) {
+ if ("mids_regular_list" %in% class(data)) {
+ data_step1 <- data |>
+ purrr::map(purrr::map, roc_gather_step) |>
+ purrr::map(purrr::list_flatten)
+ } else if ("regular_list" %in% class(data)) {
+ data_step1 <- data |> purrr::map(roc_gather_step)
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data_step1 |>
+ purrr::map2(.y = names(data), plot_roc_curve) |>
+ patchwork::wrap_plots()
+}
+
+#' Title
+#'
+#' @param tuning.param
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+multi_tuning_gather <- function(tuning.param = "bestA", data) {
+ if ("mids_regular_list" %in% class(data)) {
+ data_step1 <- data |>
+ purrr::map(purrr::map, \(x) x |> purrr::pluck(tuning.param)) |>
+ purrr::map(purrr::reduce, c)
+ } else if ("regular_list" %in% class(data)) {
+ data_step1 <- data |>
+ purrr::map(purrr::pluck, tuning.param)
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data_step1 |> purrr::map(summary)
+}
+
+
+#' Tidied tuning summary call
+#'
+#' @param data
+#'
+#' @return
+#'
+#' @examples
+#' targets::tar_read(ls_pred_mids_reg) |> tuning_summary()
+#' targets::tar_read(ls_pred_models) |> tuning_summary()
+tuning_summary <- function(data) {
+ c(ALPHA = "bestA", LAMBDA = "bestL") |> purrr::map(\(x) x |> multi_tuning_gather(data = data))
+}
+
+#' Apply regularisation steps to MIDS object, output arranged by grouping
+#'
+#' @param data mids object from mice package
+#'
+#' @return list
+#'
+#' @examples
+#' targets::tar_read(df_pred_mids) |> mids_regularisation()
+mids_regularisation <- function(data) {
+ ls <- data |>
+ mice::complete(action = "long") |>
+ dplyr::group_split(.imp) |>
+ purrr::modify(\(x){
+ x |> dplyr::select(-tidyselect::all_of(c(".imp", ".id")))
+ }) |>
+ purrr::map(pred_models)
+
+ nms <- ls |>
+ purrr::map(names) |>
+ unique() |>
+ purrr::reduce(c)
+
+ # As a consequence of the above code each "set" of analyses are together.
+ # Here the same group analyses are subset and grouped
+ ls_n <- purrr::map(nms, function(i) {
+ ls |> purrr::map(purrr::pluck, i)
+ }) |>
+ setNames(nms)
+
+ # Special class is applied to ease future handling
+ class(ls_n) <- c("mids_regular_list", class(ls_n))
+ ls_n
+}
+
+#' A collection of all the summary functions to be applied to list of
+#' pred_models() output
+#'
+#' @param data list of data
+#'
+#' @return list
+#' @export
+#'
+multi_summary <- function(data){
+ list( "coefTable" = print_pred_coefs(data) |>
+ gt::fmt_number(n_sigfig = 3) |>
+ fix_labels() #|> add_var_groups_gt()
+ ,
+ "confusionMatrices" = multi_table_cfm(data),
+ "summaryAUC" = multi_auc_summary(data),
+ "rocPlots" = multi_roc_plot(data),
+ "tuningSummaries" = tuning_summary(data))
+}
+
+# funs <-list(
+# "coefTable" = print_pred_coefs,
+# "confusionMatrices" = multi_table_cfm,
+# "summaryAUC" = multi_auc_summary,
+# "rocPlots" = multi_roc_plot,
+# "tuningSummaries" = tuning_summary
+# )
+
+# multi_summary <- plyr::each(
+# "coefTable" = print_pred_coefs,
+# "confusionMatrices" = multi_table_cfm,
+# "summaryAUC" = multi_auc_summary,
+# "rocPlots" = multi_roc_plot,
+# "tuningSummaries" = tuning_summary
+# )
+
+#' Subset multiple elements from list
+#'
+#' @param data list
+#' @param indices numeric or character vector
+#'
+#' @return list
+#' @examples
+#' targets::tar_read(ls_pred_summary)$confusionMatrices |> purrr::map(list_subset)
+list_subset <- function(data,indices=c("overall","byClass")){
+ data[indices]
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(ls_pred_summary) |> print_model_resutls()
+print_model_resutls <- function(data){
+ par(mfrow=c(1,2))
+
+ list(data$coefTable,
+ invisible(data$confusionMatrices |> purrr::map(\(x) x |> purrr::pluck("table"))),
+ data$confusionMatrices |> purrr::map(list_subset),
+ data$summaryAUC,
+ data$tuningSummaries
+ )
+}
+
+
+#' Classic logistic regression on prediction covariates
+#'
+#' @param data data frame
+#'
+#' @return
+#' @export
+#'
+#' @examples gtsummary list elemnt
+#' targets::tar_read(df_pred_data) |> pred_log_reg()
+#' targets::tar_read(df_pred_data) |> pred_ls_split()
+pred_log_reg <- function(data){
+ data |> pred_ls_split() |>
+ purrr::map(\(x) {
+ gtsummary::tbl_regression(glm(pase_bin~.,family = binomial,data = x),
+ exponentiate= TRUE)#|>
+ # gtsummary::bold_p()
+ }
+ ) |> (\(x){gtsummary::tbl_merge(tbls = x,
+ tab_spanner = names(x))})() }
+
+#' Small wrapper to format CI with square brackets
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+square_ci <- function(data){
+ gsub("(-?\\d*\\.?\\d*)(, )(-?\\d*\\.?\\d*)",
+ "\\[\\1; \\3\\]",data)}
+
+#' Apply CI formatting across gtsummary table including merged tables
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+fix_ci <- function(data){
+ data |> gtsummary::modify_table_body(~ .x |>
+ dplyr::mutate(dplyr::across(dplyr::starts_with("ci"),
+ function(.y){square_ci(.y)})))
+}
+
+#' Classic linear regression on 6 months PASE score. Uni and multi.
+#'
+#' @param data data frame
+#'
+#' @return
+#' @export
+#'
+#' @examples gtsummary list elemnt
+#' data <- targets::tar_read(df_pred_data)
+#' data <- targets::tar_read(df_pred_mids)
+#' targets::tar_read(df_pred_data) |> pred_lin_reg()
+#' targets::tar_read(df_pred_mids) |> pred_lin_reg()
+pred_lin_reg <- function(data){
+
+ # list("tbl_regression-str:ref_row_text"="Reference") |>
+ # gtsummary::set_gtsummary_theme()
+
+ if ("mids" %in% class(data)){
+ cols <- names(data$data)
+
+ } else {
+ cols <- names(data)
+ data <- data |>
+ labelling_data()
+ }
+
+ vars <- cols[cols!="pase_4"]
+
+ formula_pase <- paste("pase_4",paste(vars,collapse = "+"),sep="~" )
+
+ # multi <- with(data=data,lm(pase_4~.)) |>
+ # gtsummary::tbl_regression(add_estimate_to_reference_rows = TRUE)|>
+ # gtsummary::bold_p() |> gtsummary::add_n()
+
+ if (!"mids" %in% class(data)){
+ ls <- list("Univariate"=data |>
+ gtsummary::tbl_uvregression(method=lm, show_single_row = dplyr::where(is.logical),
+ y=pase_4,
+ add_estimate_to_reference_rows = TRUE,pvalue_fun = NULL)#|> gtsummary::bold_p()
+ ,
+ "Multivariate (no BMI)"=lm(pase_4~.,data=dplyr::select(data,-reg_bmi)) |>
+ gtsummary::tbl_regression(add_estimate_to_reference_rows = TRUE, show_single_row = dplyr::where(is.logical))|>
+ # gtsummary::bold_p() |>
+ gtsummary::add_n()
+ ,
+ "Multivariate (ALL)"= lm(pase_4~.,data=data) |>
+ gtsummary::tbl_regression(add_estimate_to_reference_rows = TRUE, show_single_row = dplyr::where(is.logical))|>
+ # gtsummary::bold_p() |>
+ gtsummary::add_n()
+ )
+
+ } else {
+ ls <- list("Multivariate (ALL)"= suppressWarnings(mice::lm.mids(pase_4~.,data=data) |>
+ gtsummary::tbl_regression(add_estimate_to_reference_rows = TRUE, show_single_row = dplyr::where(is.logical))|>
+ # gtsummary::bold_p() |>
+ gtsummary::add_n()))
+ }
+
+ ls |> (\(x){gtsummary::tbl_merge(tbls = x,
+ tab_spanner = names(x))})() |>
+ fix_ci()
+}
+
+
+#' Simple standard plot
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> events_dataset(impute = FALSE)|> cox_regression() |> plot_survival()
+plot_survival <- function(data){
+ data |>
+ ggsurvfit::survfit2() |>
+ ggsurvfit::ggsurvfit(linetype_aes = TRUE, size = 0.8) +
+ ggsurvfit::add_confidence_interval() +
+ ggsurvfit::add_risktable(
+ risktable_stats = c("n.risk", "cum.event"),
+ stats_label = list(cum.event = "Cumulative Observed Events",
+ n.risk = "Number at Risk"),
+ theme =
+ list(
+ ggsurvfit::theme_risktable_default(axis.text.y.size = 11,
+ plot.title.size = 11),
+ ggplot2::theme(plot.title = ggplot2::element_text(face = "bold"))
+ )
+ ) +
+ ggplot2::scale_y_continuous(
+ limits = c(0, 1),
+ labels = scales::percent,
+ expand = c(0.01, 0)
+ ) +
+ ggplot2::scale_x_continuous(breaks = 0:9, expand = c(0.02, 0))
+}
+
+
+#' Smooth tidy survfit object
+#'
+#' @param data survfit object
+#'
+#' @return tibble
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted) |> events_dataset(impute = FALSE)|> cox_regression()
+#' data |> ggsurvfit::survfit2(robust=TRUE) |>
+#' ggsurvfit::tidy_survfit(type="survival") |>
+#' dplyr::group_split(strata) |>
+#' purrr::map(smooth_col)
+smooth_col <- function(data){
+ smoothed <- lapply(c("estimate","conf.high","conf.low"),function(i){
+ stats::predict(mgcv::gam(data=data,formula = as.formula(glue::glue("{i}~s(time,bs='cs')")))) |>
+ as.data.frame()|>
+ setNames(glue::glue("{i}_smooth"))
+ }) |> purrr::list_cbind()
+
+ dplyr::tibble(data,
+ smoothed)
+
+}
+
+#' Prepare cox regression for smooth survival plot
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> events_dataset(impute = FALSE)|> cox_regression() |> smooth_cox_data()
+smooth_cox_data <- function(data){
+ data |>
+ ggsurvfit::survfit2(robust=TRUE) |>
+ ggsurvfit::tidy_survfit(type="survival") |>
+ dplyr::group_split(strata) |>
+ purrr::map(smooth_col) |>
+ purrr::list_rbind()
+}
+
+#' Plot smooth survival plot
+#'
+#' @param data df from cox regression
+#'
+#' @return ggplot list object
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted) |> events_dataset(impute = FALSE)|> cox_regression(use.strata=TRUE)
+#' data |> plot_survival_smooth()
+plot_survival_smooth <- function(data){
+ if ("mira" %in% class(data)) stop("Only plots non-imputed survival data")
+
+ n.level <- length(data$xlevels[[1]])
+
+ # data |>
+ # ggsurvfit::survfit2() |>
+ # ggsurvfit::tidy_survfit()
+
+ if (data |> ggsurvfit::survfit2() |> purrr::pluck("n") |> length() ==1 ){
+ ds <- data |>
+ ggsurvfit::survfit2() |>
+ ggsurvfit::tidy_survfit()
+ p <- ds |>
+ ggplot2::ggplot(ggplot2::aes(x=time, y=estimate))+
+ ggplot2::geom_smooth(se=TRUE, method="loess", formula = "y~x", linewidth=2, color="grey10")
+ # Added auto max for y axis removed again to ensure same y axis
+ # max_y <- max(ds$conf.high)
+
+ } else {
+ ds <- data |>
+ smooth_cox_data()
+ p <- ds |>
+ ggplot2::ggplot()+
+ ggplot2::geom_line(ggplot2::aes(x=time, y=estimate_smooth, color=strata, linetype=strata), linewidth=2)+
+ ggplot2::geom_ribbon(ggplot2::aes(x=time, ymin=conf.low_smooth,ymax=conf.high_smooth, fill=strata), alpha=.2)
+ # Added auto max for y axis removed again to ensure same y axis
+ # max_y <- max(ds$conf.high_smooth)
+
+ }
+ p+
+ ggplot2::scale_y_continuous(limits = c(0,1.02),
+ breaks = seq(0,1,.25),
+ labels = scales::percent,
+ expand = c(0.01, 0)
+ ) +
+ ggplot2::scale_x_continuous(breaks = 0:9, expand = c(0.02, 0))+
+ ggplot2::scale_fill_manual(values=viridisLite::turbo(n=n.level,direction = 1))+
+ ggplot2::scale_color_manual(values=viridisLite::turbo(n=n.level,direction = 1))+
+ ggplot2::theme_minimal()+
+ ggplot2::theme(axis.title.x = ggplot2::element_blank(),
+ axis.title.y = ggplot2::element_blank(),
+ # axis.text = ggplot2::element_blank(),
+ # legend.position = "none",
+ panel.grid.minor.y = ggplot2::element_blank(),
+ panel.grid.major.y = ggplot2::element_line(color="grey45",linewidth = 1))
+
+}
+
+cluster_rank <- function(data){
+ data |> cox_regression(outcome.var = "clust",use.strata = TRUE) |> ggsurvfit::survfit2(robust=TRUE) |>
+ ggsurvfit::tidy_survfit(type="survival") |>
+ dplyr::group_split(strata) |>
+ purrr::map(\(x){
+ min(x[["estimate"]])
+ }) |> purrr::list_c() |> rank() |> rev()
+}
+
+cox_relevel <- function(data){
+ data |> dplyr::mutate(clust=factor(clust,levels=cluster_rank(data)))
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted)
+complete_preds_data <- function(data){
+ data |> events_ready() |>
+ fun_impute(ignore = c("pase_0","pase_4"),pase.mod = FALSE) |>
+ mice::complete() |>
+ dplyr::filter((!is.na(pase_0)&!is.na(pase_4)))
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> add_kamila_cluster()
+#' data_kam <- targets::tar_read(df_all_data_formatted) |> add_kamila_cluster()
+#' data_kam |>print_table_summary(by.var = "kam_grp")
+#' data_kam |> cox_regression(outcome.var="kam_grp")|> plot_survival_smooth()
+#' data_kam |> cox_regression(outcome.var="kam_grp",use.strata = FALSE)|> gtsummary::tbl_regression(exponentiate = TRUE, add_estimate_to_reference_rows = TRUE) |> gtsummary::bold_p()
+#' targets::tar_read(df_events_complete) |> kamila_cluster(n.clusters=3)
+kamila_cluster <- function(data, n.clusters=3,include.out=FALSE){
+ # An index number could be added to later join pack. Of input a complete data set from imputation and pooling??
+ data_orig <- data
+
+
+ if (!include.out){
+ data <- data |>
+ dplyr::select(-tidyselect::one_of(c("time","status")))
+ }
+
+
+ catInd <- data |> lapply(\(x) is.character(x)|is.logical(x)) |> purrr::list_c()
+ conInd <- data |> lapply(\(x) is.numeric(x)|is.integer(x)) |> purrr::list_c()
+
+ catVars <- data[,catInd]
+ catVars <- catVars |> lapply(factor) |> dplyr::bind_cols() |> as.data.frame()
+ conVars <- data[,conInd] |> scale()|> as.data.frame()
+
+ if (is.null(n.clusters)){
+ out <- kamila::kamila(conVar = conVars, catFactor = catVars, numClust = 2:7, numInit = 10,
+ calcNumClust = "ps"
+ )
+ }else {
+ out <- kamila::kamila(conVar = conVars, catFactor = catVars, numClust = n.clusters, numInit = 10)
+ }
+
+ ls <- list("out"=out,"data_orig"=data_orig)
+
+ class(ls) <- c("kamila_cluster",class(ls))
+
+ ls
+
+}
+
+
+#' VarSelLCM wrapper
+#'
+#' @param data complete dataset with no missings
+#' @param n.clusters number of clusters (if length 1, n is fixed, in n>1 given clusters are tested)
+#' @param include.out flag to include outcome variables or not
+#' @param memb.out output data frame with final membership or not (then outputs standard model output)
+#'
+#' @return list with VarSelLCM output and original dataset with cluster appended
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' data |> lcm_cluster()
+lcm_cluster <- function(data, n.clusters=3, include.out=FALSE, var.sel=FALSE){
+ data_orig <- data
+
+ if (!include.out){
+ data <- data |>
+ dplyr::select(-c("time", "status"))
+ }
+
+
+ set.seed(5432)
+
+ out <- data |>
+ dplyr::mutate(dplyr::across(where(is.logical)|where(is.character),~factor(.x))) |>
+ as.data.frame() |>
+ VarSelLCM::VarSelCluster(
+ gvals=n.clusters,
+ crit.varsel="BIC",
+ vbleSelec = var.sel,
+ nbcores = round(parallel::detectCores()*.8)
+ )
+
+ ls <- list("out"=out,"data_orig"=data_orig)
+
+ class(ls) <- c("lcm_cluster",class(ls))
+
+ ls
+
+}
+
+#' Kmeans clustering
+#'
+#' @param data
+#' @param n.clusters
+#' @param include.out
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' data |> kmeans_cluster()
+#' data |> kmeans_cluster(n.clusters=3)
+kmeans_cluster <- function(data, n.clusters=3, include.out=FALSE, memb.out=TRUE){
+ data_orig <- data
+
+ if (!include.out){
+ data <- data |>
+ dplyr::select(!tidyselect::one_of(c("time", "status")))
+ }
+
+ out <- data |>
+ dplyr::mutate(dplyr::across(where(is.double),~scale(.x)),
+ dplyr::across(where(is.logical)|where(is.character),~factor(.x)),
+ dplyr::across(where(is.factor),~as.numeric(.x))) |>
+ stats::kmeans(
+ centers=n.clusters
+ )
+
+ ls <- list("out"=out,"data_orig"=data_orig)
+
+ class(ls) <- c("kmeans_cluster",class(ls))
+
+ ls
+
+}
+
+#' dbscan clustering
+#'
+#' @param data
+#' @param n.clusters
+#' @param include.out
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' data |> dbscan_cluster()
+#' data |> dbscan_cluster(n.clusters=3)
+dbscan_cluster <- function(data, n.clusters=3, include.out=FALSE, memb.out=TRUE){
+ data_orig <- data
+
+ if (!include.out){
+ data <- data |>
+ dplyr::select(!tidyselect::one_of(c("time", "status")))
+ }
+
+ data <- data |> na.omit() |> dplyr::mutate(rtreat=rtreat!="Placebo",
+ dplyr::across(dplyr::everything(), as.numeric))
+
+
+ ## This plot indicates that eps should be set around 60, but at this value everything is one cluster.
+ dbscan::kNNdistplot(data,k = 5)
+
+ ## Performing hierachical clustering, it is clear, that the algorithm is not able to seperate clusters.
+ hds <- dbscan::hdbscan(data,minPts = 5)
+
+ plot(hds,show_flat = TRUE)
+
+ ## Clustering with set eps value and minPts
+ ds <- dbscan::dbscan(data,eps = 25,minPts = 2)
+
+ ds[["cluster"]]
+
+ ## dbscan is not an interesting approach, apparently
+
+ #
+ #
+ #
+ #
+ # out <- data |>
+ # dplyr::mutate(dplyr::across(where(is.double),~scale(.x)),
+ # dplyr::across(where(is.logical)|where(is.character),~factor(.x)),
+ # dplyr::across(where(is.factor),~as.numeric(.x))) |>
+ # stats::kmeans(
+ # centers=n.clusters
+ # )
+ #
+ # ls <- list("out"=out,"data_orig"=data_orig)
+ #
+ # class(ls) <- c("kmeans_cluster",class(ls))
+ #
+ # ls
+
+}
+
+#' Title
+#'
+#' @param ls
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' ls <- data |> lcm_cluster()
+#' ls |> final_membership()
+final_membership <- function(ls){
+ cls <- class(ls)
+ if ("kamila_cluster" %in% cls) {
+
+ tibble::tibble(clust=factor(ls$out$finalMemb),
+ ls$data_orig)
+
+ } else if ("lcm_cluster" %in% cls) {
+
+ tibble::tibble(clust=factor(ls$out@partitions@zMAP),
+ ls$data_orig)
+
+ } else if ("kmeans_cluster" %in% cls) {
+
+ tibble::tibble(clust=factor(ls$out$cluster),
+ ls$data_orig)
+
+ } else stop("Class not recognised")
+
+}
+
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' data |> get_clusters()
+#' data |> get_clusters(n.cl=2:7)
+get_clusters <- function(data,n.cl=4,rm.out=TRUE){
+ set.seed(1123)
+
+ if (length(n.cl)>1){
+ list(
+ # "kmeans"=data |> kmeans_cluster(n.clusters = n.cl,include.out = !rm.out),
+ "lcm"= data |> lcm_cluster(n.clusters = n.cl,include.out = !rm.out),
+ "kamila"=data |> kamila_cluster(n.clusters = n.cl,include.out = !rm.out)
+ )
+ } else {
+ list(
+ "kmeans"=data |> kmeans_cluster(n.clusters = n.cl,include.out = !rm.out),
+ "lcm"= data |> lcm_cluster(n.clusters = n.cl,include.out = !rm.out),
+ "kamila"=data |> kamila_cluster(n.clusters = n.cl,include.out = !rm.out)
+ )
+ }
+
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(list_pred_clusters)
+#' data |> final_clusters()
+final_clusters <- function(data,new.levels=NULL){
+ out <- data |> lapply(final_membership) |> lapply(labelling_data)
+
+ if (is.null(new.levels)){
+ out
+ } else {
+ out |>
+ purrr::map2(relevels,function(x,y){
+ # x$clust <- factor(factor(x$clust,levels=y),labels=1:4)
+ x$clust <- factor(x$clust,levels=y)
+ x #|>
+ # dplyr::filter(clust %in% range(as.numeric(clust))) |>
+ # dplyr::mutate(clust=factor(clust))
+ })
+ }
+
+ }
+
+
+
+#' Title
+#'
+#' @param data
+#' @param by
+#'
+#' @return
+#' @export
+#'
+#' @examples
+merged_summary_tbl <- function(data,by="clust"){
+ data |>
+ purrr::map(function(x){
+ x |>
+ # print_table_summary(by.var = by)
+ gtsummary::tbl_summary(by=by) #|>
+ # gtsummary::add_p() |> gtsummary::bold_p()
+ }
+ ) |> (\(x){
+ x |> gtsummary::tbl_merge(tab_spanner = names(x))
+ })()
+}
+
+#' Easy cox regression tbl for uniform results
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+cox2tbl <- function(data,by="clust"){
+data|> cox_regression(outcome.var = by,use.strata = FALSE,all.vars = FALSE) |>
+ gtsummary::tbl_regression(exponentiate =TRUE) |> gtsummary::bold_p()
+}
+
+#' Title
+#'
+#' @param data
+#' @param by
+#'
+#' @return
+#' @export
+#'
+#' @examples
+merged_cox_reg_tbl <- function(data,by="clust"){
+ data |>
+ purrr::map(function(x){
+ x |> cox2tbl(by=by)
+ }
+ ) |> (\(x){
+ x |> gtsummary::tbl_merge(tab_spanner = names(x))
+ })()
+}
+
+#' Title
+#'
+#' @param data
+#' @param by
+#'
+#' @return
+#' @export
+#'
+#' @examples
+wrapped_surv_plot <- function(data,by="clust"){
+data |>
+ purrr::map(function(x){
+ x |> cox_regression(outcome.var = by,use.strata = TRUE,all.vars = FALSE) |>
+ plot_survival_smooth()+ggplot2::labs(color="Cluster",fill="Cluster",linetype="Cluster")
+ }
+ ) |> (\(x){
+ x |> patchwork::wrap_plots(ncol=1) + patchwork::plot_annotation(tag_levels = list(names(x)))
+ })()
+}
+
+
+# Ranking by most events
+relevel_by_rank <- function(data){
+ ## Assigning clusters to each dataset
+data <- targets::tar_read(list_pred_clusters) |>
+ final_clusters(new.levels = NULL)
+
+## Calculating cox regressions and ranking by the final point on the survival plot
+relevels <- data |>
+ purrr::map(function(x){
+ x |> cox_regression(outcome.var = "clust",use.strata = TRUE,all.vars = FALSE) |>
+ ggsurvfit::survfit2() |>
+ ggsurvfit::tidy_survfit() |>
+ (\(x){
+ split(x,x[["strata"]]) |>
+ purrr::map(function(.y){
+ .y[["estimate"]][nrow(.y)]
+ })
+ })() |> purrr::reduce(c) |> rank()
+ }
+ )
+
+#3 Assigning the new, ranked levels
+targets::tar_read(list_pred_clusters) |>
+ final_clusters(new.levels = relevels)
+}
+
+## TODO
+## Verify definitions
+## Do remaining documentation of functions
+##
+##
+## How does elastic net work with imputed dataset?
+## Functionalise to allow for imputed and non-imputed (both analyses) - in both cases with and without BMI - include department of inclusion to investigate reason of missing BMI data
+##
+## tidymodels does not allow pmm in mice. Thy're out!
diff --git a/1 PA Decline/Fra DDV/pa_change_analyses240411.docx b/1 PA Decline/Fra DDV/pa_change_analyses240411.docx
new file mode 100755
index 0000000..6883b1f
Binary files /dev/null and b/1 PA Decline/Fra DDV/pa_change_analyses240411.docx differ
diff --git a/1 PA Decline/Fra DDV/pa_change_analyses240411_coefs.docx b/1 PA Decline/Fra DDV/pa_change_analyses240411_coefs.docx
new file mode 100644
index 0000000..d9ee49d
Binary files /dev/null and b/1 PA Decline/Fra DDV/pa_change_analyses240411_coefs.docx differ
diff --git a/1 PA Decline/Fra DDV/pa_change_analyses240418.docx b/1 PA Decline/Fra DDV/pa_change_analyses240418.docx
new file mode 100644
index 0000000..5f8de11
Binary files /dev/null and b/1 PA Decline/Fra DDV/pa_change_analyses240418.docx differ
diff --git a/1 PA Decline/Fra DDV/pa_change_tbl1240411.docx b/1 PA Decline/Fra DDV/pa_change_tbl1240411.docx
new file mode 100755
index 0000000..07e10bb
Binary files /dev/null and b/1 PA Decline/Fra DDV/pa_change_tbl1240411.docx differ
diff --git a/1 PA Decline/Til DDV/00master.R b/1 PA Decline/Til DDV/00master.R
new file mode 100644
index 0000000..41dee5d
--- /dev/null
+++ b/1 PA Decline/Til DDV/00master.R
@@ -0,0 +1,251 @@
+##
+## Master script
+##
+## Based on the assignment work from the ISL-course
+##
+## Generation 2 - 02.december.2022
+## Code preparation for analysis on Denmarks Statistics server with enriched data set.
+##
+## Analysis plan:
+## Table 1
+## Figure 1: Sankey plot (drop & hop colored)
+## Table 2: Linear regression model of pase_6~.
+## Table 3: Elastic net prediction models of drop and hop. Performance measures referenced in text.
+##
+## A Rmarkdown file could be created to write the initial report with main results.
+## This code is a bit of a mess, as it is the result of several iterations. It works however.
+##
+
+## ====================================================================
+# Step 0: Primary outcome
+## ====================================================================
+
+# Script to run as hop and drop
+
+pout <- "drop" # Drop to first quartile
+
+# decl_rel
+# decl_abs
+# drop
+# hop
+
+## ====================================================================
+## Data
+## ====================================================================
+
+
+setwd("/Users/au301842/PhysicalActivityandStrokeOutcome/1 PA Decline/")
+
+source("data_set.R")
+
+source("data_format.R")
+
+## ====================================================================
+##
+## Baseline - by PASE group
+##
+## ====================================================================
+
+ts_q <- X_tbl |>
+ select(vars) |>
+ mutate(pase_0_cut = factor(quantile_cut(pase_0, groups = 4)[[1]],ordered = TRUE)) |>
+ select(-pase_6,-pase_0) |>
+ tbl_summary(missing = "no",
+ by="pase_0_cut",
+ value = list(where(is.factor) ~ "2"),
+ type = list(mrs_0 ~ "categorical",
+ all_continuous() ~ "continuous2"),
+ statistic = list(all_continuous() ~ c("{N_nonmiss}",
+ "{median} ({p25}, {p75})",
+ "{min}, {max}",
+ "{mean} ({sd})"))
+) |>
+ add_overall() |>
+ add_n ()
+
+ts_q
+
+tbl_one_rtf <- file("table1.RTF", "w")
+writeLines(ts_q%>%as_gt()%>%as_rtf(), tbl_one_rtf)
+close(tbl_one_rtf)
+
+## ====================================================================
+# Drops and hops
+## ====================================================================
+
+# TRUEs are patients dropping
+table(X_tbl$pase_0_cut!="1"&X_tbl$pase_6_cut=="1")/nrow(X_tbl[X_tbl$pase_0_cut!="1",])
+
+# TRUEs are percentage of patients inactive before stroke being more active after
+table(X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut!="1")/nrow(X_tbl[X_tbl$pase_0_cut=="1",])
+
+# TRUEs are percentage of patients being more active after that were inactive before stroke
+table(X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut!="1")/nrow(X_tbl[X_tbl$pase_6_cut!="1",])
+
+# Difference between hop/no-hop
+t.test(X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut!="1","pase_0"],X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_0"])
+
+summary(X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut!="1","pase_0"])
+
+summary(X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_0"])
+
+boxplot(X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut!="1","pase_0"],X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_0"])
+
+# Stationary low
+t.test(X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_0"],X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_6"])
+
+boxplot(X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_0"],X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_6"])
+
+## ====================================================================
+# Sankey plot
+## ====================================================================
+
+# source("sankey.R")
+# p_delta
+
+## ====================================================================
+# Six months PASE: Bivariate and multivariate analyses
+## ====================================================================
+
+dta_lmreg <- X_tbl |>
+ select(vars) |>
+ mutate(mrs_0=factor(ifelse(mrs_0==1,1,2)))
+
+Hmisc::label(dta_lmreg$mrs_0) <- "Pre-stroke mRS >0"
+
+uv_reg <- tbl_uvregression(data=dta_lmreg,
+ method=lm,
+ y="pase_6",
+ show_single_row = where(is.factor),
+ estimate_fun = ~style_sigfig(.x,digits = 3),
+ pvalue_fun = ~style_pvalue(.x, digits = 3)
+)
+
+mu_reg <- dta_lmreg |>
+ lm(formula=pase_6~.,data=_) |>
+ tbl_regression(show_single_row = where(is.factor),
+ estimate_fun = ~style_sigfig(.x,digits = 3),
+ pvalue_fun = ~style_pvalue(.x, digits = 3)
+ )|>
+ add_n()
+
+tbl_merge(list(uv_reg,mu_reg))
+
+
+## ====================================================================
+##
+## Data variance
+##
+## Illustrating principal components.
+##
+## ====================================================================
+
+
+# source("PCA.R")
+#
+#
+# pca22
+# ggsave("pc_plot.png",width = 18, height = 12, dpi = 300, limitsize = TRUE, units = "cm")
+
+
+## ====================================================================
+##
+## Models
+##
+## ====================================================================
+
+
+# source("assign_full.R")
+
+ls <- list()
+for (i in c("drop","hop")){
+ pout <- i
+ source("data_format.R")
+ source("regularisation_steps.R")
+}
+
+# Loop to run regularised model on both drop and hop.
+# Saved in list for printing and exporting the plot.
+
+## ====================================================================
+# Step 1: data merge
+## ====================================================================
+tbl<-merge(ls$drop$RegularisedCoefs$'_data',ls$hop$RegularisedCoefs$'_data',by="name",all.x=T, sort=F)
+
+## ====================================================================
+# Step 2: table
+## ====================================================================
+com_coef_tbl<-tbl%>%
+ gt()%>%
+ fmt_number(
+ columns=colnames(tbl)[sapply(tbl,is.numeric)], ## Selecting all numeric
+ rows = everything(),
+ decimals = 3)%>%
+ tab_spanner(
+ label = "DROP",
+ columns = 2:5
+ )%>%
+ tab_spanner(
+ label = "HOP",
+ columns = 6:9
+ )%>%
+ tab_header(
+ title = "Model coefficients",
+ subtitle = "Combined table of both full and regularised model coefficients"
+ )
+
+
+# paste0("Regularised model, (a=",
+# best_alph,
+# ", l=",
+# round(best_lamb,3),
+# ")")
+
+com_coef_tbl
+
+## ====================================================================
+# Step 3: export
+## ====================================================================
+com_coef_rtf <- file("table2.RTF", "w")
+writeLines(com_coef_tbl%>%as_rtf(), com_coef_rtf)
+close(com_coef_rtf)
+
+
+
+## ====================================================================
+##
+## Model performance
+##
+## Table with performance meassures for the two different models.
+##
+## ====================================================================
+
+## ====================================================================
+# Step 1: data set
+## ====================================================================
+
+tbl<-data.frame(Meassure=c(names(ls$drop$ConfusionMatrx$byClass),"Mean AUC"),
+ "Drop"=round(c(ls$drop$ConfusionMatrx$byClass,ls$drop$AUROC["Mean"]),3),
+ "Hop"=round(c(ls$hop$ConfusionMatrx$byClass,ls$hop$AUROC["Mean"]),3))
+
+## ====================================================================
+# Step 2: table
+## ====================================================================
+tbl_perf<-tbl%>%
+ gt()%>%
+ tab_header(
+ title = "Performance meassures",
+ subtitle = "Combined table of both drop and hop"
+ )
+
+tbl_perf
+
+## ====================================================================
+# Step 3: export
+## ====================================================================
+tbl_perf_rtf <- file("table3.RTF", "w")
+writeLines(tbl_perf%>%as_rtf(), tbl_perf_rtf)
+close(tbl_perf_rtf)
+
+
+
diff --git a/1 PA Decline/Til DDV/data_format.R b/1 PA Decline/Til DDV/data_format.R
new file mode 100644
index 0000000..e5668af
--- /dev/null
+++ b/1 PA Decline/Til DDV/data_format.R
@@ -0,0 +1,50 @@
+## Article 1 outcome group definition script
+## To be enriched from Statistics Denmark
+##
+## Based on the ItMLiHSmar2022 course
+
+library(Hmisc)
+library(dplyr)
+library(daDoctoR)
+library(tidyselect)
+
+# Setting final primary output from "pout"
+if (pout=="drop"){
+ X_tbl <- X_tbl|>
+ mutate(group=pase_drop_fac)
+
+ # print(quantile(as.numeric(X_tbl$pase_0)))
+ # print(quantile(as.numeric(X_tbl$pase_6)))
+ # print(summary(X_tbl$pase_0_cut))
+
+ X_tbl_f <- X_tbl|>
+ filter(pase_0_cut!=1)|>
+ select(-starts_with("pase_"))
+}
+
+if (pout=="hop"){
+ X_tbl <- X_tbl|>
+ mutate(group=pase_hop_fac)
+
+ # print(quantile(as.numeric(X_tbl$pase_0)))
+ # print(quantile(as.numeric(X_tbl$pase_6)))
+ # print(summary(X_tbl$pase_0_cut))
+
+ X_tbl_f <- X_tbl|>
+ filter(pase_6_cut!=1)|>
+ select(-starts_with("pase_"))
+}
+
+# Dropping non-complete for analysis
+Xy <- X_tbl_f|>
+ na.omit()|> # Keeping only complete observations
+ select(-c(tci) # Left out of model as no present in drop-group
+ )|>
+ mutate(mrs_0=factor(ifelse(mrs_0==1,1,2))) # Sets binary mRS 0 to include in glmnet, 0 or above
+
+label(Xy) = as.list(var.labels[match(names(Xy), names(var.labels))])
+
+X<-dplyr::select(Xy,-c(group, -starts_with("pase_")) # Exclude primary outcome
+ )
+y<-Xy$group
+
diff --git a/1 PA Decline/Til DDV/data_set.R b/1 PA Decline/Til DDV/data_set.R
new file mode 100644
index 0000000..72948eb
--- /dev/null
+++ b/1 PA Decline/Til DDV/data_set.R
@@ -0,0 +1,193 @@
+## Article 1 data set definition
+## To be enriched from Statistics Denmark
+##
+## Based on the ItMLiHSmar2022 course
+
+library(Hmisc)
+library(dplyr)
+library(daDoctoR)
+library(tidyverse)
+library(patchwork)
+library(caret)
+library(glmnet)
+library(leaps)
+library(pROC)
+library(gt)
+library(gtsummary)
+library(glue)
+# library(ggdendro)
+library(corrplot)
+
+## ====================================================================
+# Step 2: Selection
+## ====================================================================
+
+
+export<-export[,c("pase_0",
+ "age",
+ "sex",
+ "civil",
+ "smoke_ever",
+ "smoker",
+ "rtreat",
+ "alc",
+ "afli",
+ "hypertension",
+ "diabetes",
+ "mrs_0",
+ "nihss_c",
+ "thrombolysis",
+ "pad",
+ "thrombechtomy",
+ "ami",
+ "tci",
+ "pase_6")]
+
+## ====================================================================
+# Step 3: Formatting variables
+## ====================================================================
+
+export$diabetes[is.na(export$diabetes)]<-"no"
+export$diabetes[is.na(export$hypertension)]<-"no"
+export$thrombolysis[is.na(export$thrombolysis)]<-"no"
+export$thrombechtomy[is.na(export$thrombechtomy)]<-"no"
+export$pad[is.na(export$pad)]<-"no"
+export$ami[is.na(export$ami)]<-"no"
+# export$smoker_prev <- ifelse(export$smoker=="3","yes","no")
+export$smoker <- ifelse(export$smoker=="1","yes","no")
+export$smoker[is.na(export$smoker)] <- "no"
+# export$mrs_0[export$mrs_0==3]<-NA
+
+dta <- export %>%
+ # as_tibble()%>%
+ mutate(any_rep=factor(ifelse(thrombolysis=="yes"|thrombechtomy=="yes","yes","no")), # If not noted, no therapy was received
+ male_sex= factor(ifelse(sex=="female","no","yes")),
+ # smoke_ever=factor(ifelse(smoke_ever=="never","no","yes")),
+ civil=factor(ifelse(civil=="partner","no","yes")), # Sets "yes" for not-cohabiting
+ rtreat=factor(ifelse(rtreat=="Placebo","no","yes")), # "Yes" receives active treatment
+ alc=factor(ifelse(alc=="more","yes","no")), # Yes for more than guideline
+ pase_0=as.numeric(pase_0),
+ pase_6=as.numeric(pase_6),
+ across(c("diabetes",
+ "hypertension",
+ "smoker",
+ "afli",
+ "pad",
+ "ami",
+ "tci",
+ "mrs_0"),as.factor),
+ across(c("nihss_c",
+ "age"),as.numeric )
+ )%>%
+ select(-c(sex))
+
+
+## ====================================================================
+# Step 4: Defining outcome
+## ====================================================================
+
+## Changed to step 7
+## This is to perform proper quantile split based on actually included.
+
+## ====================================================================
+# Step 5: Ordering variables
+## ====================================================================
+
+vars <- c("age",
+ "male_sex",
+ "civil",
+ "pase_0",
+ "smoker",
+ "alc",
+ "afli",
+ "hypertension",
+ "diabetes",
+ "pad",
+ "ami",
+ "tci",
+ "mrs_0",
+ "nihss_c",
+ "any_rep",
+ "rtreat",
+ "pase_6")
+
+dta<-dta[vars]
+
+## ====================================================================
+# Step 6: Labeling
+## ====================================================================
+
+var.labels = c(age="Age",
+ male_sex="Male",
+ civil="Living alone",
+ pase_0="Pre-stroke PASE score",
+ pase_6="Six month PASE score",
+ smoker="Daily or occasinally smoking",
+ alc="More alcohol than recommendation",
+ afli="AFIB",
+ hypertension="Hypertension",
+ diabetes="Diabetes",
+ pad="PAD",
+ ami="Previous MI",
+ tci="Previous TIA",
+ mrs_0="Pre-stroke mRS [-1]",
+ nihss_c="Acute NIHSS score",
+ thrombolysis="Acute thrombolysis",
+ thrombechtomy="Acute thrombechtomy",
+ any_rep="Any reperfusion therapy",
+ rtreat="Active trial treatment",
+ pase_drop_fac="PASE first quartile drop F",
+ pase_hop_fac="PASE first quartile hop F",
+ pase_0_cut="PASE 0 quartiles",
+ pase_6_cut="PASE 6 quartiles")
+
+
+
+## ====================================================================
+# Step 7: final data export
+## ====================================================================
+
+data_summary<-summary(dta)
+
+# Saving "old" factorised variables
+sel<-sapply(dta,is.factor)
+# Reformatting factors as 1/2 for analysis
+dta<-dta |>
+ mutate(across(where(is.factor), as.numeric))|> # Turning factors into 1(no) or 2(yes) for model. Numbered alphabetically.
+ mutate(across(matches(colnames(dta)[sel]), as.factor),
+ across(starts_with("pase_"), as.numeric))
+
+# Filtering out non-PASE
+X_tbl<-dta |>
+ filter(!is.na(pase_0),!is.na(pase_6))
+
+nrow(X_tbl)
+
+# Defining possible outcome meassures. Keeping in df for characterisation
+X_tbl <- X_tbl|>
+ mutate(## Relative decline
+ pase_diff=(pase_0-pase_6),
+ pase_decl_rel = pase_diff/pase_0*100,
+ # pase_decl_rel_fac=factor(ifelse(pase_decl_rel>=rel_dif,"yes","no")),
+ ## Absolute decline
+ # pase_decl_abs_fac=factor(ifelse(pase_diff>=abs_dif,"yes","no")),
+ ## Drop
+ pase_0_cut=quantile_cut(as.numeric(pase_0),
+ groups=4,
+ group.names = c(as.character(1:4)),
+ y=as.numeric(pase_0),
+ ordered.f = TRUE,
+ inc.outs = TRUE,
+ detail.lst=FALSE),
+ pase_6_cut=quantile_cut(as.numeric(pase_6),
+ groups=4,
+ group.names = c(as.character(1:4)),
+ y=as.numeric(pase_0),
+ ordered.f = TRUE,
+ inc.outs = TRUE,
+ detail.lst=FALSE),
+ pase_drop_fac=factor(ifelse(pase_6_cut==1&pase_0_cut!=1,"yes","no")),
+ pase_hop_fac=factor(ifelse(pase_6_cut!=1&pase_0_cut==1,"yes","no")))
+
+Hmisc::label(X_tbl) = as.list(var.labels[match(names(X_tbl), names(var.labels))])
+
diff --git a/1 PA Decline/Til DDV/regular_fun.R b/1 PA Decline/Til DDV/regular_fun.R
new file mode 100644
index 0000000..1b457b0
--- /dev/null
+++ b/1 PA Decline/Til DDV/regular_fun.R
@@ -0,0 +1,117 @@
+## ItMLiHSmar2022
+## regular_fun.R, child script
+## Regularisation model building function
+## Andreas Gammelgaard Damsbo, agdamsbo@clin.au.dk
+##
+## Now modified to use in publication
+##
+
+regular_fun<-function(X,y,K,lambdas,alpha){
+n<-nrow(X)
+set.seed(321)
+
+# Using caret function to ensure both levels represented in all folds
+c<-createFolds(y=y, k = K, list = FALSE, returnTrain = TRUE)
+
+B<-yhatTestProbKeep<-list()
+accTrain<-accTest<-err_train<-err_test<-auc_train<-auc_test<-matrix(nrow = K,ncol = length(lambdas))
+
+catinfo<-levels(y)
+
+cMatTrain<-cMatTest<-table(true=factor(c(0,0),levels=catinfo),pred=factor(c(0,0),levels=catinfo))
+
+
+## Iterate over partitions
+for (idx1 in 1:K){
+
+ # Status
+ cat('Processing fold', idx1, 'of', K,'\n')
+
+ # idx1=1
+ # Get training- and test sets
+ I_train = c!=idx1 ## Creating selection vector of TRUE/FALSE
+ I_test = !I_train
+
+ Xtrain = X[I_train,]
+ ytrain = y[I_train]
+ Xtest = X[I_test,]
+ ytest = y[I_test]
+
+
+ ## Model matrices for glmnet
+ ## Using the complicated approach not to include first level.
+ # Xmat.train<-model.matrix(~ .-1, data=Xtrain,
+ # contrasts.arg = lapply(Xtrain[,sapply(Xtrain, is.factor)],
+ # contrasts, contrasts=T))
+ # Xmat.test<-model.matrix(~ .-1, data=Xtest,
+ # contrasts.arg = lapply(Xtest[,sapply(Xtest, is.factor)],
+ # contrasts, contrasts=T))
+
+ # Xmat.train<-model.matrix(~.-1,Xtrain)
+ # Xmat.test<-model.matrix(~.-1,Xtest)
+
+ # Weights
+ ytrain_weight<-as.vector(1 - (table(ytrain)[ytrain] / length(ytrain)))
+ # ytest_weight<-as.vector(1 / (table(ytest)[ytest] / length(ytest)))
+
+ # Fit regularized linear regression model
+ mod<-glmnet(Xtrain, ytrain,
+ alpha = alpha, ## Alpha = 1 for lasso
+ lambda = lambdas, ## Setting lambdas
+ standardize = TRUE, ## Scales and centers
+ weights = ytrain_weight,
+ family = "binomial"
+ )
+
+ # Keep coefficients for plot
+ B[[idx1]] <- as.matrix(coef(mod))
+
+ # Iterate over regularization strengths to compute training- and test
+ # errors for individual regularization strengths.
+ for (idx2 in 1:length(lambdas)){
+ # idx2=1
+
+ # Predict
+ yhatTrainProb<-predict(mod,
+ s = lambdas[idx2],
+ newx = data.matrix(Xtrain),
+ type = "response"
+ )
+
+ yhatTestProb<-predict(mod,
+ s = lambdas[idx2],
+ newx = data.matrix(Xtest),
+ type = "response"
+ )
+
+ # Compute training and test error
+ yhatTrain = round(yhatTrainProb)
+ yhatTest = round(yhatTestProb)
+
+ # Make predictions categorical again (instead of 0/1 coding)
+ yhatTrainCat = factor(round(yhatTrainProb),levels=c("0","1"),labels=catinfo,ordered = TRUE)
+ yhatTestCat = factor(round(yhatTestProb),levels=c("0","1"),labels=catinfo,ordered = TRUE)
+
+ # Evaluate classifier performance
+ # Accuracy
+ # accTrain[idx1,idx2] <- sum(yhatTrainCat==ytrain)/length(ytrain)
+ # accTest [idx1,idx2] <- sum(yhatTestCat==ytest)/length(ytest)
+ # #
+ # # Error rate
+ # err_train[idx1,idx2] = 1 - accTrain[idx1,idx2]
+ # err_test [idx1,idx2] = 1 - accTest[idx1,idx2]
+
+ # AUROC
+ suppressMessages(
+ auc_train[idx1,idx2]<-auc(ytrain, yhatTrainCat))
+ suppressMessages(
+ auc_test [idx1,idx2]<-auc(ytest, yhatTestCat))
+
+ # Compute confusion matrices
+ cMatTrain = cMatTrain + table(true=ytrain,pred=yhatTrainCat)
+ cMatTest = cMatTest + table(true=ytest,pred=yhatTestCat)
+ }
+}
+ls<-list(mod=mod,B=B,auc_train=auc_train,auc_test=auc_test,cMatTrain=cMatTrain,cMatTest=cMatTest)
+return(ls)
+}
diff --git a/1 PA Decline/Til DDV/regularisation_steps.R b/1 PA Decline/Til DDV/regularisation_steps.R
new file mode 100644
index 0000000..bacd072
--- /dev/null
+++ b/1 PA Decline/Til DDV/regularisation_steps.R
@@ -0,0 +1,150 @@
+## ItMLiHSmar2022
+## regularisation_steps.R, child script
+## Regularised model building and analysation for assignment
+## Andreas Gammelgaard Damsbo, agdamsbo@clin.au.dk
+##
+## Now modified to use in publication
+##
+
+## ====================================================================
+## Step 0: data import and wrangling
+## ====================================================================
+
+setwd("/Users/au301842/PhysicalActivityandStrokeOutcome/1 PA Decline/")
+
+# source("data_format.R")
+y1<-factor(as.integer(y)-1) ## Outcome is required to be factor of 0 or 1.
+
+
+## ====================================================================
+## Step 1: settings
+## ====================================================================
+
+## Folds
+K=10
+set.seed(3)
+c<-caret::createFolds(y=y,
+ k = K,
+ list = FALSE,
+ returnTrain = TRUE) # Foldids for alpha tuning
+
+## Defining tuning parameters
+lambdas=2^seq(-10, 5, 1)
+alphas<-seq(0,1,.1)
+
+## Weights for models
+weighted=TRUE
+if (weighted == TRUE) {
+ wght<-as.vector(1 - (table(y)[y] / length(y)))
+} else {
+ wght <- rep(1, nrow(y))
+}
+
+
+## Standardise numeric
+## Centered and
+
+
+
+## ====================================================================
+## Step 2: all cross validations for each alpha
+## ====================================================================
+
+library(furrr)
+library(purrr)
+library(doMC)
+registerDoMC(cores=6)
+
+# Nested CVs with analysis for all lambdas for each alpha
+#
+set.seed(3)
+cvs <- future_map(alphas, function(a){
+ cv.glmnet(model.matrix(~.-1,X),
+ y1,
+ weights = wght,
+ lambda=lambdas,
+ type.measure = "deviance", # This is standard measure and recommended for tuning
+ foldid = c, # Per recommendation the folds are kept for alpha optimisation
+ alpha=a,
+ standardize=TRUE,
+ family=quasibinomial,
+ keep=TRUE) # Same as binomial, but not as picky
+})
+
+## ====================================================================
+# Step 3: optimum lambda for each alpha
+## ====================================================================
+
+
+# For each alpha, lambda is chosen for the lowest meassure (deviance)
+each_alpha <- sapply(seq_along(alphas), function(id) {
+ each_cv <- cvs[[id]]
+ alpha_val <- alphas[id]
+ index_lmin <- match(each_cv$lambda.min,
+ each_cv$lambda)
+ c(lamb = each_cv$lambda.min,
+ alph = alpha_val,
+ cvm = each_cv$cvm[index_lmin])
+})
+
+# Best lambda
+best_lamb <- min(each_alpha["lamb", ])
+
+# Alpha is chosen for best lambda with lowest model deviance, each_alpha["cvm",]
+best_alph <- each_alpha["alph",][each_alpha["cvm",]==min(each_alpha["cvm",]
+ [each_alpha["lamb",] %in% best_lamb])]
+
+## https://stackoverflow.com/questions/42007313/plot-an-roc-curve-in-r-with-ggplot2
+p_roc<-roc.glmnet(cvs[[1]]$fit.preval, newy = y)[[match(best_alph,alphas)]]|> # Plots performance from model with best alpha
+ ggplot(aes(FPR,TPR)) +
+ geom_step() +
+ coord_cartesian(xlim=c(0,1), ylim=c(0,1)) +
+ geom_abline()+
+ theme_bw()
+
+## ====================================================================
+# Step 4: Creating the final model
+## ====================================================================
+
+source("regular_fun.R") # Custom function
+optimised_model<-regular_fun(X,y1,K,lambdas=best_lamb,alpha=best_alph)
+# With lambda and alpha specified, the function is just a k-fold cross-validation wrapper,
+# but keeps model performance figures from each fold.
+
+list2env(optimised_model,.GlobalEnv)
+# Function outputs a list, which is unwrapped to Env.
+# See source script for reference.
+
+## ====================================================================
+# Step 5: creating table of coefficients for inference
+## ====================================================================
+
+Bmatrix<-matrix(unlist(B),ncol=10)
+Bmedian<-apply(Bmatrix,1,median)
+Bmean<-apply(Bmatrix,1,mean)
+
+reg_coef_tbl<-tibble(
+ name = c("Intercept",Hmisc::label(X)),
+ medianX = round(Bmedian,5),
+ ORmed = round(exp(Bmedian),5),
+ meanX = round(Bmean,5),
+ ORmea = round(exp(Bmean),5))%>%
+ # arrange(desc(abs(medianX)))%>%
+ gt()
+
+## ====================================================================
+# Step 6: plotting predictive performance
+## ====================================================================
+
+reg_cfm<-confusionMatrix(cMatTest)
+reg_auc_sum<-summary(auc_test[,1])
+
+## ====================================================================
+# Step 7: Packing list to save in loop
+## ====================================================================
+
+ls[[i]] <- list("RegularisedCoefs"=reg_coef_tbl,
+ "bestA"=best_alph,
+ "bestL"=best_lamb,
+ "ConfusionMatrx"=reg_cfm,
+ "AUROC"=reg_auc_sum)
diff --git a/1 PA Decline/Til DDV/standardise.R b/1 PA Decline/Til DDV/standardise.R
new file mode 100644
index 0000000..2521e6d
--- /dev/null
+++ b/1 PA Decline/Til DDV/standardise.R
@@ -0,0 +1,41 @@
+## ItMLiHSmar2022
+## standardise.R, child script
+## Data standardisation, returns list
+## Andreas Gammelgaard Damsbo, agdamsbo@clin.au.dk
+
+standardise<-function(train,test,type){
+ # From:
+ # https://datascience.stackexchange.com/questions/13971/standardization-normalization-test-data-in-r
+
+ sel<-sapply(Xtrain,is.numeric) # Deciding which to stadardise (only numeric)
+ cnm<-colnames(Xtrain) # Saving column names for ordering
+
+ # Subsetting
+
+ ## Data to treat
+ train.tr<-train[,sel]
+ test.tr<-test[,sel]
+
+ ## Data to save
+ train.sv<-train[,!sel]
+ test.sv<-test[,!sel]
+
+ # Calculate mean and SD of train data
+ trainMean <- sapply(train.tr,mean)
+ trainSd <- sapply(train.tr,sd)
+
+ if (type=="c"){
+ ## centered
+ norm.trainData<-sweep(train.tr, 2L, trainMean) # using the default "-" to subtract mean column-wise
+ norm.testData<-sweep(test.tr, 2L, trainMean) # using the default "-" to subtract mean column-wise
+ }
+
+ if (type=="cs"){
+ ## centered AND scaled (Z-score standardisation)
+ norm.trainData<-sweep(sweep(train.tr, 2L, trainMean), 2, trainSd, "/")
+ norm.testData<-sweep(sweep(test.tr, 2L, trainMean), 2, trainSd, "/")
+ }
+ return(list(XtrainSt=cbind(norm.trainData,train.sv)[,cnm], # Reordering columns to original
+ XtestSt=cbind(norm.testData,test.sv)[,cnm]))
+}
+
diff --git a/1 PA Decline/archive/.DS_Store b/1 PA Decline/archive/.DS_Store
new file mode 100644
index 0000000..ada98ef
Binary files /dev/null and b/1 PA Decline/archive/.DS_Store differ
diff --git a/1 PA Decline/archive/dataset.R b/1 PA Decline/archive/dataset.R
new file mode 100644
index 0000000..b49348d
--- /dev/null
+++ b/1 PA Decline/archive/dataset.R
@@ -0,0 +1,98 @@
+# Data
+## Import from previous work
+dta<-read.csv("/Volumes/Data/exercise/source/background.csv",na.strings = c("NA","","unknown"),colClasses = "character")
+
+## Cleaning and enhancing
+dta$pase_drop<-factor(ifelse((dta$pase_0_q=="q_2"|dta$pase_0_q=="q_3"|dta$pase_0_q=="q_4")&dta$pase_06_q=="q_1","yes","no"),levels = c("no","yes"))
+dta$pase_drop[is.na(dta$pase_6)]<-NA
+dta$pase_drop[is.na(dta$pase_0)]<-NA
+
+## Selection of data set and formatting
+library(dplyr)
+dta_f<-dta %>% filter(pase_0_q != "q_1" & !is.na(pase_drop))
+
+
+variable_names<-c("age","sex","weight","height",
+ "bmi",
+ "smoke_ever",
+ "civil",
+ "diabetes",
+ "hypertension",
+ "pad",
+ "afli",
+ "ami",
+ "tci",
+ "nihss_0",
+ "thrombolysis",
+ "thrombechtomy",
+ "rep_any","pase_0_q","pase_drop")
+
+
+library(daDoctoR)
+dta2<-dta_f[,variable_names]
+
+dta2<-col_num(c("age","weight","height","bmi","nihss_0"),dta2)
+dta2<-col_fact(c("sex","smoke_ever","civil","diabetes", "hypertension","pad", "afli", "ami", "tci","thrombolysis", "thrombechtomy","rep_any","pase_0_q","pase_drop"),dta2)
+
+## Partitioning
+library(caret)
+set.seed(100)
+
+## Step 1: Get row numbers for the training data
+trainRowNumbers <- createDataPartition(dta2$pase_drop, p=0.8, list=FALSE)
+
+## Step 2: Create the training dataset
+trainData <- dta2[trainRowNumbers,]
+
+## Step 3: Create the test dataset
+testData <- dta2[-trainRowNumbers,]
+y_test = testData[,"pase_drop"]
+
+# Store X and Y for later use.
+x = trainData %>% select(!matches("pase_drop"))
+y = trainData[,"pase_drop"]
+
+# Normalization and dummy binaries
+
+# One-Hot Encoding
+# Creating dummy variables is converting a categorical variable to as many binary variables as here are categories.
+dummies_model <- dummyVars(pase_drop ~ ., data=trainData)
+
+# Create the dummy variables using predict. The Y variable (Purchase) will not be present in trainData_mat.
+trainData_mat <- predict(dummies_model, newdata = trainData)
+
+# # Convert to dataframe
+trainData <- data.frame(trainData_mat)
+
+# # See the structure of the new dataset
+str(trainData)
+
+dummies_model <- dummyVars(pase_drop ~ ., data=testData)
+testData_mat <- predict(dummies_model, newdata = testData)
+testData <- data.frame(testData_mat)
+preProcess_range_model <- preProcess(testData, method='range')
+testData <- predict(preProcess_range_model, newdata = testData)
+testData$pase_drop<-y_test
+
+# Imputation
+
+library(RANN) # required for knnInpute
+preProcess_missingdata_model <- preProcess(trainData, method='knnImpute')
+# preProcess_missingdata_model
+
+trainData <- predict(preProcess_missingdata_model, newdata = trainData) # Giver fejl??
+anyNA(trainData)
+
+# skimr::skim(trainData)
+# skimr::skim(x)
+
+preProcess_range_model <- preProcess(trainData, method='range')
+trainData <- predict(preProcess_range_model, newdata = trainData)
+
+# Append the Y variable
+trainData$pase_drop <- y
+
+
+# Export
+write.csv(trainData,"/Users/au301842/PhysicalActivityandStrokeOutcome/data/trainData.csv",row.names = FALSE)
+write.csv(testData,"/Users/au301842/PhysicalActivityandStrokeOutcome/data/testData.csv",row.names = FALSE)
diff --git a/1 PA Decline/archive/generation_1/.DS_Store b/1 PA Decline/archive/generation_1/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/1 PA Decline/archive/generation_1/.DS_Store differ
diff --git a/1 PA Decline/archive/generation_1/00master.R b/1 PA Decline/archive/generation_1/00master.R
new file mode 100644
index 0000000..729c79d
--- /dev/null
+++ b/1 PA Decline/archive/generation_1/00master.R
@@ -0,0 +1,409 @@
+##
+## Master script
+##
+## Based on the assignment work from the ISL-course
+##
+##
+##
+
+## ====================================================================
+# Step 0: Primary outcome
+## ====================================================================
+
+# Difs
+rel_dif <- 20 # 20 % difference
+abs_dif <- 20 # 20 point diff
+
+# pout <- "diff"
+#
+# Note:: By increasing the relative decline, the sensitivity increases and specificity declines.
+# This fact is an argument against over fitting. The reason being the nature of the clinical data and the fact, that predicting PA is difficult (!)
+#
+pout <- "drop" # Drop to first quartile
+
+# decl_rel
+# decl_abs
+# drop
+# hop
+
+
+## ====================================================================
+## Data
+## ====================================================================
+
+
+setwd("/Users/au301842/PhysicalActivityandStrokeOutcome/1 PA Decline/")
+
+source("data_set.R")
+# Loading data-set from USB, to not store on computer
+
+source("data_format.R")
+
+## ====================================================================
+# Libraries
+## ====================================================================
+
+
+library(tidyverse)
+library(glue)
+library(patchwork)
+# library(ggdendro)
+library(corrplot)
+library(gt)
+library(gtsummary)
+
+
+## ====================================================================
+##
+## Baseline
+##
+## ====================================================================
+
+
+## ====================================================================
+# Step 0: labels
+## ====================================================================
+
+
+lbs<-var.labels[match(colnames(X_tbl),
+ names(var.labels))]
+
+ls<-lapply(1:ncol(X_tbl),function(x){
+ as.formula(paste0(names(lbs)[x],"~","\"",lbs[x],"\""))
+})
+
+ts<-tbl_summary(X_tbl|>filter(pase_0_cut!="1"),
+ by = "group",
+ missing = "no",
+ # label = ls[-length(ls)], ## Removing the last, as this is output
+ value = list(where(is.factor) ~ "2"),
+ type = list(mrs_0 ~ "categorical"),
+ statistic = list(all_continuous() ~ "{median} ({p25};{p75}) [{min},{max}]")
+)%>%
+ add_overall() %>%
+ add_n()%>%
+ as_gt()
+
+ts
+
+ts_rtf <- file("table1.RTF", "w")
+writeLines(ts%>%as_rtf(), ts_rtf)
+close(ts_rtf)
+
+
+
+## ====================================================================
+# Step 1: labels
+## ====================================================================
+lbs<-var.labels[match(colnames(X_tbl_f), names(var.labels))]
+
+ls<-lapply(1:ncol(X_tbl_f),function(x){
+ as.formula(paste0(names(lbs)[x],"~","\"",lbs[x],"\""))
+})
+
+## ====================================================================
+# Step 2: table - edited
+## ====================================================================
+
+ts_e<-tbl_summary(X_tbl,
+ missing = "no",
+ value = list(where(is.factor) ~ "2"),
+ type = list(mrs_0 ~ "categorical",
+ mrs_1 ~ "categorical"),
+ statistic = list(all_continuous() ~ "{median} ({p25};{p75}) [{min},{max}]")
+)%>%
+ as_gt()
+
+ts_e
+
+## ====================================================================
+# Step 3: table export
+## ====================================================================
+
+ts_rtf <- file("table1_overall.RTF", "w")
+writeLines(ts%>%as_rtf(), ts_rtf)
+close(ts_rtf)
+
+## ====================================================================
+# Baseline table - by PASE group
+## ====================================================================
+
+ts_q <- X_tbl |>
+ select(vars) |>
+ mutate(pase_0_cut = factor(quantile_cut(pase_0, groups = 4)[[1]],ordered = TRUE)) |>
+ select(-pase_6,-pase_0) |>
+ tbl_summary(missing = "no",
+ by="pase_0_cut",
+ value = list(where(is.factor) ~ "2"),
+ type = list(mrs_0 ~ "categorical"),
+ statistic = list(all_continuous() ~ "{median} ({p25};{p75}) [{min},{max}]")
+) |>
+ add_overall() |>
+ add_n ()
+
+ts_q
+
+## ====================================================================
+# Drops and hops
+## ====================================================================
+
+# TRUEs are patients dropping
+table(X_tbl$pase_0_cut!="1"&X_tbl$pase_6_cut=="1")/nrow(X_tbl[X_tbl$pase_0_cut!="1",])
+
+# TRUEs are percentage of patients inactive before stroke being more active after
+table(X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut!="1")/nrow(X_tbl[X_tbl$pase_0_cut=="1",])
+
+# TRUEs are percentage of patients being more active after that were inactive before stroke
+table(X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut!="1")/nrow(X_tbl[X_tbl$pase_6_cut!="1",])
+
+# Difference between hop/no-hop
+t.test(X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut!="1","pase_0"],X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_0"])
+
+summary(X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut!="1","pase_0"])
+
+summary(X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_0"])
+
+boxplot(X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut!="1","pase_0"],X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_0"])
+
+# Stationary low
+t.test(X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_0"],X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_6"])
+
+boxplot(X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_0"],X_tbl[X_tbl$pase_0_cut=="1"&X_tbl$pase_6_cut=="1","pase_6"])
+
+## ====================================================================
+# Sankey plot
+## ====================================================================
+
+if (pout=="drop"){
+ source("sankey.R")
+ p_delta
+}
+
+
+## ====================================================================
+# Six months PASE: Bivariate and multivariate analyses
+## ====================================================================
+
+dta_lmreg <- X_tbl |>
+ select(vars) |>
+ mutate(mrs_0=factor(ifelse(mrs_0==1,1,2)))
+
+Hmisc::label(dta_lmreg$mrs_0) <- "Pre-stroke mRS >0"
+
+uv_reg <- tbl_uvregression(data=dta_lmreg,
+ method=lm,
+ y="pase_6",
+ show_single_row = where(is.factor),
+ estimate_fun = ~style_sigfig(.x,digits = 3),
+ pvalue_fun = ~style_pvalue(.x, digits = 3)
+)
+
+mu_reg <- dta_lmreg |>
+ lm(formula=pase_6~.,data=_) |>
+ tbl_regression(show_single_row = where(is.factor),
+ estimate_fun = ~style_sigfig(.x,digits = 3),
+ pvalue_fun = ~style_pvalue(.x, digits = 3)
+ )|>
+ add_n()
+
+tbl_merge(list(uv_reg,mu_reg))
+
+
+## ====================================================================
+##
+## Data variance
+##
+## Illustrating principal components.
+##
+## ====================================================================
+
+
+# source("PCA.R")
+#
+#
+# pca22
+# ggsave("pc_plot.png",width = 18, height = 12, dpi = 300, limitsize = TRUE, units = "cm")
+
+
+## ====================================================================
+##
+## Models
+##
+## ====================================================================
+
+
+source("assign_full.R")
+source("regularisation_steps.R")
+
+## ====================================================================
+# Step 1: data merge
+## ====================================================================
+tbl<-merge(reg_coef_tbl$'_data',full_coef_tbl$'_data',by="name",all.x=T, sort=F)
+
+## ====================================================================
+# Step 2: table
+## ====================================================================
+com_coef_tbl<-tbl%>%
+ gt()%>%
+ fmt_number(
+ columns=colnames(tbl)[sapply(tbl,is.numeric)], ## Selecting all numeric
+ rows = everything(),
+ decimals = 3)%>%
+ tab_spanner(
+ label = "Full model",
+ columns = 6:8
+ )%>%
+ tab_spanner(
+ label = paste0("Regularised model, (a=",
+ best_alph,
+ ", l=",
+ round(best_lamb,3),
+ ")"),
+ columns = 2:5
+ )%>%
+ tab_header(
+ title = "Model coefficients",
+ subtitle = "Combined table of both full and regularised model coefficients"
+ )
+
+com_coef_tbl
+
+## ====================================================================
+# Step 3: export
+## ====================================================================
+com_coef_rtf <- file("table2.RTF", "w")
+writeLines(com_coef_tbl%>%as_rtf(), com_coef_rtf)
+close(com_coef_rtf)
+
+
+
+## ====================================================================
+##
+## Model performance
+##
+## Table with performance meassures for the two different models.
+##
+## ====================================================================
+
+# ROC curve of best model
+
+p_roc
+ggsave("roc_plot.png",width = 12, height = 12, dpi = 300, limitsize = TRUE, units = "cm")
+
+
+## ====================================================================
+# Step 1: data set
+## ====================================================================
+tbl<-data.frame(Meassure=c(names(full_cfm$byClass),"Mean AUC"),
+ "Regularised model"=round(c(reg_cfm$byClass,reg_auc_sum["Mean"]),3),
+ "Full model"=round(c(full_cfm$byClass,full_auc_sum["Mean"]),3))
+
+## ====================================================================
+# Step 2: table
+## ====================================================================
+tbl_perf<-tbl%>%
+ gt()%>%
+ tab_header(
+ title = "Performance meassures",
+ subtitle = "Combined table of both full and regularised performance meassures"
+ )
+
+tbl_perf
+
+## ====================================================================
+# Step 3: export
+## ====================================================================
+tbl_perf_rtf <- file("table3.RTF", "w")
+writeLines(tbl_perf%>%as_rtf(), tbl_perf_rtf)
+close(tbl_perf_rtf)
+#
+
+## ====================================================================
+##
+## Secondary analysis
+##
+## ====================================================================
+
+Xy<-dta_s
+X<-dta_s|>select(-group)
+y<-dta_s$group
+
+
+source("assign_full.R")
+source("regularisation_steps.R")
+
+## ====================================================================
+# Step 1: data merge
+## ====================================================================
+tbl<-merge(reg_coef_tbl$'_data',full_coef_tbl$'_data',by="name",all.x=T, sort=F)
+
+## ====================================================================
+# Step 2: table
+## ====================================================================
+com_coef_tbl<-tbl%>%
+ gt()%>%
+ fmt_number(
+ columns=colnames(tbl)[sapply(tbl,is.numeric)], ## Selecting all numeric
+ rows = everything(),
+ decimals = 3)%>%
+ tab_spanner(
+ label = "Full model",
+ columns = 6:8
+ )%>%
+ tab_spanner(
+ label = paste0("Regularised model, (a=",
+ best_alph,
+ ", l=",
+ round(best_lamb,3),
+ ")"),
+ columns = 2:5
+ )%>%
+ tab_header(
+ title = "Model coefficients",
+ subtitle = "Combined table of both full and regularised model coefficients"
+ )
+
+com_coef_tbl
+
+## ====================================================================
+# Step 3: export
+## ====================================================================
+com_coef_rtf <- file("table2_sec.RTF", "w")
+writeLines(com_coef_tbl%>%as_rtf(), com_coef_rtf)
+close(com_coef_rtf)
+
+
+## ====================================================================
+##
+## Model performance
+##
+## Table with performance meassures for the two different models.
+##
+## ====================================================================
+
+
+## ====================================================================
+# Step 1: data set
+## ====================================================================
+tbl<-data.frame(Meassure=c(names(full_cfm$byClass),"Mean AUC"),
+ "Regularised model"=round(c(reg_cfm$byClass,reg_auc_sum["Mean"]),3),
+ "Full model"=round(c(full_cfm$byClass,full_auc_sum["Mean"]),3))
+
+## ====================================================================
+# Step 2: table
+## ====================================================================
+tbl_perf<-tbl%>%
+ gt()%>%
+ tab_header(
+ title = "Performance meassures",
+ subtitle = "Combined table of both full and regularised performance meassures"
+ )
+
+tbl_perf
+
+## ====================================================================
+# Step 3: export
+## ====================================================================
+tbl_perf_rtf <- file("table3_sec.RTF", "w")
+writeLines(tbl_perf%>%as_rtf(), tbl_perf_rtf)
+close(tbl_perf_rtf)
diff --git a/1 PA Decline/archive/generation_1/PCA.R b/1 PA Decline/archive/generation_1/PCA.R
new file mode 100644
index 0000000..c659cb0
--- /dev/null
+++ b/1 PA Decline/archive/generation_1/PCA.R
@@ -0,0 +1,74 @@
+## ItMLiHSmar2022
+## PCA.R, child script
+## Principal components analysis for data visualisation
+## Andreas Gammelgaard Damsbo, agdamsbo@clin.au.dk
+
+
+## ====================================================================
+## Step 0: data wrangling
+## ====================================================================
+# source("data_format.R")
+
+X1<-X %>% dplyr::mutate(across(where(is.factor), as.numeric))
+
+pc.out<-prcomp(X1, center=TRUE, scale = TRUE)
+
+pc.sum<-summary(pc.out)
+
+## ====================================================================
+## Step 1: plotting
+## ====================================================================
+Xy$group<-factor(Xy$group,labels = c("No decline", "Decline"))
+
+library(ggfortify)
+ppc12 <- autoplot(pc.out,
+ data = Xy,
+ x=1,
+ y=2,
+ colour = 'group')+
+ labs(title = "PC1 and PC2",
+ colour = "Outcome")
+ppc13 <- autoplot(pc.out,
+ data = Xy,
+ x=1,
+ y=3,
+ colour = 'group')+
+ labs(title = "PC1 and PC3",
+ colour = "Outcome")
+ppc23 <- autoplot(pc.out,
+ data = Xy,
+ x=2,
+ y=3,
+ colour = 'group')+
+ labs(title = "PC2 and PC3",
+ colour = "Outcome")
+
+# Scree plot
+pscr<-tibble(x=1:dim(pc.sum$importance)[2],
+ Proportion=pc.sum$importance[2,],
+ Cumulative=pc.sum$importance[3,])%>%
+ pivot_longer(cols=-x)%>%
+ ggplot(aes(x=x,y=value,color=name))+
+ geom_line()+
+ geom_point()+
+ ylim(0,1)+
+ labs(title = "Scree plot",
+ color= "Variance")+
+ ylab("Variance")+
+ xlab("Principal components")
+
+## ====================================================================
+## Step 2: merge plots
+## ====================================================================
+library(patchwork)
+pca22<-ppc12+
+ theme(legend.position="none")+
+ ppc13+
+ ppc23+theme(legend.position="none")+
+ pscr+
+ plot_layout(ncol=2)+
+ plot_annotation(title = 'Principal component visualisation',
+ tag_levels = "A")
+
+# pca22
+
diff --git a/1 PA Decline/archive/generation_1/assign_full.R b/1 PA Decline/archive/generation_1/assign_full.R
new file mode 100644
index 0000000..d6e4b2f
--- /dev/null
+++ b/1 PA Decline/archive/generation_1/assign_full.R
@@ -0,0 +1,141 @@
+## ItMLiHSmar2022
+## assign_full.R, child script
+## Full model building and analysation for assignment
+## Andreas Gammelgaard Damsbo, agdamsbo@clin.au.dk
+
+## ====================================================================
+## Step 0: data import and wrangling
+## ====================================================================
+
+# source("data_format.R")
+
+## ====================================================================
+## Step 1: settings
+## ====================================================================
+K<-10
+n<-nrow(X)
+set.seed(321)
+
+# Using caret function to ensure both levels represented in all folds
+c<-createFolds(y=y, k = K, list = FALSE, returnTrain = TRUE)
+
+B<-list()
+auc_train<-auc_test<-c()
+
+catinfo<-levels(y)
+
+cMatTrain<-cMatTest<-table(factor(c(0,0),levels=catinfo),factor(c(0,0),levels=catinfo))
+
+## ====================================================================
+## Step 2: cross validation
+## ====================================================================
+
+set.seed(321)
+## Iterate over partitions
+for (idx1 in 1:K){
+
+ # Status
+ cat('Processing fold', idx1, 'of', K,'\n')
+
+ # idx1=1
+ # Get training- and test sets
+ I_train = c!=idx1 ## Creating selection vector of TRUE/FALSE
+ I_test = !I_train
+
+ Xtrain = X[I_train,]
+ ytrain = y[I_train]
+ Xtest = X[I_test,]
+ ytest = y[I_test]
+
+ # Z-score standardisation
+ source("standardise.R")
+ list2env(standardise(Xtrain,Xtest,type="cs"),.GlobalEnv)
+ ## Outputs XtrainSt and XtestSt
+ ## Standardised by centering and scaling
+
+
+ ## Model matrices for glmnet
+ # Xmat.train<-model.matrix(~.-1,XtrainSt)
+ # Xmat.test<-model.matrix(~.-1,XtestSt)
+
+ # Weights
+ ytrain_weight<-as.vector(1 - (table(ytrain)[ytrain] / length(ytrain)))
+
+ # Fit regularized linear regression model
+ mod<-glm(ytrain~.,
+ data=XtrainSt,
+ weights = ytrain_weight,
+ family = stats::quasibinomial(link = "logit"))
+
+ # Keep coefficients for plot
+ B[[idx1]] <- mod
+
+ # Predict
+ yhatTrainProb<-predict(mod,
+ newdata = XtrainSt,
+ type = "response"
+ )
+
+ yhatTestProb<-predict(mod,
+ newdata = XtestSt,
+ type = "response"
+ )
+
+ # Compute training and test error
+ yhatTrain = round(yhatTrainProb)
+ yhatTest = round(yhatTestProb)
+
+ # Make predictions categorical again (instead of 0/1 coding)
+ yhatTrainCat = factor(round(yhatTrainProb),levels=c("0","1"),labels=catinfo,ordered = TRUE)
+ yhatTestCat = factor(round(yhatTestProb),levels=c("0","1"),labels=catinfo,ordered = TRUE)
+ # Compute confusion matrices
+ cMatTrain = cMatTrain + table(ytrain,yhatTrainCat)
+ cMatTest = cMatTest + table(ytest,yhatTestCat)
+
+ # AUROC
+ suppressMessages(
+ auc_train[idx1]<-auc(ytrain, yhatTrainCat))
+ suppressMessages(
+ auc_test [idx1]<-auc(ytest, yhatTestCat))
+}
+
+## ====================================================================
+# Step 3: creating table of coefficients for inference
+## ====================================================================
+
+confs<-lapply(1:K, function(x){
+ cs<-exp(confint(B[[x]]))
+ lo<-cs[,1]
+ hi<-cs[,2]
+ return(list(lo=lo,hi=hi))
+})
+
+coefs<-apply(Reduce('cbind', lapply(B,"[[", "coefficients")),1,mean)
+
+unlist(strsplit(names(B[[1]]$coefficients),2))
+
+var.labels<-c(var.labels,'(Intercept)'="Intercept")
+
+ds<-tibble(name=var.labels[match(unlist(strsplit(names(coefs),2)), names(var.labels))],
+ coefs=coefs,
+ OR=round(exp(coefs),3),
+ CIs=paste0("(",
+ round(apply(Reduce('cbind', lapply(confs,"[[", "lo")),1,mean),3),
+ ",",
+ round(apply(Reduce('cbind', lapply(confs,"[[", "hi")),1,mean),3),
+ ")")
+ )
+
+#
+full_coef_tbl<-ds%>%
+ gt(rowname_col = list(age~"Age"))
+#
+full_coef_tbl
+
+## ====================================================================
+# Step 4: plotting classification performance
+## ====================================================================
+
+full_cfm<-confusionMatrix(cMatTest)
+full_auc_sum<-summary(auc_test)
+
diff --git a/1 PA Decline/archive/generation_1/assigndata.csv b/1 PA Decline/archive/generation_1/assigndata.csv
new file mode 100644
index 0000000..501729c
--- /dev/null
+++ b/1 PA Decline/archive/generation_1/assigndata.csv
@@ -0,0 +1,643 @@
+"pase_0","age","sex","civil","smoke_ever","rtreat","alc","afli","hypertension","diabetes","mrs_0","nihss_c","thrombolysis","pad","thrombechtomy","ami","tci","pase_drop","pase_6","mrs_1","mfi_gen_1","mdi_1","who5_score_1"
+"377.44","76","male","partner","never","Placebo","guideline","no","yes","no","0","2","yes","no","no","yes","no","no","260.52","0","10","6","84"
+"277","49","male","partner","never","Placebo","guideline","no","no","no","0","4","no","no","no","no","no","no","113.11","2","12","11","64"
+"192.4","43","male","alone","never","Placebo","guideline","no","yes","yes","0","2","yes","no","no","no","no","no","123.05","4","12","3","76"
+"30","89","female","alone","ever","Placebo","guideline","yes","no","no","0","3","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"44.14","80","male","partner","ever","Active","guideline","no","no","no","2","4","no","no","no","no","no","no","135.15","3","16","11","64"
+"128.76","72","male","partner","never","Placebo","guideline","no","yes","no","0","1","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"224.54","71","female","partner","ever","Placebo","guideline","no","yes","no","0","1","no","no","no","no","no","no","197.78","1","8","1","80"
+"100","66","female","alone","never","Active","guideline","no","no","no","0","4","no","no","yes","no","no","yes","32.36","4","17","14","52"
+"144.8","64","male","partner","never","Placebo","guideline","no","no","no","0","3","no","no","no","no","no","no","191.84","1","14","3","84"
+"136.8","64","male","partner","never","Placebo","guideline","no","yes","no","0","3","no","yes","no","no","no","yes","9.7","2","10","7","36"
+"134.33","65","female","alone","ever","Placebo","guideline","no","yes","yes","0","2","no","no","no","no","no","no","178.97","2","10","4","80"
+"118.2","63","male","partner","never","Active","guideline","no","yes","no","0","9","yes","no","no","no","no","yes","33.14","2","4","3","48"
+"99.28","62","male","partner","never","Active","more","no","yes","no","0","1","no","no","no","no","no","no","209.68","1","15","9","48"
+"101.3","73","male","partner","never","Placebo","more","no","no","no","1","16","yes","no","yes","no","no","yes","34.6","1","14","12","0"
+"75.5","59","female","alone","never","Placebo","guideline","no","no","no","0","5","no","no","no","no","no","no","123.97","2","20","22","44"
+"81","73","male","partner","never","Active","guideline","no","yes","no","0","2","no","no","no","yes","no","no","184.4","1","16","10","44"
+"79.08","70","male","partner","never","Active","guideline","yes","no","no","0","5","yes","no","no","no","no","no","235.75","2","17","9","60"
+"27.2","83","male","partner","never","Active","guideline","no","yes","no","0","3","no","no","no","no","no","no","81","0","6","3","68"
+"173.25","80","male","partner","ever","Active","guideline","no","yes","no","0","5","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"255.8","63","male","alone","never","Placebo","guideline","no","no","no","0","9","no","no","no","no","no","no","121.4","1","4","5","84"
+"27.2","82","male","alone","never","Active","guideline","no","yes","no","0","3","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"329.51","72","male","partner","ever","Placebo","guideline","yes","no","no","1","11","yes","no","no","no","no","no","506.35","2","11","2","80"
+"199.91","58","female","alone","ever","Active","guideline","no","yes","no","0","0","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"218.09","64","male","partner","ever","Active","guideline","no","no","no","0","2","no","no","no","no","no","no","117.25","0","4","1","92"
+"166.8","49","female","partner","ever","Placebo","guideline","no","no","no","0","5","no","no","no","no","no","no","183.58","0","5","6","76"
+"25","99","female","alone","ever","Placebo","guideline","yes","no","no","0","8","yes","no","no","no","no","no","8.82","2","12","14","52"
+"90","79","female","alone","never","Placebo","guideline","no","yes","no","0","2","yes","no","no","yes","yes","no","136.4","0","16","11","96"
+"232.71","60","male","partner","never","Active","guideline","no","yes","no","0","5","no","no","no","no","no","no","228.25","2","12","9","72"
+"208.24","51","male","alone","never","Placebo","guideline","no","no","no","0","10","no","no","no","no","no","no","98.14","2","12","4","76"
+"28.11","77","male","alone","never","Placebo",NA,"yes","yes","no","0","9","no","no","no","no","no","no","8.4","4","10","14","52"
+"116","54","female","partner","never","Active","guideline","no","yes","no","0","6","no","no","no","no","no","no","110.32","0",NA,NA,"0"
+"271.5","71","female","partner","ever","Placebo","guideline","no","yes","no","0","16","yes","no","no","no","no","no","288.88","3","13","10","72"
+"155.8","67","female","alone","never","Placebo","more","no","yes","no","0","1","no","yes","no","no","no","no","207.4","0","6","0","100"
+"116.4","31","male","alone","never","Active","guideline","no","no","no","0","5","no","no","no","no","no","no","81.32","1","4","5","92"
+"88.76","72","female","partner","never","Active","guideline","yes","yes","no","1","5","no","no","no","no","no","no","126.65","1","11","8","64"
+"78.48","71","female","partner","never","Active","guideline","no","no","no","1","15","yes","no","no","no","no","no","152.22","0","4","4","80"
+"98.68","75","female","partner","ever","Active","guideline","no","no","no","0","4","no","no","no","no","no","yes","60.83","2","9","3","84"
+"183.3","78","male","partner","never","Active","guideline","no","no","no","0","2","no","no","no","no","no","no","240.04","1","12","1","76"
+"192.5","74","male","partner","never","Active","guideline","no","no","no","0","3","yes","no","no","no","no",NA,NA,NA,NA,NA,NA
+"217.82","62","female","partner","ever","Placebo","guideline","no","yes","no","1","3","yes","no","no","no","no","no","185.18","1","11","6","64"
+"144.4","86","male","partner","ever","Active","guideline","no","yes","no","0","2","yes","no","no","no","no","no","171.37","1","5","5","84"
+"85","82","male","partner","never","Active","guideline","no","yes","no","0","3","yes","no","no","no","no","yes","62.8","0","20","18","48"
+"168.87","60","female","partner","never","Active","guideline","no","yes","no","0","0","no","no","no","no","no","no","230.14","2","15","14","40"
+"115.56","63","female","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","no","188.73","2","13","12","60"
+"111","53","male","partner","never","Placebo","guideline","no","no","no","0","3","yes","no","no","no","no","no","136","1","17","6","92"
+"58.53","86","female","alone","never","Active","guideline","no","yes","no","0","0","no","no","no","no","no","no","246.47","0","14","4","52"
+"75.8","75","male","partner","never","Placebo","guideline","yes","no","yes","0","2","yes","no","no","no","no","no","108.2","2","11","14","64"
+"153.01","70","female","alone","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","no","228.24","2","7","3","88"
+"114.93","63","male","partner","never","Placebo","guideline","no","no","yes","0","3","no","no","no","no","no","no","188.05","2","18","5","72"
+"243.33","57","male","alone","never","Placebo",NA,"no","no","no","0","6","no","no","yes","no","no","no","199.86","3","7","5","8"
+"218.89","77","male","alone","ever","Placebo","guideline","no","no","no","0","3","no","no","no","no","no","yes","32.09","1","5","11","88"
+"116.05","76","female","alone","ever","Active","guideline","no","no","no","0","7","no","no","no","no","no","yes","66.32","4","8","6","88"
+"126.31","65","male","partner","never","Active","guideline","yes","yes","no","0","2","yes","no","no","no","no","no","259.37",NA,NA,NA,"0"
+NA,"82","female","alone","ever","Placebo","guideline","yes","no","no","1","16","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"81.72","77","male","partner","never","Active","more","yes","yes","no","1","1","no","yes","no","no","no","yes","35.71","2",NA,NA,NA
+"155.83","63","female","alone","never","Placebo","guideline","no","no","no","0","0","no","no","no","yes","no","no","221.5","0","10","5","56"
+"136","55","male","alone","never","Placebo","guideline","no","no","no","0","7","yes","no","no","no","no",NA,NA,NA,NA,NA,NA
+"267.12","53","female","partner","never","Placebo","guideline","no","no","no","0","8","yes","no","no","no","no","no","223.62","1","17","6","60"
+NA,"73","male","alone","never","Active","guideline","no","no","no","0","7","no","no","no","no","no",NA,"42.22","3","20","29","4"
+"33.4","62","female","alone","never","Active","guideline","no","no","no","1","8","no","no","no","no","no","no","212.4",NA,NA,NA,NA
+"296","60","male","partner","never","Active","guideline","no","no","no","0","12","no","no","no","no","no","no","112.82","4","8","3","92"
+"59.2","87","female","alone","never","Active","guideline","yes","yes","no","2","4","no","no","no","no","no","no","99.66","2","14","12","72"
+"278.48","74","male","alone","never","Placebo","guideline","no","no","yes","0","4","no","no","no","no","no","no","410.61","1","6","6","80"
+"448.9","54","female","alone","ever","Active","guideline","no","yes","yes","0","3","no","no","no","no","no","no","318.91","1","18","8","48"
+"114.5","69","male","partner","never","Placebo","guideline","no","yes","no","0","10","yes","no","no","yes","no","no","105.8","1","4","1","88"
+"56","67","male","partner","never","Active","guideline","no","no","no","0","4","yes","no","no","no","no",NA,NA,NA,NA,NA,NA
+"292.24","63","male","partner","ever","Active","guideline","no","no","no","0","2","yes","no","no","yes","no","yes","52.5","3","4","4","96"
+"155.83","45","male","partner","ever","Active","guideline","no","yes","no","0","4","no","no","no","no","no","no","335.46","1","9","3","92"
+"106","78","male","alone","never","Active","guideline","no","no","no","0","4","no","no","no","no","no",NA,NA,"1","4","3","96"
+"114.4","52","male","partner","never","Active","guideline","no","yes","no","0","2","yes","no","no","yes","no","yes","31.4","1","19","22","44"
+"0","86","female","alone","never","Placebo","guideline","no","no","no","3","2","yes","no","no","no","no","no","35","3","4","0","88"
+"55","67","male","partner","never","Active","guideline","no","yes","no","0","7","no","yes","no","no",NA,"no","3.3","2","10","2","88"
+"0","76","male","partner","never","Active","guideline","no","yes","no","0","3","yes","no","no","yes","no",NA,NA,"1","16","15","44"
+"158.5","67","male","partner","ever","Active","guideline","no","yes","no","0","16","yes","no","no","no","no","no","242.07","1","14","4","80"
+"246.65","70","male","partner","ever","Placebo","guideline","no","yes","no","0","4","no","no","no","no",NA,"yes","0","1","10","10","72"
+"196","81","male","alone","never","Placebo","guideline","no","no","no","0","2","yes","no","no","no","no","yes","33.4","3","4","5","88"
+"249.9","62","male","partner","ever","Active","guideline","no","yes","no","0","1","yes","no","no","no","yes",NA,NA,NA,NA,NA,NA
+"61","64","male","partner","never","Active","guideline","no","yes","no","0","3","no","no","no","no","no","no","35.4","3","17","10","72"
+"0","60","male","alone","ever","Active","guideline","no","yes","no","2","3","no","no","no","no","no",NA,NA,"4",NA,"16","52"
+"155.91","68","male","partner","never","Active","guideline","no","no","no","0","2","no","no","no","no","no","no","158.5","1","12","12","72"
+"220.76","69","male","partner","never","Active","guideline","no","yes","no","0","3","yes","no","no","no","no","no","231.5","0","5","12","76"
+"270.4","63","male","partner","never","Placebo","guideline","no","yes","no","0","3","no","no","no","no","no","no","86.11","3","11","9","76"
+"268.72","45","male","alone",NA,"Active","guideline","no","no","no","0","0","no","no","no","no","no","no","245.77","1","13","2","72"
+"215.8","64","male","partner","ever","Placebo","guideline","no","no","no","0","6","yes","no","no","no","no","no","250.3","1","13","5","60"
+"187.4","51","female","partner","ever","Active","more","no","yes","no","0","4","no","no","no","no","no","no","140.61","2","16","5","80"
+"66.04","77","female","alone","ever","Active","guideline","no","no","no","0","2","yes","no","no","no","no","no","50","0","7","2","100"
+"74.97","83","male","partner","never","Placebo","guideline","no","yes","no","0","1","no","no","no","no","no","no","66.5","2","10","4","72"
+"133.6","63","male","partner",NA,"Placebo",NA,"no","yes","yes","0","2","no","no","no","no","no","no","111","1","8","0","80"
+"54.51","71","male","alone","never","Placebo","guideline","no","yes","yes","0","5","no","no","no","no","no","no","50.02","1","11","6","60"
+"327.72","57","male","alone","never","Active","more","no","no","no","0","0","yes","no","no","no","no","no","206.05","1","16","24","44"
+"198.66","81","male","partner","ever","Active","guideline","no","yes","no","1","7","yes","no","no","no","no","no","164.51","1","10","5","80"
+"138.2","76","male","alone","ever","Placebo","guideline","yes","yes","no","1","6","no","no","no","no","no","no","185.92","2","10","2","100"
+"91.7","74","male","alone","never","Placebo","guideline","no","yes","no","0","8","yes","yes","no","no","no",NA,NA,"6","8","2","80"
+"68.4","54","female","partner","never","Placebo","guideline","no","no","no","1","1","no","no","no","no","no","no","117.2","1","14","5","68"
+"137","44","male","partner","ever","Placebo","guideline","no","no","no","0","1","yes","no","no","no","no","no","255.14","0","8","5","72"
+"214.2","64","male","partner","never","Active","guideline","no","no","no","0","17","yes","no","yes","no","no","no","176.57","2","11","20","40"
+"85.8","52","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","no","211","2","15","10","64"
+"216.47","48","female","partner","never","Placebo","guideline","no","yes","no","0","0","no","no","no","no","no","no","255.92","1","10","5","76"
+"257.32","85","male","partner","never","Placebo","guideline","yes","yes","no","0","6","yes","no","no","no","no","no","136","3","9","4","80"
+"27.2","61","male","alone","never","Placebo","guideline","no","yes","no","0","2","yes","no","no","no","no","no","65","1","13","1","68"
+"189.71","49","female","alone","never","Active","guideline","no","yes","no","0","0","no","no","no","no","no","yes","52.2","2","20","18","24"
+"197","63","male","alone","ever","Active","guideline","no","no","no","0","2","no","no","no","no","no","no","231.73","2","15","11","52"
+"116","70","male","partner","never","Active","more","no","no","no","0","4","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"177.4","64","male","partner","ever","Active","guideline","no","yes","no","0","0","no","no","no","no","no","no","205","2","16","9","80"
+"88.2","63","male","partner","never","Placebo","guideline","no","no","no","1","28","yes","no","no","no","no",NA,NA,NA,NA,NA,NA
+"50","85","female","alone","never","Active","guideline","yes","no","no","0","27","yes","no","no","no","no",NA,NA,"6",NA,NA,NA
+"114.4","83","male","alone","ever","Active","guideline","no","no","yes","0","7","no","no","no","yes","no","no","106.8","1","8","4","80"
+"171.96","75","female","partner","never","Placebo","guideline","no","yes","no","0","1","yes","no","no","no","no","no","95.8","1","14","9","52"
+"100","72","male","partner","never","Active","guideline","no","yes","no","0","4","yes","no","yes","no","no","yes","52.53","3","4","6","92"
+"195.92","64","female","alone","ever","Placebo","guideline","no","no","no","0","2","yes","no","no","no","no","no","158.51","1","6","5","80"
+"180.22","69","male","partner","never","Placebo","guideline","yes","no","no","0","5","yes","no","no","no","no","no","190","1","4","0","100"
+"136.12","65","male","partner","never","Active","guideline","no","yes","no","0","17","yes","no","yes","no","no","no","199.16","2","16","9","68"
+NA,"73","male","alone","never","Placebo","guideline","no","yes","yes",NA,NA,"no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"22.2","66","male","partner","ever","Active","guideline","yes","yes","yes","1","4","no","no","no","no","no","no","64.11","3","14","8","84"
+"29.73","79","male","alone","never","Active","guideline","no","yes","no","0","1","no","no","no","no","no","no","31.4","1","16","4","48"
+"216.86","69","male","partner","ever","Active","guideline","yes","no","no","1","6","yes","no","yes","no","no","no","272.43","1","6","3","76"
+"226.8","55","male","partner","never","Active","guideline","no","no","yes","0","0","no","no","no","no","no","no","142.4","1","10","6","92"
+"166","81","male","alone","never","Active","more","no","no","no","0","3","yes","no","no","no","yes","no","99.7","4","4","5","92"
+"131.8","69","male","alone","never","Placebo","guideline","no","yes","no","0","16","yes","no","yes","no","no","yes","8.82","4","17","5","100"
+"161.27","53","female","partner","ever","Placebo","guideline","yes","no","no","0","2","no","no","no","no","no","no","302.77","0","16","8","80"
+"256","74","male","partner","ever","Active","guideline","yes","yes","no","0","0","no","no","no","no","no","no","311.8","1","4","1","100"
+"238.4","62","male","partner","ever","Active","more","no","no","no","0","12","yes","no","no","no","no","no","308.93","1","12","7","64"
+"252.8","51","male","partner","never","Placebo","guideline","no","no","no","0","5","yes","no","no","no","no",NA,NA,NA,NA,NA,NA
+"84.6","45","male","partner","never","Placebo","guideline","no","yes","yes","0","3","no","no","no","no","no","yes","73.61","2","16","14","60"
+"121.4","54","male","partner","never","Placebo","more","no","no","no","0","3","no","no","no","no","no",NA,NA,"0","20","29","16"
+"117.8","87","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","no","131.8","2","11","4","72"
+"113.21","79","female","partner","ever","Active","more","no","no","no","0","5","yes","no","no","no","no",NA,NA,NA,NA,NA,NA
+"82.13","69","male",NA,"never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","no","254.51","0","12","2","76"
+"30","62","male","partner","never","Placebo","more","no","no","no","0","2","yes","no","no","no","yes","no","95","2","10","13","60"
+"241.3","45","male","partner","ever","Placebo","guideline","no","no","no","0","32","yes","no","yes","no","no","no","356.97","2","11","14","80"
+"157.4","83","female","partner","ever","Active","guideline","no","no","no","1","4","no","no","no","no","no","no","175.01","3","13",NA,"52"
+"260.5","50","male","partner","ever","Active","guideline","no","no","no","0","4","no","no","no","no","no","no","238.05","1","11","2","76"
+"289","63","male","partner","never","Placebo","more","yes","no","no","0","6","yes","no","no","no","no","no","253.4","1","14","10","64"
+"30","77","female","partner","ever","Active","guideline","no","no","no","3","7","no","no","no","no","no","no","31.72","4","15","9","76"
+"25","77","male","alone","never","Active","guideline","yes","yes","yes","2","2","no","no","no","no","no","no","0","2","8","6","92"
+"130.56","37","female","alone","ever","Placebo","guideline","no","no","no","0","1","no","no","no","no","no","no","288.72","1","16","13","32"
+"59.8","81","male","alone","never","Active","more","no","yes","no","0","2","no","no","no","no","no","no","154.84","1","4","0","100"
+"116.93","71","male","partner","ever","Active","guideline","no","yes","no","0","3","yes","no","no","no","no","no","89.4","2","12","1","100"
+"286.47","50","male","partner","never","Active","guideline","no","no","no","0","3","yes","no","no","no","no","no","306.55","1","12","5","56"
+"117.22","72","female","partner","ever","Active","guideline","no","yes","no","1","4","yes","no","no","no","yes","no","196.4","1","9","3","68"
+"27.2","80","female","alone","never","Active","guideline","no","no","no","1","14","no","no","no","no","no","no","4.84","4","20","14","64"
+"211.4","51","male","partner","ever","Active","guideline","no","no","no","0","1","yes","no","no","no","no","no","288.4","2","14","11","52"
+"100","73","female","partner","ever","Active","guideline","no","yes","no","0","3","no","no","no","no","no","no","102.89","2","15","19","56"
+"298.98","52","male","partner","ever","Placebo","guideline","no","yes","no","1","7","yes","no","no","no","no","no","149.05","1","11","7","64"
+"75.8","64","male","partner","never","Placebo","more","no","no","no","0","4","no","no","no","no","no","no","224.32","1","8","10","88"
+"25","77","male","partner","never","Active","more","no","yes","no","2","6","no","yes","no","no","no","no","116.59","3","13","16","60"
+"90","58","male","alone","never","Active","guideline","yes","yes","yes","0","0","no","no","no","no","no","yes","55","1","15","13","60"
+"146.93","74","male","partner","never","Placebo","more","no","yes","no","0","5","no","no","no","no","no","no","135.1","2","15","5","72"
+"131.8","69","male","partner","never","Placebo","guideline","yes","no","no","2","3","no","no","no","no","no","no","167.45","2","5","1","92"
+"104.16","65","female","partner","ever","Placebo","guideline","yes","yes","no","0","12","yes","no","yes","yes","no","no","156.58","1","18","16","44"
+"54.51","85","male","partner","never","Placebo","more","no","yes","yes","0","2","no","no","no","no","no",NA,NA,"2","20","14","16"
+"50","81","male","alone","never","Placebo","guideline","no","no","no","0","2","no","no","no","no","no","no","115.13","1","14","6","72"
+"297.4","71","male","partner","never","Active","guideline","no","no","no","1","5","no","no","no","no","no","no","169.4","2","9","5","88"
+"131.8","67","male","partner","never","Placebo","guideline","no","yes","yes","0","5","yes","no","no","no","no","no","266.23","0","10","2","84"
+"190","61","male","alone","ever","Placebo","guideline","no","no","no","0","2","no","no","no","no","no","no","271.37","1","10","3","88"
+"191.81","58","male","alone","never","Active","more","no","no","no","0","1","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"248.3","52","male","alone","never","Active","guideline","no","no","no","0","1","no","no","no","no","no","no","161.8","1","14","6","64"
+"348.97","49","male","partner","ever","Placebo","guideline","no","no","no","1","1","yes","no","no","no","no","no","255.66","0","7","3","80"
+"252","60","male","partner","ever","Active","guideline","no","yes","no","0","1","no","no","no","no","no","no","226.08","2","14","4","68"
+"85","67","male","partner","never","Placebo","guideline","no","yes","no","0","2","yes","no","no","no","no","no","225.11","1","4","0","92"
+"161","49","male","partner","never","Placebo","guideline","no","no","no","0","2","no","no","no","no","no","no","259.5","1","5","6","84"
+"87.47","45","male","partner","never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","no","166.87","1","4","3","96"
+"167.8","83","male","partner","never","Active","guideline","yes","yes","no","0","5","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"86.72","72","female","partner","ever","Active","guideline","no","no","no","0","2","no","no","no","no","no","no","109.25","1","10","3","64"
+"116.75","67","male","alone","never","Placebo","guideline","no","yes","yes","0","4","no","no","no","yes","no","yes","62.36","3","17","15","52"
+"183.91","78","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","yes","72.91","1","5","0","92"
+"310.28","63","male","partner","never","Placebo","guideline","no","yes","no","0","13","yes","no","no","no","no","no","184.72","0","6","12","72"
+"215.8","51","female","partner","ever","Active","guideline","yes","no","no","0","2","no","no","no","no","no",NA,NA,"2","17","20","48"
+"91","72","female","partner","never","Active","guideline","no","no","no","1","7","yes","no","no","no","no","no","96.4","0","10","3","88"
+"221","44","female","alone","never","Active","guideline","no","no","yes","0","3","yes","no","no","no","no","no","146","2","18","17","44"
+"49.73","66","female","partner","never","Placebo","more","yes","no","no","0","18","yes","no","yes","no","no","no","87.09","2","12","13","80"
+"184.4","48","female","partner","never","Active","guideline","no","no","no","0","5","yes","no","yes","no","no","no","146.45","1","14","19","60"
+"64.15","76","female","partner","never","Active","guideline","yes","yes","no","2","17","yes","no","yes","no","no","no","71.48","2","18","20","48"
+"132.12","76","female","alone","ever","Active","guideline","no","yes","no","0","3","no","no","no","no","no","yes","70.52","0","9","1","88"
+"190.67","54","female","partner","never","Placebo","guideline","no","yes","no","0","4","no","no","no","no","no","no","132.56","1","12","5","56"
+"58.4","83","female","partner","ever","Active","guideline","no","yes","no","0","10","yes","no","no","no","no","no","19.45","4","11","7","88"
+"316.76","44","male","partner","never","Placebo","guideline","no","yes","no","0","4","no","no","no","no","no","no","281.83","1","4","1","100"
+NA,"84","female","partner","ever","Active","guideline","no","yes","yes","0","2","no","no","no","no","no",NA,"58.4","2","12","7","80"
+"146.9","37","male","partner","ever","Active","guideline","no","no","no","0","2","yes","no","no","no","no","no","227.83","1","14","9","72"
+"152.4","69","male","partner","never","Active","guideline","no","yes","no","0","4","no","no","no","no","no","no","88.3","1","11","18","68"
+"212.4","81","male","partner","never","Placebo","guideline","no","no","no","1","3","no","no","no","no","no","no","108.34","0","10","1","92"
+"237.2","80","male","partner","never","Placebo","guideline","no","no","no","0","2","no","no","no","no","no","no","322.4","1","7","4","84"
+"85","75","female","alone","never","Placebo","guideline","no","yes","no","0","7","no","no","no","no","no","yes","60.71","2","14","12","88"
+"106.52","84","male","partner","never","Active","more","yes","no","no","0","3","no","no","no","no","no","no","207.86","2","12","5","76"
+"221","57","female","alone","never","Placebo","guideline","no","yes","no","0","11","yes","no","no","yes","no","no","228.72","3","18","7","28"
+"25.8","48","male","partner","ever","Active","guideline","no","no","no","0","1","no","no","no","no","no","no","281.41","0","9","3","68"
+"30","87","female","alone","never","Active","guideline","no","yes","no","1","2","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"179.73","57","female","partner","never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","no","239.97","1","17","15","36"
+"313.12","46","male","partner","ever","Placebo","guideline","yes","no","yes","0","1","yes","no","no","no","no","no","356.46","1","8","7","72"
+"60","65","female","partner","ever","Active","guideline","no","yes","no","0","4","no","no","no","no","no","no","92.31","1","12","5","72"
+"88.77","61","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","no","263.98","2","10","12","84"
+"202.72","45","female","partner","ever","Placebo","guideline","no","no","no","0","1","yes","no","no","no","no","no","247.93","1","9","5","88"
+"147.05","76","male","alone","never","Placebo","guideline","yes","yes","no","0","2","yes","yes","no","yes","no","no","245.8","2","10","13","80"
+"172.2","63","male","alone","never","Placebo","guideline","yes","no","no","0","19","no","no","no","no","no",NA,NA,"6",NA,NA,NA
+"282.7","48","male","partner","ever","Active","guideline","no","no","no","0","18","yes","no","yes","no","no","yes","67.27","3","20","14","20"
+"254.4","64","female","partner","never","Placebo","guideline","no","no","no","0","11","yes","no","no","no","no","no","125.18","4","11","1","96"
+"149.71","64","female","alone","never","Placebo","guideline","no","no","no","0","1","no","no","no","no","no",NA,NA,"0","4","0","96"
+"141.8","60","male","alone","never","Active","guideline","no","no","yes","1","6","no","no","no","no","no","no","118.06","4","7","2","100"
+"256","54","male","partner","never","Active","guideline","no","yes","no","0","5","yes","no","no","no","no","no","158.43","0","5","7","72"
+"163.55","68","male","partner","never","Active","guideline","yes","yes","no","0","6","no","no","no","yes","no","no","253.27","1","16","3","76"
+"40","66","female","partner","ever","Placebo","guideline","no","yes","no","0","4","yes","no","no","no","no","no","85","0","9","5","64"
+"37.84","84","female","alone","never","Placebo","guideline","no","yes","no","0","1","no","no","no","no","no","no","98.13","1","12","2","80"
+"106.2","72","male","partner","ever","Placebo","guideline","yes","yes","no","0","11","yes","no","no","no","no","no","93.5","1","12","7","40"
+"162.15","33","female","alone","ever","Placebo","guideline","no","no","no","0","2","no","no","no","no","no","yes","56.87","1","19","15","44"
+NA,"70","male","partner","ever","Active","guideline","no","no","no","0","19","yes","no","no","no","no",NA,"62.87","3","11","7","84"
+"52.36","88","male","alone","ever","Active","more","yes","no","no","0","12","no","no","no","no","no","no","25.8","3","7","4","72"
+"191.8","84","male","partner","ever","Placebo","guideline","no","no","no","1","1","no","no","no","no","no","yes","64.6","4","20","19","4"
+"75.8","45","male","partner","never","Placebo","guideline","no","no","no","0","3","yes","no","no","yes","no",NA,NA,NA,NA,NA,NA
+"252","74","male","partner","never","Placebo","guideline","no","yes","no","0","0","no","yes","no","no","no","no","224.64","0","8","3","80"
+"195.5","63","male","alone","never","Active","guideline","no","no","no","0","5","no","no","no","no","no","no","175.58","3","11","5","80"
+"171.4","62","male","partner","never","Placebo","guideline","no","no","yes","0","9","no","no","no","no","no","no","214.9","3","10","3","84"
+"131.29","67","female","partner","never","Active","guideline","no","no","no","0","3","yes","no","no","no","no","no","243.92","1","8","5","76"
+"110.8","66","male","alone","never","Placebo","guideline","no","yes","no","0","3","yes","no","no","no","no","yes","38.07","2",NA,NA,NA
+"0","65","male","alone","never","Placebo","guideline","no","yes","yes","3",NA,"no","no","no","yes","no","no","25","4","10","2","72"
+NA,"63","male","alone","never","Active","guideline","no","yes","no","0","16","no","yes","no","yes",NA,NA,"21.15","5","16",NA,"20"
+"222.8","58","male","partner","never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","no","471.58","2","12","6","80"
+"204.49","79","female","partner","ever","Placebo","guideline","no","yes","no","0","3","yes","no","no","no","no",NA,NA,"0","7","1","96"
+"191","60","male","alone","never","Active","guideline","no","yes","no","1","3","yes","no","no","no","no","no","141.08","2","4","1","96"
+"184.47","54","female","partner","ever","Active","guideline","no","yes","no","0","1","no","no","no","no","no","no","277.76","2","15","12","52"
+"114.4","65","female","partner","ever","Active","guideline","no","no","no","0","19","yes","no","yes","no","no",NA,NA,NA,NA,NA,NA
+NA,"52","male",NA,NA,"Placebo",NA,NA,NA,"no","0","10","no","no","no","no",NA,NA,NA,NA,NA,NA,NA
+"91.98","77","female","partner","never","Active","guideline","yes","yes","no","0","0","no","no","no","yes","no","yes","56.35","2","9","24","40"
+"53.11","72","female","alone",NA,"Placebo","guideline","no","no","no","0","4","yes","no","no","no","no","no","297.5","1","4","0","100"
+"161","61","male","partner","never","Placebo","guideline","yes","yes","no","0","1","no","no","no","no","no","no","140.62","0","8","2","68"
+"75","62","female","partner","never","Placebo",NA,"no","no","no","0","24","no","no","no","no","no","no","27.09","4","14","10","64"
+"143.2","66","female","partner","ever","Placebo","guideline","no","no","no","0","9","yes","no","no","no","yes","no","111.4","2","13","1","88"
+"61.72","50","male","alone","never","Active","guideline","no","yes","no","0","0","no","no","no","no","no",NA,NA,"2","12","17","60"
+"33.4","82","female","partner","never","Placebo","guideline","no","yes","no","0","19","no","no","no","no","no",NA,NA,"4","15","28","4"
+"75","70","female","partner","ever","Placebo","guideline","no","no","no","0","3","no","no","no","no","no","no","93.14","1",NA,"5","76"
+"111","69","male","partner",NA,"Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","yes","58.4","1","7","3","84"
+"145","58","male","partner","ever","Placebo","guideline","yes","no","no","0","14","no","no","no","no","no","no","276.47","2","10","7","44"
+"52.2","72","female","alone","never","Active","guideline","no","no","no","0","4","yes","no","no","no","no","no","31.4","1","4","0","100"
+"141.2","79","male","partner","ever","Placebo","guideline","no","no","no","0","4","yes","no","no","no","no","no","107.3","2","12","13","72"
+"144.4","79","male","partner","ever","Placebo","guideline","no","no","no","2","9","no","no","no","no","no",NA,NA,"6","18","11","40"
+"65","67","male","alone","never","Placebo","guideline","no","yes","yes","2","2","no","no","no","no","no","no","97.13","2","16","7","56"
+"110.8","87","male","partner","never","Placebo","guideline","no","no","no","0","4","yes","no","no","no","no","yes","33.4","1","10","5","68"
+"131.8","67","male","partner","never","Placebo","guideline","yes","yes","no","2","3","yes","no","no","yes","no","yes","70.8","0","7","4","76"
+"52.2","19","female","alone","never","Placebo","guideline","no","no","no","0","19","yes","no","yes","no","no","no","78.85","1","8","3","84"
+"106.8","83","female","alone","ever","Active","guideline","no","yes","no","3","16","yes","no","no","no","no","yes","27.2","3",NA,NA,NA
+"27.53","72","female","alone","never","Placebo","guideline","no","yes","no","3","1","yes","no","no","no","no","no","39.17","1","14","3","64"
+"278.4","72","male","partner","ever","Active","guideline","yes","yes","yes","0","4","yes","no","no","no","no","yes","65","2","6","3","84"
+"209.37","76","male","partner","never","Placebo","guideline","no","yes","no","0","1","no","no","no","no","no","no","161.8","2","11","2","100"
+"17.22","83","female","alone","never","Active","guideline","no","yes","no","3","2","no","no","no","no","no","no","8.4","3","12","9","72"
+"52.2","91","female","alone","ever","Placebo","guideline","no","yes","no","1","5","no","no","no","no","no","no","62.92","2","12","6","72"
+"71.4","67","male","partner","never","Placebo","guideline","no","no","no","0","5","yes","no","no","no","no","no","88.43","1","10","3","88"
+"144.4","72","male","partner","never","Active","guideline","no","no","no","1","20","yes","no","yes","no","no",NA,NA,"6",NA,NA,NA
+"109.25","89","male","partner","ever","Active","guideline","yes","no","no","0","3","yes","no","no","no","no","yes","33.4","2","11","4","84"
+"95.12","64","male","alone","never","Placebo","guideline","no","yes","no","0","1","no","no","no","no","no","no","85.82","1","15","16","60"
+"146","57","female","alone","never","Active","guideline","no","no","no","0","7","no","no","no","no","no","no","252.8","1","10","3","80"
+"179.2","80","male","partner","never","Active","guideline","no","yes","no","0","8","no","no","no","no","no","no","86","2","13",NA,"48"
+"249.9","76","male","partner","ever","Active","guideline","no","no","no","0","3","yes","no","no","no","no","no","195.8","1","7","2","100"
+"241","57","male","partner","never","Placebo","guideline","no","no","no","0","8","no","no","yes","no","no","no","171","0","4","1","92"
+"186.8","60","male","alone","never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","no","174.18","2","11","7","52"
+"163.09","81","female","alone","never","Active","guideline","no","yes","no","0","5","yes","no","no","no","no","no","121","1","12","2","88"
+"152.53","48","male","alone","never","Placebo","guideline","no","no","no","0","5","no","no","no","no","no","no","128.76","3","15","16","52"
+"98.22","86","male","alone","never","Active","guideline","no","yes","yes","2","3","yes","no","no","no","no","yes","41.18","2","12","34","24"
+"50.8","74","male",NA,NA,"Active",NA,NA,NA,"no","0","1","no","no","no","no",NA,NA,NA,NA,NA,NA,NA
+"84.62","67","female","partner","ever","Placebo","guideline","no","no","no","0","6","yes","no","no","no","no","no","98.65","0","8","6","92"
+"254.15","64","male","partner","never","Placebo","guideline","no","no","yes","0","5","yes","no","no","no","no","no","107.31","2","7","2","88"
+"241.4","61","male","partner","never","Active","guideline","no","yes","no","0","3","no","no","no","no","no","no","117.4","2","9","5","60"
+"291.47","58","male","partner","never","Placebo","more","no","no","no","0","7","no","no","no","no","no","no","484.8","1","9","3","88"
+"27.2","83","male","partner","never","Placebo","guideline","no","yes","no","1","1","no","no","no","no","no","no","121.8","2","13","2","88"
+"208","68","male","partner","never","Placebo","guideline","no","no","yes","0","2","yes","no","no","yes","no","no","207.5","0","7","4","92"
+"178.4","53","male","alone","never","Active","more","no","no","no","0","14","no","no","no","no","no","yes","63.07","4","12","10","32"
+NA,"52","male","partner","never","Active","guideline","no","yes","no","0","5","no","no","no","no","no",NA,NA,"6",NA,NA,NA
+"197.3","84","female","alone","ever","Active","guideline","yes","yes","no","0","0","no","no","no","no","no","no","80","1","13","7","64"
+"354.59","63","male","partner","never","Placebo","guideline","yes","no","no","0","15","yes","no","no","no","no","no","312","1","6","2","88"
+"111","58","male","alone","ever","Placebo","guideline","no","no","no","0","4","no","no","no","no","no","no","239.54","2","10","1","100"
+"30","89","female","alone","never","Placebo","more","no","yes","no","0",NA,"no","no","no","no","no",NA,NA,"6",NA,NA,NA
+"78.33","84","female","alone","never","Active","guideline","no","yes","no","2","0","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"14.01","79","male","partner","never","Active","guideline","yes","no","no","2","6","no","yes","no","no","no","no","135.42","4","7","0","100"
+"95.8","86","female","alone","never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","yes","50.8","2","15","14","68"
+"75.39","73","male","partner","ever","Placebo","guideline","yes","yes","no","1","8","no","no","no","no","no",NA,NA,"1","4","2","100"
+"170.25","69","female","partner","ever","Placebo","guideline","no","no","no","0","4","yes","no","no","no","yes","no","193.3","0","12","1","92"
+"61","70","male","partner","never","Placebo","guideline","no","no","no","0","3","yes","no","yes","no","no","no","220.8","0","6","6","80"
+"236.8","49","male","partner","never","Placebo","guideline","no","no","no","0","3","no","no","no","no","no","no","227.05","1","9","7","76"
+"163.2","53","male","partner","never","Active","guideline","no","no","no","0","5","no","no","no","no","no","no","179.06","1","13","14","68"
+"29.51","77","female","alone","never","Active","guideline","yes","yes","no","0","3","yes","no","no","no","no","no","61.76","0","10","3","76"
+"206.4","51","male","partner","never","Placebo","guideline","no","no","yes","0","7","yes","no","no","yes","no",NA,NA,"2","17","30","20"
+"116","74","male","partner","never","Placebo","guideline","yes","yes","no","0","7","yes","no","no","yes","no","no","123.81","0","4","1","84"
+"343.17","58","male","partner","ever","Placebo","guideline","no","no","no","0","0","no","no","no","no","no","no","403","1","10","3","80"
+"107.81","79","male","partner","never","Placebo","guideline","no","no","no","0","3","no","no","no","no","no","no","162.87","1","16","5","68"
+"231.4","48","male","partner","never","Active","guideline","no","no","no","0","2","no","no","no","no","no","no","210.16","1","13","4","60"
+"177.4","78","male","partner","ever","Placebo","guideline","no","no","no","0","4","no","no","no","no","no","no","137.15","0","6","10","64"
+"126.64","52","male","partner","ever","Placebo","guideline","no","yes","no","0","4","no","no","no","no","no","no","271.15","2","6","2","100"
+"69.36","78","female","alone","never","Active","guideline","no","no","no","0","5","yes","no","no","no","no","no","128.04","1","20","23","32"
+"107.52","78","male","partner","never","Placebo","more","yes","yes","no","2","2","no","no","no","no","no","no","88.78","2","14","5","68"
+"60","69","male","partner","never","Active","guideline","no","yes","yes","0","8","yes","no","no","yes","no","no","107.16","1","13","10","60"
+"169.4","60","female","alone","ever","Placebo","guideline","no","no","yes","0","3","no","no","no","no","no","no","196.12","2","5","6","76"
+"106","68","male","partner","never","Active","guideline","yes","no","no","0","12","yes","no","yes","no","no","no","127","0","6","0","88"
+"132.5","68","female","partner","never","Placebo","guideline","no","no","no","0","2","no","no","no","no","no","no","131.16","0","4","0","92"
+"141.32","73","female","alone","ever","Active","guideline","no","yes","no","0","2","no","no","no","no","no","no","106.55","2","16","8","48"
+"247.23","37","female","partner","never","Active","guideline","no","no","no","0","1","no","no","no","no","no","no","172.14","1",NA,"5","64"
+"71.72","44","male","alone","never","Active","guideline","no","no","no","0","12","yes","no","yes","no","no","no","50.8","2","19","24","16"
+"217.05","79","male","partner","never","Active","guideline","no","yes","no","0","3","no","no","no","no","no","no","147.74","2","10","3","60"
+"140.75","56","male","partner","ever","Placebo","guideline","no","yes","no","0","5","no","no","no","no","no","no","120.56","0","12","4","76"
+"95.8","84","female","alone","ever","Active","guideline","no","yes","no","0","3","no","no","no","no","yes",NA,NA,"0","12","50","100"
+"140.65","73","male","partner","never","Active","guideline","no","no","no","0","2","yes","no","no","no","no","no","311.77","1","7","6","80"
+"2.2","71","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","no","50.8","2","11","10","84"
+"56.4","67","male","partner","ever","Active","guideline","yes","no","no","1","2","no","no","no","no","no","no","103.12","2","9","4","84"
+"58.81","80","male","partner","never","Active","guideline","no","yes","no","0","3","no","no","no","yes",NA,NA,NA,"3","18","29","8"
+"77","77","female","partner",NA,"Placebo","guideline","no","yes","no","0","9","yes","yes","no","yes","no","no","100","1","12","11","80"
+"188.8","49","female","partner","never","Placebo","guideline","no","yes","no","0","3","no","no","no","no","no","no","78.65","1","12","4","76"
+"163.2","63","female","partner","never","Placebo","guideline","no","no","no","0","3","no","no","no","no","no","no","251.54","2","14","20","56"
+"0","88","female","partner","ever","Placebo","guideline","no","yes","no","0","2","yes","no","no","yes","no","no","25","0","7","0","96"
+"50","86","female","alone","ever","Placebo","guideline","no","no","no","2","4","no","no","no","no","no","no","52.2","2","13","5","72"
+"269.9","67","female","partner","never","Placebo","guideline","no","yes","no","0","3","no","no","no","no","no","no","111.1","2","12","10","64"
+"170.72","75","male","alone","never","Active","guideline","no","yes","no","0","4","no","no","no","no","no","no","190.12","1","6","2","92"
+"70","79","female","alone","never","Active","guideline","no","no","no","0","5","no","no","no","no","no","no","55","3","17","13","48"
+"143.92","80","female","alone","never","Placebo","guideline","no","no","no","0",NA,"no","no","no","yes","no","no","238.43","0","4","0","96"
+"338.91","68","male","partner","never","Placebo","guideline","no","no","no","0","1","no","no","no","no","no","no","241.05","1","5","4","88"
+"50.8","72","male","partner","ever","Active","guideline","no","no","yes","1","22","yes","no","no","no","no","no","44.4","4","6","9","88"
+"80.75","69","female","partner","ever","Placebo","guideline","no","yes","no","0","0","no","no","no","no","no","no","161.07","0","6","0","96"
+"25","97","female","alone",NA,"Active","guideline","yes","yes","no","2","24","no","no","no","no","no",NA,NA,"5",NA,NA,"0"
+"277.11","54","male","partner","never","Placebo","guideline","no","no","no","0","3","yes","no","no","no","no",NA,NA,"0","14","11","36"
+"112.4","47","female","partner","never","Placebo","guideline","no","no","no","0","2","no","no","no","no","no","yes","52.2","0",NA,"3","100"
+"105","64","female","partner","never","Active",NA,"yes","no","no","0","23","no","no","yes","no","no","no","133.37","4","7","1","92"
+"181.12","54","female","partner","never","Placebo","guideline","no","no","no","2","5","yes","no","no","no","no","no","158.84","2","13","1","68"
+"27.31","52","male","alone","never","Placebo","guideline","no","yes","no","1","2","no","no","no","no","no","no","151.72","2","7","8","52"
+"37.8","76","female","alone","never","Placebo","guideline","no","yes","yes","0","4","no","yes","no","no","no","no","25","1","12","7","56"
+"128.76","79","male","partner",NA,"Active","guideline","no","no","no","0","2","no","no","no","yes","no","no","320.85","2","4","2","92"
+"152.03","71","female","partner","ever","Active","guideline","no","yes","no","0","7","yes","no","no","no","no","no","216.55","1","7","8","100"
+"55","66","male","partner","never","Active","guideline","no","yes","no","0","20","yes","no","yes","yes","no","no","139.51","1","11","7","64"
+"80.25","80","male","partner","never","Placebo","guideline","yes","yes","no","2","9","no","no","no","no","no",NA,NA,"6","6","13","32"
+"50","72","male","partner","never","Placebo","more","no","no","no","0","2","yes","no","no","no","no",NA,NA,NA,NA,NA,NA
+"188.47","70","male","partner","never","Active","guideline","no","yes","yes","0","0","no","yes","no","yes","no","no","158.89","1",NA,"0","96"
+"256.9","64","female","partner","ever","Placebo","guideline","no","no","no","0","2","no","no","no","no","no","no","297.6","0","7","1","100"
+"300.72","57","male","partner","ever","Active","guideline","no","no","no","0","1","no","no","no","no","no","no","279.93","0","4","1","100"
+"115.82","77","male","partner","ever","Placebo","guideline","yes","yes","no","1","9","yes","no","no","no","no","no","170.33","4","9","8","76"
+"156.31","65","female","alone","never","Active","guideline","no","yes","no","0","6","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"50","73","male","alone","never","Placebo","guideline","no","no","no","2","0","no","no","no","no","no","no","27.2","1","19","20","28"
+"27.2","85","female","alone","ever","Active","guideline","no","no","no","1","1","no","no","no","no","no",NA,NA,"1","19","26","28"
+NA,"79","female","alone","never","Placebo","guideline","yes","no","no",NA,"9","yes","no","no","no","no",NA,NA,NA,NA,NA,NA
+"129.22","75","male","partner","never","Placebo","guideline","no","no","no","0","18","no","no","yes","yes","no",NA,NA,"6","15","26","24"
+"82.22","75","female","partner","ever","Active","guideline","no","yes","no","0","4","no","no","no","no","no","no","139.68","2","16","10","76"
+"134.59","70","female","alone","ever","Active","guideline","no","no","yes","0","7","yes","no","no","no","yes","no","83.16","1","13","18","56"
+"117","70","male","partner","never","Placebo","guideline","yes","no","no","0","5","no","no","no","no","no","no","101.82","2","13","3","0"
+"99.48","82","male","alone","never","Placebo","guideline","no","no","no","0","4","no","yes","no","no","no","no","98.22","0","14","8","72"
+"366.68","56","male",NA,NA,"Active",NA,NA,NA,"no","0","3","no","no","no","no",NA,"no","492.38","2","5","1","96"
+"76.4","84","female","alone","ever","Placebo","guideline","no","yes","yes","0","0","no","no","no","no","no","no","56.4","1","16","7","68"
+"95.75","69","female","alone","ever","Active","guideline","no","yes","no","0","13","yes","no","no","no","no","no","82.09","4","8","3","88"
+"160.56","67","male","partner","never","Active","more","no","no","no","0","2","no","no","no","no","yes","no","393.48","2","17","9","72"
+"162.4","59","male","partner","ever","Placebo","guideline","no","no","no","0","1","no","no","no","no","no","no","249.67","1","4","1","88"
+"151","69","male","partner","never","Placebo","guideline","no","yes","no","0","1","yes","no","yes","no","no","no","254.38","1","13","11","56"
+"98.2","40","male","partner","never","Placebo","more",NA,"yes","no","0","2","yes","no","no","no","no","no","315.11","0","7","9","80"
+"168.15","72","male","partner","never","Active","guideline","no","yes","no","0","1","no","no","no","no","no","no","136","1","12","8","68"
+"111.8","73","male","partner","ever","Placebo","guideline","no","yes","yes","0","1","no","no","no","no","no","no","121","1","10","3","88"
+"179.23","50","male","partner","ever","Placebo","guideline","no","no","no","0","0","no","no","no","no","no","no","336.27","0","5","0","92"
+"107","44","female","alone","never","Placebo","guideline","no","yes","yes","1","5","no","no","no","no","no","yes","70","1","12","6","68"
+"249.5","72","male","partner","never","Placebo","guideline","yes","yes","no","0","5","no","no","no","no","no","yes","58.4","2","10","18","48"
+"365.28","64","male","partner","never","Placebo","more","no","no","no","0","9","yes","no","no","no","no","no","142.42","2","8","2","100"
+"412.9","55","male","partner","never","Active","guideline","no","no","no","0","5","yes","no","no","no","no","no","272.84","3","10","3","100"
+"108.31","67","female","partner","never","Active","guideline","no","yes","no","0","3","no","no","no","no","no","no","116.25","1","15","8","72"
+"153.22","86","male","partner","never","Active","guideline","yes","no","no","0","4","no","no","no","no","no","no","108.2","1","4","0","92"
+"111.8","78","female","alone","ever","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"101.16","74","male","alone","ever","Active","guideline","no","no","no","0","3","no","no","no","no","no","no","96","3","6","2","96"
+"157","73","male","partner","never","Active","guideline","no","yes","no","1","3","no","no","no","no","no",NA,NA,"0","8","1","88"
+"290.84","61","male","partner","ever","Active","guideline","no","no","no","0","2","no","no","no","no","no","no","262","1","9","0","88"
+"88.2","74","female","alone","ever","Placebo","guideline","no","yes","no","0","1","no","no","no","no","no","no","130","1","17","16",NA
+"170.66","45","male","alone","ever","Active","guideline","yes","yes","no","0","13","no","no","no","no","no","no","170.84","1","6","0","52"
+"107.72","82","male","partner","ever","Placebo","guideline","no","yes","no","0","10","yes","no","yes","no","no","no","138.38","1","9","4","64"
+"225.4","61","male","partner","never","Placebo","guideline","no","no","no","0","1","no","no","no","no","no","no","219.55","0","9","6","60"
+"235.16","57","male","partner","never","Active","guideline","yes","no","no","0","0","no","no","no","no","no","no","255.33","0","9","2","72"
+"50","82","female","partner","never","Active","guideline","no","no","no","0","17","yes","no","yes","no","no","no","30.5","2","15","8","84"
+"99.55","74","female","alone","never","Active","guideline","no","yes","no","0","7","no","no","no","no","no","yes","58.82","4","13","8","76"
+"105.61","80","female","alone","never","Active","guideline","no","yes","yes","1","0","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"28.95","78","male","partner","never","Placebo","more","no","yes","no","0","2","yes","no","no","no","no","no","167.32","1","10","4","92"
+"179.5","71","male","alone","ever","Placebo","guideline","no","yes","no","0","5","yes","no","no","yes","no","no","177.34","2","12","8","76"
+"245.11","56","male","alone","never","Active","guideline","no","no","no","0","2","no","no","no","no","no","no","92.4","1","7","8","84"
+"315.8","45","male","partner","never","Active","guideline","no","no","no","0","3","yes","no","no","no","no","no","378.79","0","6","5","72"
+"120","70","female","partner","ever","Active","guideline","yes","no","no","0","11","no","no","yes","no","no","no","78.4","1","17","26","56"
+"58.4","84","female","partner","never","Placebo","guideline","yes","yes","no","0","4","yes","no","no","no","no","no","204.55","2","17","7","56"
+"56.4","66","female","alone","never","Active","guideline","yes","no","no","0","12","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"159.11","54","male","partner","never","Active","guideline","no","yes","no","0","1","yes","no","no","yes","no",NA,NA,NA,NA,NA,NA
+"156.53","52","male","partner","ever","Active","guideline","no","yes","no","0","17","yes","no","no","no","no",NA,NA,NA,NA,NA,NA
+"186.8","62","female","partner","ever","Active","guideline","no","yes","yes","0","8","yes","no","no","no","no","no","165.4","2","16","18","24"
+"142.36","67","male","partner","never","Active","more","no","no","no","0","2","no","no","no","no","no","no","213.2","2","4","5","100"
+"242.4","64","male",NA,"never","Active",NA,"no","no","no","0","0","no","no","no","no","no","no","212.4","2","9","2","96"
+"58.4","93","male","alone","never","Placebo","guideline","no","yes","no","1","11","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"62.26","89","male","partner","never","Placebo","guideline","no","yes","no","2","3","yes","no","no","no","no","no","122.81","2","14","10","36"
+"105.72","74","male","partner","never","Placebo","guideline","yes","yes","no","0","2","no","yes","no","no","no","no","160.26","1","10","8","76"
+"258.2","66","male","partner","never","Placebo","more","no","yes","no","0","2","no","no","no","no","no","no","138.25","1","8","6","76"
+"256","51","female","alone","never","Active","guideline","no","no","no","0","4","yes","no","yes","no","no","no","77.25","2","15","29","60"
+"52.2","69","male","alone","ever","Placebo","guideline","yes","yes","yes","0","1","no","no","no","no","no","no","108.2","2","4","3","100"
+"50","93","female","alone","ever","Placebo","guideline","no","yes","yes","2","1","no","no","no","no","no","no","25","4","15","5","76"
+"103.29","66","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","yes","21.42","4","13","40","56"
+"229.73","64","male","alone","never","Active","guideline","no","yes","no","0",NA,"no","no","no","yes","no","yes","29.51","4","5","1","88"
+"196.8","71","male","partner","never","Placebo","guideline","no","yes","no","1","1","yes","no","no","no","no","no","146.8","1","12","2","76"
+"183.4","66","male","alone","ever","Active","guideline","no","no","no","0","2","no","no","no","no","no","no","140.8","1","7","1","88"
+"76.4","73","female","partner","never","Active","guideline","no","yes","no","0","4","no","no","no","no","no",NA,NA,"2","18","3","88"
+"33.4","75","male","alone","never","Active","guideline","yes","no","no","0","2","no","no","no","no","no","no","106.8","1","7","1","84"
+"75","69","female","partner","never","Active","guideline","no","yes","no","0","1","no","no","no","no","no","no","25","2","16","12","72"
+"65","78","male","partner","never","Active","guideline","no","no","no","2","2","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"185.15","74","female","partner","never","Active","guideline","no","no","no","0","4","no","no","no","no","no","no","183.79","1","4","3","84"
+"155.52","68","male","partner","ever","Active","guideline","yes","yes","no","0","3","no","no","no","no","no","no","134.8","0","7","3","76"
+"34.56","78","female","alone","never","Placebo","guideline","no","yes","no","0","1","yes","no","no","no","no","no","103.7","2","10","2","96"
+"76.21","65","male","partner","never","Placebo","guideline","no","no","no","0","2","no","no","no","no","no","no","67.76","0","13","27","24"
+"65","70","male","alone","never","Active","more","no","yes","no","0","1","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"133.89","79","male","partner","never","Active","guideline","no","yes","yes","2","19","yes","no","yes","no","no","no","82.46","3","12","11","48"
+"50","75","female","partner","ever","Active","guideline","yes","yes","no","1","1","no","no","no","no","no","no","109.72","2","7","2","80"
+"111","72","male","partner","never","Active","guideline","no","yes","no","0","1","no","no","no","no","no","no","113.53","0","20","29","16"
+"213.4","56","male","partner","never","Placebo","guideline","no","yes","no","0","1","no","no","no","no","no","no","182.7","2","17","18","24"
+"50.8","56","male","alone","never","Placebo","guideline","no","yes","no","1","12","yes","no","no","no","no","no","68.3","2","18","21","28"
+"213.25","55","male","partner","never","Active","guideline","no","yes","no","0","1","no","no","no","no","no","no","224.53","1",NA,"8","76"
+"145.56","80","male","partner","never","Active","guideline","yes","no","no","0","6","no","no","no","no","no","no","149.82","2","7","1","84"
+"50","80","male","alone","ever","Active","guideline","yes","no","no","0","8","yes","no","no","no","no","no","78.82","2","17","9","52"
+"76.4","66","male","partner","never","Active","guideline","yes","no","no","0","2","no","no","no","no","no","no","161","0","13","9","60"
+"136","63","female","partner","ever","Active","guideline","no","yes","yes","0","2","no","no","no","no","no","no","239.04","1","11","6","68"
+"230.9","54","male","partner","ever","Active","guideline","no","yes","no","0","2","no","no","no","no","no","no","143.53","1","8","3","72"
+"248.25","45","male","partner","ever","Active","guideline","yes","no","no","0","0","no","no","no","no","no","no","153.25","1","12","8","88"
+"101","88","female","alone","ever","Active","guideline","no","yes","no","0","4","no","no","no","no","no",NA,NA,"3",NA,NA,NA
+"133.4","71","male","partner","never","Active","guideline","no","yes","no","0","10","yes","no","no","no","no","no","145.4","0","4","0","96"
+"113.52","73","male","partner","never","Placebo","guideline","no","no","yes","2","19","yes","no","no","no","no",NA,NA,NA,NA,NA,NA
+"141.8","67","male","partner","never","Active","guideline","no","yes","no","0","7","yes","no","no","yes","no","no","218.39","1","18","37","48"
+"170.8","64","male","partner","never","Placebo","guideline","no","yes","yes","0","5","yes","no","no","no","no","no","210.24","1","12","2","80"
+"50.8","58","female","partner","never","Active","guideline","no","yes","no","1","4","no","no","no","no","no","no","35","3","16","37","40"
+"78.33","71","male","alone","never","Active","more","no","no","no","1","4","no","no","no","no","no","yes","4.51","4","20","38","20"
+"146.8","71","female","partner","ever","Active","guideline","no","no","no","0","20","yes","no","no","no","no",NA,NA,"3","14","7","88"
+"108.2","87","male","alone","never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","yes","67.22","2","5","4","88"
+"180","61","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","no","281.07","2","10","6","76"
+"130.8","76","male","partner","ever","Placebo","guideline","yes","no","no","0","0","no","no","no","no","no","no","455.45","2","4","1","92"
+"123.22","70","female","alone","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","no","94.4","1","5","6","80"
+"201.8","69","male","partner","never","Placebo","guideline","no","yes","yes","0","2","no","no","no","no","no","no","204.55","2","11","6","44"
+"52.2","67","male","alone","never","Placebo","more","no","no","no","1","5","no","no","no","no","no","no","74.25","1","11","9","72"
+"282","60","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","yes","no","no","177.4","2","10","7","80"
+"89.61","82","male","alone","never","Placebo","guideline","no","yes","yes","0","4","no","no","no","no","no","no","158.52","0","4","0","96"
+"77.31","78","female","alone","ever","Active","guideline","no","yes","no","0","2","no","no","no","no","no","no","209.9","2","16",NA,"44"
+"204.67","71","female","partner","never","Active","guideline","no","yes","no","0","4","no","no","no","no","no","no","91","2","4","0","100"
+"220.9","59","male","partner","never","Active","guideline","no","no","no","1","3","yes","no","no","no","no","no","194.43","2","13","9","40"
+"233.52","56","male","alone","never","Placebo","guideline","no","no","no","0","1","yes","no","no","no","no","no","144.4","1",NA,NA,NA
+"325.6","46","male","partner","ever","Placebo","guideline","no","no","no","0","3","yes","no","no","no","no","no","177.87","2","16","19","44"
+"113","76","female",NA,"never","Placebo","guideline","no","no","no","1","4","no","yes","no","no","no","no","79.15","2","20","36","12"
+"91.71","64","male","partner","never","Active","more","no","yes","yes","0","5","yes","no","no","no","no",NA,NA,"1",NA,NA,NA
+"195.8","58","female","partner","never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","no","111","1","11","11","76"
+"196.95","49","female","partner","ever","Active","guideline","no","no","no","0","5","yes","no","no","no","no","no","193.8","0","13","8","76"
+"207.31","52","male","alone","ever","Placebo","guideline","no","no","no","0","1","no","no","no","no","no","no","208.5","2","12","2","68"
+"53.4","88","male","partner","never","Placebo","guideline","no","yes","no","2","3","no","yes","no","no","no",NA,NA,NA,NA,NA,NA
+"45","82","male","partner","never","Placebo","guideline","no","no","no","0","7","no","no","no","no","no",NA,NA,"4","7","15","48"
+"25","82","female","alone","never","Placebo","guideline","no","no","no","1","6","no","no","no","no","no","no","25.8","3","16","9","72"
+"167.4","34","female","partner","ever","Active","guideline","no","no","no","0","10","yes","no","no","no","no","no","139.05","2","20","36","24"
+"85","78","female","partner","ever","Active","guideline","no","no","no","0","3","no","no","no","no","no","no","131.8","1","12","1","92"
+"27.2","74","female","alone","never","Active","more","no","yes","no","2","2","no","no","no","no","no","no","36.02","2","10","3","84"
+"15","64","female","partner","never","Active","guideline","no","no","no","0","0","no","no","no","no","no","no","30.75","0","13","9","76"
+"225.4","51","male","partner","ever","Active","guideline","no","no","no","0","4","yes","no","no","no","no","no","211","0","7","1","88"
+"75.8","85","male","alone","never","Placebo","guideline","no","yes","no","0","3","no","no","no","no","no","no","75.8","1","17","12","36"
+"196.2","59","male","partner","never","Active","guideline","no","no","no","0","7","yes","no","no","no","no","no","122","1","11","3","84"
+"194.73","70","male","partner","ever","Placebo","guideline","no","no","no","0","4","yes","no","no","no","no","no","131.8","0","4","0","100"
+"40.12","77","male","partner","never","Placebo","guideline","yes","yes","no","0","1","yes","no","no","no","no","no","244.49","2","13","2","92"
+"106","82","male","partner","ever","Placebo","guideline","yes","no","no","0","19","yes","no","yes","no","no",NA,NA,"2",NA,NA,NA
+"63.38","73","female","partner","never","Active","guideline","no","no","no","0","0","no","no","no","no","no","no","153.14","1","11","4","72"
+NA,"42","male","partner","ever","Placebo","guideline","no","no","no","0","7","yes","no","no","no","no",NA,"202.37","2","5","5","84"
+"178.11","62","male","partner","never","Active","guideline","no","yes","no","0","26","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"314.76","58","male","partner","never","Placebo","guideline","no","yes","no","0","0","yes","no","no","no","yes",NA,NA,NA,NA,NA,NA
+"196.47","84","male","partner","ever","Placebo","guideline","no","yes","no","0","6","no","no","no","no","no","yes","7.31","4","16","15","64"
+NA,"71","female","alone","never","Active","guideline","yes","yes","no","3",NA,"no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"247","54","male","partner","never","Active","more","no","yes","no","1","3","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"81.87","70","female","partner","ever","Active","guideline","no","yes","yes","0","3","yes","no","no","no","no","yes","59.66","1","12","5","88"
+"132.12","87","male","partner","ever","Active","more","no","no","no","0","6","no","no","no","no","no","yes","36.72","3","14","5","84"
+"50","84","male","alone","never","Active","guideline","yes","yes","no","2",NA,"no","no","no","no","no",NA,NA,NA,NA,NA,NA
+NA,"76","female","alone","never","Active","guideline","no","no","yes",NA,NA,"no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"247","67","male","partner","never","Active","guideline","no","yes","no","0","3","no","no","no","no","no","no","298.9","1","14","16","16"
+"166.72","52","male","partner","ever","Active","guideline","no","no","no","0","13","yes","no","yes","yes","no","no","161.4","1","13","5","64"
+"81.7","80","female","alone","ever","Active","guideline","no","yes","no","0","7","no","no","no","no","no","no","184.31","2","17","17","48"
+"148","63","female","alone","never","Placebo","guideline","no","yes","no","0","7","no","no","no","no","no","no","85","0","4","0","100"
+"43.8","67","male","partner","never","Placebo","guideline","no","yes","no","1","9","yes","no","yes","no","no","no","54.11","2","12","14","32"
+"143.31","67","male",NA,NA,"Placebo",NA,NA,NA,"no","0","0","no","no","no","no",NA,"yes","27.2","1","18","27","40"
+"14.72","52","male","partner","never","Active","more","no","yes","yes","0","3","yes","no","no","no","no","no","97.4","0","14","6","68"
+"174.94","69","female","alone","never","Placebo","guideline","yes","yes","no","0","5","no","no","no","no","no","no","203.78","1","12","13","64"
+"247","71","male","partner","never","Active","guideline","yes","no","no","0","11","yes","no","no","no","no","yes","61.2","2","8","5","96"
+"73.67","79","female","alone","never","Placebo","guideline","no","no","no","0","18","yes","no","yes","no","no","no","131.3","2","9","4","72"
+"122.55","75","male","partner","never","Active","guideline","no","no","no","0","3","no","yes","no","yes","no","no","81.59","0","7","4","76"
+"65","74","female","partner","never","Placebo","guideline","no","yes","no","0","6","no","no","no","no","no","no","75.8","1","16","7","72"
+"75","76","female","partner","ever","Active","guideline","no","yes","yes","0","2","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"64.67","75","female","alone","never","Placebo","guideline","no","no","no","0","1","yes","no","no","no","no","no","125.61","0","11","5","76"
+"135.48","72","female","alone","ever","Active","guideline","yes","no","no","0","1","no","no","no","no","no","no","108.8","1","7","0","96"
+"106.07","65","female","alone","ever","Placebo","guideline","no","no","no","0","1","no","no","no","no","no","no","92.09","1","5","5","84"
+"252.4","48","male","alone","never","Placebo","more","no","yes","no","0","2","no","no","no","no","no","no","302.48","1","7","7","76"
+"107.5","63","male","partner","ever","Active","guideline","no","yes","no","0","1","yes","no","no","no","no","no","210.17","1","8","2","96"
+"109.61","74","male","partner","never","Placebo","guideline","yes","yes","no","1","2","yes","no","no","no","no","no","111","2","4","3","40"
+"116.8","73","male","partner","never","Placebo","guideline","yes","no","no","0","2","yes","no","no","no","no",NA,NA,"0",NA,NA,NA
+"114.92","78","male","partner","ever","Active","guideline","no","no","no","0","2","no","no","no","no","no","no","99.77","5","13","9","52"
+"85.5","45","male","partner","never","Placebo","guideline","no","no","no","0","5","no","no","no","no","yes","no","203.12","1","8","3","80"
+"124.07","66","male","alone","never","Active","guideline","no","no","no","0","3","no","no","no","yes","no","yes","50.8","3","13","1","84"
+"263.33","37","male","partner","ever","Active","guideline","no","no","no","0","1","no","no","no","no","no","no","148.05","0","8","9","60"
+"166.8","54","male","partner","never","Placebo","guideline","no","no","no","0","3","no","no","no","no","no","no","236.8","0","4","1","100"
+NA,"83","male","partner","ever","Active","guideline","yes","no","no",NA,"27","no","no","yes","yes","yes",NA,NA,"6",NA,NA,NA
+"147.11","66","female","alone","never","Placebo","guideline","no","no","no","0","6","no","no","no","no","no","no","261.43","2","16","7","44"
+"150","55","male","partner","never","Active","guideline","yes","yes","yes","0","5","no","no","no","no","no",NA,NA,"6",NA,NA,NA
+"39.23","92","female","alone","ever","Placebo","guideline","no","yes","no","2","9","no","no","no","no","no","no","2.2","4","18","25","20"
+"78.82","88","female","partner","never","Active","guideline","yes","yes","no","0","21","yes","no","no","yes","no",NA,NA,NA,NA,NA,NA
+"290.93","57","male","partner","ever","Placebo","guideline","no","no","no","0","3","no","no","no","no","no","no","276.72","0","12","8","72"
+"431.8","55","male","partner","never","Active","guideline","yes","yes","no","0","1","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"65","79","female","alone","never","Active","guideline","no","no","no","0","8","no","no","no","no","no",NA,NA,"6",NA,NA,NA
+"173.65","78","female","partner","ever","Active","guideline","yes","no","no","0","0","yes","no","no","no","no","no","210.58","1","8","5","72"
+"196.8","48","male","partner","ever","Active","guideline","no","no","no","0","2","yes","no","no","no","no","no","164.16","1","11","14","100"
+"58.4","80","male","alone","never","Placebo","guideline","no","no","no","2","2","no","no","no","no","no","no","78.4","3","14","10","80"
+"40","49","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","yes","no","no","no","no","142.98","0","14","30","60"
+"90.55","75","male","partner","ever","Placebo","guideline","no","yes","yes","0","5","yes","no","no","yes","no",NA,NA,NA,NA,NA,NA
+"55.2","74","male","alone","never","Placebo","guideline",NA,"yes","no","0","5","no","yes","no","yes","no",NA,NA,"2","18","12","68"
+"102.31","85","female","alone","never","Placebo","guideline","yes","no","no","0","1","no","no","no","no","no","no","171.28","0","11","8","76"
+"60.49","82","male","alone","ever","Active","guideline","no","yes","no","0","5","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"27.2","79","male","partner","never","Placebo","guideline","yes","yes","yes","2","3","yes","no","no","no","no",NA,NA,NA,NA,NA,NA
+"68.4","75","male","partner","never","Active","guideline","no","yes","yes","1","5","no","no","no","no","yes","no","2.2","2","16","12","48"
+"221.47","70","male","partner","never","Placebo","guideline","no","yes","no","0","2","yes","no","no","yes","no","no","187.3","2","5","7","76"
+"272.8","57","male","partner","never","Active","guideline","no","no","no","0","4","no","no","no","no","no","no","259.84","2","9","2","100"
+"35.25","85","female","alone","ever","Active","guideline","no","yes","no","3","23","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"67.86","83","female","alone",NA,"Placebo",NA,"no","yes","no","0","5","no","no","no","no","no","no","92","1",NA,"8","84"
+"137.52","77","female","alone","ever","Active","guideline","no","no","no","0","5","yes","no","no","no","no","no","261.65","1","10","4","64"
+NA,"76","female","alone","never","Active","guideline","no","yes","no","1","7","no","no","no","no","no",NA,"30","3","16","11","28"
+"227.71","54","male","partner","ever","Active","guideline","no","no","no","0","4","yes","no","no","no","no","no","206.06","2","15","5","72"
+"56.4","78","female","alone","ever","Active","guideline","yes","yes","no","0","11","yes","no","no","no","no",NA,NA,NA,NA,NA,NA
+"16","85","male","partner","never","Active","guideline","no","yes","no","3","2","no","no","no","no","no","no","4.51","3","4","4","84"
+"135.1","82","male","partner","ever","Placebo","more","no","no","no","1","3","yes","no","no","no","no","no","144.77","1","12","4","72"
+NA,"80","male","partner","never","Placebo","more","yes","yes","no","0","12","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"42.22","91","female","alone","never","Placebo","guideline","no","yes","yes","0","0","no","yes","no","no","no","no","42.22","1","20","7","36"
+"52.2","78","male","alone","never","Placebo","guideline","no","yes","no","0","4","no","no","no","no","no","no","171.56","3","10","6","64"
+"0","78","male","partner","never","Placebo","guideline","no","yes","no","1","2","no","no","no","no","no","no","14.65","4","11","1","84"
+"154.96","77","male","partner","ever","Placebo","guideline","no","yes","no","1","2","yes","no","no","no","no","no","107","2","18","12","40"
+"38.2","71","male","partner","never","Placebo","guideline","no","yes","yes","0","1","no","no","no","no","no","no","95","1","20","24","64"
+"135.46","66","male","partner","never","Active","guideline","no","no","yes","0","2","no","no","no","no","no","no","139.86","2","9","12","68"
+"205.4","55","male","alone","never","Placebo","guideline","no","yes","yes","0","2","no","no","no","no","no","yes","60","1","17","8","40"
+"81.67","71","female","alone","never","Placebo","guideline","no","yes","no","0","5","no","no","no","no","no","yes","44.16","3","16","20","20"
+"85.05","84","male","partner","never","Placebo","more","no","no","no","1","2","yes","no","no","no","no","no","128.11","1","5","5","88"
+"71.4","80","male","alone",NA,"Placebo","guideline","yes","yes","yes","0","3","yes","no","yes","no","no","no","151","1","16","5","80"
+"101.74","71","female","alone","never","Active","guideline","no","yes","no","0","0","no","no","no","no","no","yes","27.6","1","12","6","88"
+"290.56","69","male","partner","never","Active","more","no","no","no","0","1","no","no","no","yes","no","no","254.35","1","7","3","80"
+"251.2","62","male","partner","never","Active","guideline","no","no","no","0","2","yes","no","no","no","no",NA,NA,NA,NA,NA,NA
+"274.11","57","male","partner",NA,"Placebo",NA,"yes","yes","yes","0","7","yes","yes","yes","no","no","no","378.76","0","9","3","64"
+"226","61","male","alone","ever","Placebo","guideline","no","yes","no","0","5","yes","no","no","no","no","no","295.76","0","4","0","92"
+"59.56","75","male","alone","never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","no","135.72","2","6","6","92"
+"53.11","93","female","alone","never","Placebo","guideline","no","yes","no","1","2","no","no","no","no","no","no","38.82","2","18","9","56"
+"150.6","86","male","partner","never","Placebo","guideline","no","no","no","0","3","no","yes","no","no","no","no","111","1","10","5","64"
+"119.55","84","male","alone","ever","Placebo","guideline","no","yes","no","0","2","yes","no","no","no","no","yes","74.55","2","12","11","72"
+"121.4","80","male","partner","never","Placebo","guideline","no","yes","yes","2","4","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"180.56","70","male","partner","never","Placebo","guideline","no","yes","no","0","2","yes","no","no","yes","no","no","249.46","2","14","20","72"
+"337.8","68","female","partner",NA,"Active","guideline","no","no","no","2","1","yes","no","no","no","no","no","201.72","2","5","0","92"
+"170.05","40","female","partner","never","Placebo","guideline","no","no","no","0","15","no","no","yes","no","no","yes","27.2","4","14","17","76"
+"95.8","77","female","partner","ever","Placebo","guideline","no","no","no","1","7","yes","no","no","no","no","no","131.8","1","15","12","100"
+"113.65","70","female","partner","never","Placebo","guideline","no","no","no","0","6","yes","no","no","no","no",NA,NA,"4","12","14","72"
+"108.2","84","male","partner","ever","Active","guideline","yes","yes","yes","0","9","no","no","no","no","no","no","112.08","4","8","5","40"
+"188.16","71","male","partner","never","Active","guideline","yes","yes","no","0","9","no","no","no","no","no","no","183.73","4","5","3","80"
+"361.93","44","male","partner","never","Placebo","guideline","no","no","no","0","2","yes","no","no","no","no","no","261.4","2","14","16","68"
+"228.61","80","male","partner","never","Active","guideline","no","no","no","0","3","no","no","no","no","no","no","328.27","2","14","8","76"
+"65","65","female","alone","never","Active","guideline","no","yes","no","0","4","no","no","no","no","no","no","153.05","3","17","4","76"
+"259.53","60","male","partner","never","Placebo","more","no","yes","no","0","4","no","no","no","no","no","no","169.75","3","4","4","92"
+"313.72","69","female","alone","never","Placebo","guideline","no","yes","no","0","1","no","no","no","no","no","yes","27.2","2","15","9","92"
+"169.4","47","male","partner","never","Placebo","guideline","no","no","no","0","1","yes","no","no","no","no","no","79.57","2","9","11","92"
+"88.31","63","male","partner","never","Placebo","more","no","yes","no","0","3","yes","no","no","no","no","no","81.41","2",NA,NA,NA
+"236","57","male","alone","never","Placebo","more","no","no","no","0","1","no","no","no","no","yes","no","217","1","4","2","88"
+"78.44","78","female","partner","never","Active","guideline","yes","yes","no","0","12","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"249.4","33","male",NA,NA,"Active",NA,NA,NA,"no","0","1","no","no","no","no",NA,"no","204.82","1","4","1","84"
+"94.4","81","female","alone","ever","Active","guideline","no","yes","no","1","2","no","no","no","yes","no","yes","35.71","3","18","23","48"
+"214.12","70","male","partner","never","Placebo","guideline","no","no","no","0","0","no","no","no","no","no","no","191.8","1","16","11","60"
+"205.4","68","female","alone","ever","Placebo","guideline","no","no","no","0","3","yes","no","no","no","no","no","258.55","1","10","5","92"
+"139.3","67","female","alone","never","Placebo","guideline","yes","no","no","0","12","yes","no","yes","no","no","no","288.73","2","13","6","68"
+"237.87","73","male",NA,NA,"Active",NA,NA,NA,"no","0","4","no","no","no","no",NA,"no","169.58","1","9","2","96"
+"239.76","36","male","partner","ever","Active","guideline","no","no","no","0","0","no","no","no","no","no","no","181.4","2","18","8","56"
+"106.68","78","female","partner","never","Active","guideline","no","yes","no","0","4","no","no","no","no","no","no","199.26","2","6","5","76"
+"50","71","female","partner","never","Active","guideline","no","yes","no","0","1","no","no","no","no","no","no","52.2","3","17","14","48"
+"52.2","38","male","partner","ever","Placebo","guideline","no","no","no","0","5","yes","no","no","no","no",NA,NA,NA,NA,NA,NA
+"85.25","79","male","partner","never","Active","guideline","no","yes","no","0","6","no","no","no","no","no",NA,NA,NA,NA,NA,NA
+"59.56","78","female","partner","ever","Active","more","no","yes","no","0","7","yes","no","no","no","no","no","131.2","4","16","12","68"
+"168.4","77","female","partner","ever","Active","guideline","no","yes","no","0","16","no","no","no","no","no","yes","0","4","16","18","52"
+"232","63","male","partner","ever","Placebo","guideline","no","yes","yes","0","3","no","no","no","no","no","no","162.08","2","14","15","68"
+"116.53","77","male","partner","never","Placebo","guideline","no","yes","yes","0","8","yes","no","yes","no","no",NA,NA,NA,NA,NA,NA
+"89.12","75","male","partner","never","Active","guideline","no","yes","no","0","6","no","no","no","no","no","no","159.71","1","13","13","64"
+"50","68","female","alone","never","Active","guideline","no","no","no","0","2","no","no","no","no","no","no","129.1","0","12","4","72"
+"199.72","56","male","partner","never","Active","guideline","no","no","no","0","2","yes","no","no","no","no","no","172.02","1","18","7","76"
+"176.89","83","female","alone","never","Active","guideline","no","yes","no","0","5","no","no","no","no","no","no","138.53","0","13","2","92"
+"143.71","71","male","partner","never","Placebo","more","no","no","no","0","5","no","no","no","no","no","yes","68.25","1","20","19","16"
+"148.11","68","male","partner","never","Active","more","no","yes","no","2",NA,"no","no","no","no","no","yes","58.4","2","20","45","4"
+"91.4","74","male","partner","ever","Placebo","guideline","no","yes","no","0","5","no","no","no","yes","no","no","170.49","1","13","3","76"
+"256.8","79","female","alone",NA,"Placebo",NA,"no","yes","no","0","21","no","yes","no","no","no","yes","0","4","10","15","20"
+"58.4","69","male","partner","ever","Placebo","guideline","yes","yes","no","0","17","yes","no","no","no","no","no","149.77","1","14",NA,"56"
+"162.99","67","female","partner","never","Active","guideline","no","no","no","0","4","yes","no","no","no","no",NA,NA,NA,NA,NA,NA
+"108.2","76","female","alone","never","Active","guideline","yes","no","no","2","2","no","no","no","no","no","yes","27.2","2","11","12","52"
+"119.51","48","female","partner","never","Active","guideline","no","no","no","0","15","yes","no","yes","no","no","no","167.11","2","14","6","68"
+"475.41","67","male","partner","never","Active","guideline","no","yes","no","0","1","no","no","no","yes","no","no","166","0","5","3","72"
+"31.4","82","female","alone","never","Placebo","guideline","no","yes","no","0","5","no","no","no","no",NA,NA,NA,"4",NA,NA,NA
+"161.86","70","female","partner","never","Placebo","guideline","no","no","no","1","7","yes","no","no","no","no","no","96.86","2",NA,"5","84"
+"25","94","female","alone","ever","Placebo","guideline","yes","yes","no","3","12","no","no","no","no","no",NA,NA,"4","13","32","80"
+"54.51","93","female","alone","never","Placebo","guideline","yes","yes","no","0","7","no","no","no","no","no",NA,NA,"5","15","18","28"
+"144.4","53","male","partner","never","Placebo","guideline","no","yes","no","0","3","no","no","no","no","no","yes","60.4","3","4","0","100"
+"55","42","male","alone","never","Active","guideline","no","no","no","0","2","yes","no","no","no","yes","no","58.4","1","18","8","48"
+"294.3","56","male","partner","never","Placebo","guideline","no","yes","no","0","5","yes","no","no","no","no",NA,NA,"1","6","5","88"
+"110.8","61","female","partner","never","Active","guideline","no","yes","yes","0","22","yes","no","yes","no","no",NA,NA,"6",NA,NA,NA
+"256.8","59","female","alone","never","Placebo","guideline","no","no","no","0","0","no","no","no","no","no","no","95.8","1","14","10","64"
+"255.91","69","female","partner","ever","Active","guideline","no","yes","no","2","5","yes","no","no","no","no","no","260.34","2","16","10","44"
+"264.65","47","male","partner","ever","Active","guideline","no","no","no","0","3","yes","no","no","no","no","no","305.28","1","16","4","68"
+"93.44","44","male","alone","never","Active","more","no","no","no","0","3","no","no","no","no","no","no","161.94","3","12","7","64"
+"132.5","69","male","partner","ever","Placebo","guideline","no","no","no","0","2","yes","no","no","no","no","no","179.32","0","12","6","60"
+"78.08","77","female","partner","never","Placebo","guideline","no","yes","no","0","15","yes","no","yes","no","no",NA,NA,"1",NA,NA,NA
+"108.4","75","male","alone","ever","Placebo","guideline","no","no","no","0","1","yes","no","no","no","no",NA,NA,"2","14","6","36"
+"33.93","86","female","alone","ever","Placebo","guideline","yes","no","no","2","24","yes","no","no","no","no","no","0","4","10","2","68"
+"574.26","70","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","no","225.16","1","8","3","80"
+"309.5","56","male","partner","never","Active","guideline","no","no","no","0","1","yes","no","no","no","no","no","435.76","1","13","5","76"
+"247","48","female","partner","never","Placebo","guideline","no","no","no","0","12","yes","no","no","no","no","no","138.2","2","15","3","68"
+"136","55","male","partner","never","Active","guideline","no","no","no","0","13","yes","no","yes","no","no","no","172.2","0","13","6","52"
+"302.8","45","male","alone","never","Active","guideline","no","yes","no","0","0","no","no","no","no","no","no","121.4","2","12","4","92"
+NA,"79","male","partner","ever","Active","guideline","yes","yes","no","0","19","yes","no","yes","no","no",NA,NA,NA,NA,NA,NA
+"173.2","81","male","partner","never","Placebo","guideline","no","no","no","0","5","no","no","no","no","no","no","111.4","1","10","7","84"
+"152.11","79","male","alone","ever","Placebo","guideline","no","yes","no","0","1","no","no","no","yes","no","no","395.56","0","10","7","96"
+"238.23","57","male","alone","ever","Placebo","guideline","no","no","no","0","12","no","no","no","no","no","no","216.36","2","8","1","44"
+"229.16","83","male","alone","ever","Active","guideline","no","no","no","0","11","no","no","no","no","no","no","299.23","4","12","1","100"
+"136","82","male","alone","never","Placebo","guideline","no","yes","yes","1","18","no","no","no","no","no",NA,NA,"4","17","18","16"
+"61","79","male","partner","never","Placebo","guideline","no","yes","no","2","2","no","yes","no","yes","no","no","27.2","2",NA,NA,NA
+"221.8","77","male","alone","never","Active","guideline","yes","yes","no","0","22","no","no","no","no","no","yes","41.55","4",NA,"4","52"
+"149.16","49","male","partner","never","Placebo","guideline","no","no","no","1","2","no","no","no","no","no","no","256.55","2","10","1","80"
+"373.58","47","male","partner","ever","Active","guideline","no","no","no","0","6","yes","no","no","no","no","no","176.61","2","19","24","28"
+"204.4","81","female","alone","never","Active","guideline","no","no","no","0","6","no","no","no","no","no","no","114.82","1","17","9","60"
+"173.2","24","female","partner","ever","Active","guideline","no","no","no","0","1","no","no","no","no","no","no","171.2","2","10","6","64"
+"121","70","male","partner","never","Active","more","no","no","no","0","2","no","no","no","yes","no",NA,NA,NA,NA,NA,NA
+"0","68","male","partner","ever","Placebo","guideline","yes","yes","yes","0","8","no","no","no","no","no",NA,NA,"2","7","4","16"
+"141.4","80","male","partner","never","Active","guideline","no","no","no","0","5","no","no","no","no","no","yes","4.51","2","5","0","88"
+"46","67","male","partner","never","Active","guideline","no","yes","no","1","18","yes","yes","no","no","no",NA,NA,"4","18","18","68"
+"206","55","male","alone","ever","Active","guideline","no","no","no","0","1","no","no","no","no","no",NA,NA,"1","9","6","88"
+"160.11","77","male","partner","ever","Placebo","guideline","no","no","no","0","4","no","no","yes","no","no","no","124.44","1","9","6","68"
+"60.61","71","female","partner","never","Active","guideline","no","yes","no","0","5","no","no","no","no","no","no","58.94","1","20","22","24"
+"148.49","63","female","partner","never","Placebo","guideline","no","yes","no","0","3","no","no","no","no","no","no","95.05","0",NA,NA,NA
+"5","62","male","partner","ever","Placebo","guideline","no","yes","yes","2","19","yes","no","no","yes","no","no","123.93","2","18","36","36"
+"98.17","61","male","partner","never","Active","more","no","yes","no","0","2","no","no","no","no","yes","no","157.12","3","5","9","80"
+"302.4","77","female","alone","never","Placebo","guideline","yes","yes","no","0","11","yes","no","no","no","no","no","180.6","3","11","9","72"
+"110.8","77","male","partner","never","Placebo","guideline","no","no","no","0","1","no","no","no","no","no","yes","58.4","1","11","7","72"
+"166.8","90","male","alone","never","Placebo","more","yes","yes","no","0","10","no","no","no","no","no","yes","58.4","3","13","6","80"
+"162.01","71","female","alone","ever","Placebo","guideline","no","yes","no","0","1","yes","no","no","no","no","no","160.68","1","5","1","92"
+"156","68","female","alone","never","Active","more","no","yes","no","0","12","yes","no","no","no","no","no","85.46","2","4","1","100"
+"390.27","62","male","partner","ever","Active","guideline","no","no","yes","0","2","no","no","no","no","no","no","250.66","2","8","12","100"
+"155.96","57","male","partner","never","Placebo","guideline","no","no","no","0","1","no","no","no","no","no","no","150.76","1","10","8","64"
+"58.4","72","male","alone","never","Placebo","more","no","no","no","0","7","no","no","no","no","no",NA,NA,"2","15","5","56"
+"199.87","79","male","partner","never","Placebo","guideline","no","no","no","0","3","no","no","no","yes","no",NA,NA,NA,NA,NA,NA
+"75.8","76","female","partner","never","Active","guideline","no","yes","no","0","3","no","no","no","no","no","no","59.7","2","19","8","64"
+"0","67","male","partner","never","Active","guideline","no","no","no","0","3","no","no","no","no","no","no","119.05","2","6","5","80"
+"131.8","66","male","partner","never","Placebo","guideline","no","no","no","0","1","no","no","no","no","no","no","121.4","1","10","4","76"
+"95.8","83","female","partner","never","Active","more","no","yes","no","1","2","no","no","no","no","no","yes","56.4","2","10","15","24"
+"90","71","male","alone","never","Placebo","guideline","no","no","no","0","6","no","no","no","no","no","yes","55","1","4","4","100"
+"67.22","68","male","alone","never","Placebo","guideline","no","yes","no","1","2","yes","no","no","no","no","no","137.89","2","8","3","84"
+"162.72","52","male","partner","never","Placebo","more","no","yes","no","0","3","yes","no","no","no","no","no","391.48","0","6","3","76"
+"227.33","80","male","partner","never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","no","284.33","1","6",NA,"100"
+"188.48","84","male","partner","never","Placebo","guideline","yes","yes","yes","1","1","no","no","no","no","no","no","172.72","1","10","6","76"
+"229.2","50","male","partner","never","Placebo","guideline","no","no","no","0","3","no","no","no","no","no",NA,NA,"2","11","16","76"
+"197.15","44","male","partner","ever","Placebo","guideline","no","no","no","0","7","yes","no","no","no","no","no","245.75","1","8","6","76"
+NA,"63","male","partner","never","Placebo","guideline","no","no","no","0","2","yes","no","no","no","no",NA,NA,NA,NA,NA,NA
diff --git a/1 PA Decline/archive/generation_1/data_format.R b/1 PA Decline/archive/generation_1/data_format.R
new file mode 100644
index 0000000..2c3113f
--- /dev/null
+++ b/1 PA Decline/archive/generation_1/data_format.R
@@ -0,0 +1,290 @@
+## ItMLiHSmar2022
+## data_format.R, child script
+## Data formatting and handling
+## Andreas Gammelgaard Damsbo, agdamsbo@clin.au.dk
+##
+## Now modified to use in publication
+##
+
+## ====================================================================
+# Step 1: Loading libraries
+## ====================================================================
+
+library(Hmisc)
+library(dplyr)
+library(daDoctoR)
+library(tidyselect)
+
+## ====================================================================
+# Step 2: Loading data
+## ====================================================================
+
+# rm(list = ls()) # Clear
+# setwd("/Users/au301842/Library/CloudStorage/OneDrive-Personligt/Research/ISLcourse/")
+# dta<-read.csv("/Users/au301842/Library/CloudStorage/OneDrive-Personligt/Research/ISLcourse/assigndata.csv")
+
+## ====================================================================
+# Step 3: Formatting variables
+## ====================================================================
+
+dta <- export %>%
+ # as_tibble()%>%
+ mutate(any_rep=factor(ifelse(thrombolysis=="yes"|thrombechtomy=="yes","yes","no")), # If not noted, no therapy was received
+ male_sex= factor(ifelse(sex=="female","no","yes")),
+ # smoke_ever=factor(ifelse(smoke_ever=="never","no","yes")),
+ civil=factor(ifelse(civil=="partner","no","yes")), # Sets "yes" for not-cohabiting
+ rtreat=factor(ifelse(rtreat=="Placebo","no","yes")), # "Yes" receives active treatment
+ alc=factor(ifelse(alc=="more","yes","no")), # Yes for more than guideline
+ pase_0=as.numeric(pase_0),
+ pase_6=as.numeric(pase_6),
+ across(c("diabetes",
+ "hypertension",
+ "smoker",
+ # "smoker_prev",
+ "afli",
+ "pad",
+ "ami",
+ "tci",
+ "mrs_0",
+ "mrs_1"),as.factor),
+ across(c("nihss_c",
+ "age",
+ "mdi_1", # For "enriched" analysis
+ "who5_score_1",
+ "mfi_gen_1",
+ "mfi_phys_1",
+ "mfi_act_1",
+ "mfi_mot_1",
+ "mfi_men_1"),as.numeric )
+ )%>%
+ select(-c(sex))
+
+
+## ====================================================================
+# Step 4: Defining outcome
+## ====================================================================
+
+## Changed to step 7
+## This is to perform proper quantile split based on actually included.
+
+## ====================================================================
+# Step 5: Ordering variables
+## ====================================================================
+
+vars <- c("age",
+ "male_sex",
+ "civil",
+ "pase_0",
+ "smoker",
+ "alc",
+ "afli",
+ "hypertension",
+ "diabetes",
+ "pad",
+ "ami",
+ "tci",
+ "mrs_0",
+ "nihss_c",
+ "any_rep",
+ "rtreat",
+ "pase_6")
+
+dta<-select(dta,c(vars,
+ "mrs_1",
+ "mfi_gen_1",
+ "mfi_phys_1",
+ "mfi_act_1",
+ "mfi_mot_1",
+ "mfi_men_1",
+ "mdi_1",
+ "who5_score_1"
+ ))
+
+## ====================================================================
+# Step 6: Labeling
+## ====================================================================
+
+var.labels = c(age="Age",
+ male_sex="Male",
+ civil="Living alone",
+ pase_0="Pre-stroke PASE score",
+ pase_6="Six month PASE score",
+ smoker="Daily or occasinally smoking",
+ # smoker_prev="Previous habbit of smoking",
+ alc="More alcohol than recommendation",
+ afli="AFIB",
+ hypertension="Hypertension",
+ diabetes="Diabetes",
+ pad="PAD",
+ ami="Previous MI",
+ tci="Previous TIA",
+ mrs_0="Pre-stroke mRS [-1]",
+ nihss_c="Acute NIHSS score",
+ thrombolysis="Acute thrombolysis",
+ thrombechtomy="Acute thrombechtomy",
+ any_rep="Any reperfusion therapy",
+ rtreat="Active trial treatment",
+ mrs_1="One month mRS [-1]",
+ mfi_gen_1="One month MFI (General fatigue)",
+ mfi_phys_1="One month MFI (Physical fatigue)",
+ mfi_act_1="One month MFI (Reduced activity)",
+ mfi_mot_1="One month MFI (Reduced motivation)",
+ mfi_men_1="One month MFI (Mental fatigue)",
+ mdi_1="One month MDI",
+ who5_score_1="One month WHO5",
+ pase_decl_rel_fac="PASE score difference, relative F",
+ pase_decl_abs_fac="PASE score difference, absolute F",
+ pase_drop_fac="PASE first quartile drop F",
+ pase_hop_fac="PASE first quartile hop F",
+ pase_diff="PASE absolute decline",
+ pase_decl_rel="PASE relative decline",
+ pase_0_cut="PASE 0 quartiles",
+ pase_6_cut="PASE 6 quartiles")
+
+## Labelling based on outcome flag
+if (pout=="decl_rel"|pout=="decl_abs"){
+ var.labels = c(var.labels,group="PASE decline")}
+if (pout=="drop"){
+ var.labels = c(var.labels,group="PASE drop")}
+
+## ====================================================================
+# Step 7: final data export
+## ====================================================================
+
+data_summary<-summary(dta)
+
+# Saving "old" factorised variables
+sel<-sapply(dta,is.factor)
+# Reformatting factors as 1/2 for analysis
+dta<-dta |>
+ mutate(across(where(is.factor), as.numeric))|> # Turning factors into 1(no) or 2(yes) for model. Numbered alphabetically.
+ mutate(across(matches(colnames(dta)[sel]), as.factor),
+ across(starts_with("pase_"), as.numeric))
+
+# Filtering out non-PASE
+X_tbl<-dta |>
+ filter(!is.na(pase_0),!is.na(pase_6))
+
+nrow(X_tbl)
+
+# Defining possible outcome meassures. Keeping in df for characterisation
+X_tbl <- X_tbl|>
+ mutate(## Relative decline
+ pase_diff=(pase_0-pase_6),
+ pase_decl_rel = pase_diff/pase_0*100,
+ pase_decl_rel_fac=factor(ifelse(pase_decl_rel>=rel_dif,"yes","no")),
+ ## Absolute decline
+ pase_decl_abs_fac=factor(ifelse(pase_diff>=abs_dif,"yes","no")),
+ ## Drop
+ pase_0_cut=quantile_cut(as.numeric(pase_0),
+ groups=4,
+ group.names = c(as.character(1:4)),
+ y=as.numeric(pase_0),
+ ordered.f = TRUE,
+ inc.outs = TRUE,
+ detail.lst=FALSE),
+ pase_6_cut=quantile_cut(as.numeric(pase_6),
+ groups=4,
+ group.names = c(as.character(1:4)),
+ y=as.numeric(pase_0),
+ ordered.f = TRUE,
+ inc.outs = TRUE,
+ detail.lst=FALSE),
+ pase_drop_fac=factor(ifelse(pase_6_cut==1&pase_0_cut!=1,"yes","no")),
+ pase_hop_fac=factor(ifelse(pase_6_cut!=1&pase_0_cut==1,"yes","no")))
+
+Hmisc::label(X_tbl) = as.list(var.labels[match(names(X_tbl), names(var.labels))])
+
+# Setting final primary output from "pout"
+if (pout=="decl_rel"){
+ X_tbl <- X_tbl|>
+ mutate(group=pase_decl_rel_fac)
+
+ X_tbl_f <- X_tbl|>
+ filter(pase_0!=0)|>
+ select(-starts_with("pase_"))
+}
+
+if (pout=="decl_abs"){
+ X_tbl <- X_tbl|>
+ mutate(group=pase_decl_rel_fac)
+
+ X_tbl_f <- X_tbl|>
+ filter(pase_0>=abs_dif)|>
+ select(-starts_with("pase_"))
+}
+
+if (pout=="drop"){
+ X_tbl <- X_tbl|>
+ mutate(group=pase_drop_fac)
+
+ # print(quantile(as.numeric(X_tbl$pase_0)))
+ # print(quantile(as.numeric(X_tbl$pase_6)))
+ # print(summary(X_tbl$pase_0_cut))
+
+ X_tbl_f <- X_tbl|>
+ filter(pase_0_cut!=1)|>
+ select(-starts_with("pase_"))
+}
+
+if (pout=="hop"){
+ X_tbl <- X_tbl|>
+ mutate(group=pase_hop_fac)
+
+ # print(quantile(as.numeric(X_tbl$pase_0)))
+ # print(quantile(as.numeric(X_tbl$pase_6)))
+ # print(summary(X_tbl$pase_0_cut))
+
+ X_tbl_f <- X_tbl|>
+ filter(pase_6_cut!=1)|>
+ select(-starts_with("pase_"))
+}
+
+# Excluding one month measures for primary analysis and setting df for table one
+X_tbl_f <- X_tbl_f |>
+ select(-c(who5_score_1,
+ mdi_1,
+ mrs_1,
+ starts_with("mfi_"))) # Left out of model as no present in drop-group
+
+# Dropping non-complete for analysis
+Xy <- X_tbl_f|>
+ na.omit()|> # Keeping only complete observations
+ select(-c(tci) # Left out of model as no present in drop-group
+ )|>
+ mutate(mrs_0=factor(ifelse(mrs_0==1,1,2))) # Sets binary mRS 0 to include in glmnet, 0 or above
+
+label(Xy) = as.list(var.labels[match(names(Xy), names(var.labels))])
+
+X<-dplyr::select(Xy,-c(group, -starts_with("pase_")) # Exclude primary outcome
+ )
+y<-Xy$group
+
+
+## ====================================================================
+# Secondary analysis
+## ====================================================================
+
+
+dta_s<-X_tbl|>
+ select(-c(tci),
+ -starts_with("pase_"))|>
+ na.omit()|>
+ mutate(mrs_0=factor(ifelse(mrs_0==1,1,2)),# Sets binary mRS 0 to include in glmnet, 0 or above
+ mrs_1=factor(ifelse(mrs_1==1,1,2)))# Sets binary mRS 1 to include in glmnet, 0 or above
+
+label(dta_s) = as.list(var.labels[match(names(dta_s), names(var.labels))])
+
+## ====================================================================
+# Step 8: Loading rest of libraries
+## ====================================================================
+
+library(tidyverse)
+library(patchwork)
+library(caret)
+library(glmnet)
+library(leaps)
+library(pROC)
+library(gt)
+library(gtsummary)
+library(dplyr)
diff --git a/1 PA Decline/archive/generation_1/data_set.R b/1 PA Decline/archive/generation_1/data_set.R
new file mode 100644
index 0000000..f7455fc
--- /dev/null
+++ b/1 PA Decline/archive/generation_1/data_set.R
@@ -0,0 +1,49 @@
+## ItMLiHS assignment data set
+
+export<-read.csv("/Volumes/Data 1/exercise/source/background.csv",colClasses = "character", na.strings = c("NA","","unknown"))
+
+export<-export[,c("pase_0",
+ "age",
+ "sex",
+ "civil",
+ "smoke_ever",
+ "smoker",
+ "rtreat",
+ "alc",
+ "afli",
+ "hypertension",
+ "diabetes",
+ "mrs_0",
+ "nihss_c",
+ "thrombolysis",
+ "pad",
+ "thrombechtomy",
+ "ami",
+ "tci",
+ "pase_6",
+ "mrs_1",
+ "mfi_gen_1",
+ "mfi_phys_1",
+ "mfi_act_1",
+ "mfi_mot_1",
+ "mfi_men_1",
+ "mdi_1",
+ "who5_score_1")]
+
+export$diabetes[is.na(export$diabetes)]<-"no"
+export$diabetes[is.na(export$hypertension)]<-"no"
+export$thrombolysis[is.na(export$thrombolysis)]<-"no"
+export$thrombechtomy[is.na(export$thrombechtomy)]<-"no"
+export$pad[is.na(export$pad)]<-"no"
+export$ami[is.na(export$ami)]<-"no"
+# export$smoker_prev <- ifelse(export$smoker=="3","yes","no")
+export$smoker <- ifelse(export$smoker=="1","yes","no")
+export$smoker[is.na(export$smoker)] <- "no"
+# export$mrs_0[export$mrs_0==3]<-NA
+
+
+
+# export<-na.omit(export)
+
+export
+# write.csv(export,"/Users/au301842/Library/CloudStorage/OneDrive-Personligt/Research/ISLcourse/assigndata.csv",row.names = FALSE)
diff --git a/1 PA Decline/archive/generation_1/dataset_redcap.R b/1 PA Decline/archive/generation_1/dataset_redcap.R
new file mode 100644
index 0000000..1b0bf62
--- /dev/null
+++ b/1 PA Decline/archive/generation_1/dataset_redcap.R
@@ -0,0 +1,138 @@
+# Data
+## Import from previous work
+# dta<-read.csv("/Volumes/Data/exercise/source/background.csv",na.strings = c("NA","","unknown"),colClasses = "character")
+
+library(REDCapR)
+library(lubridate)
+library(dplyr)
+library(daDoctoR)
+
+# source("https://raw.githubusercontent.com/agdamsbo/daDoctoR/master/R/dob_extract_cpr_function.R")
+
+dta <- redcap_read_oneshot(
+ redcap_uri = "https://redcap.au.dk/api/",
+ token = read.csv("/Users/au301842/talos_redcap_token.csv",header = FALSE)[[1]],
+ fields = c("talos_basis02a", #Indlæggelsesdato
+ "cpr",
+ "talos_nihss16_0", #Akut NIHSS
+ "basis_kon",
+ "reg_hojde", #Alle fra "reg(ister/DAP)"
+ "reg_vaegt",
+ "reg_vaegt_anslaaet",
+ "reg_rygning",
+ "reg_alkohol",
+ "reg_civil",
+ "reg_bolig",
+ "reg_diabetes",
+ "reg_hyperten",
+ "reg_perifer_arteriel",
+ "reg_atriefli",
+ "reg_ami",
+ "reg_tidl_tci",
+ "reg_trombolyse",
+ "reg_trombektomi",
+ "rtreat" #Trial treatment
+ )
+)$data |>
+ mutate(age=time_length(talos_basis02a-dob_extract_cpr(cpr),
+ unit="year")
+ )|>
+ select(!c("cpr"))
+
+
+
+
+## Cleaning and enhancing
+dta$pase_drop<-factor(ifelse((dta$pase_0_q=="q_2"|dta$pase_0_q=="q_3"|dta$pase_0_q=="q_4")&dta$pase_06_q=="q_1","yes","no"),levels = c("no","yes"))
+dta$pase_drop[is.na(dta$pase_6)]<-NA
+dta$pase_drop[is.na(dta$pase_0)]<-NA
+
+## Selection of data set and formatting
+library(dplyr)
+dta_f<-dta %>% filter(pase_0_q != "q_1" & !is.na(pase_drop))
+
+
+variable_names<-c("age","sex","weight","height",
+ "bmi",
+ "smoke_ever",
+ "civil",
+ "diabetes",
+ "hypertension",
+ "pad",
+ "afli",
+ "ami",
+ "tci",
+ "nihss_0",
+ "thrombolysis",
+ "thrombechtomy",
+ "rep_any","pase_0_q","pase_drop")
+
+
+library(daDoctoR)
+dta2<-dta_f[,variable_names]
+
+dta2<-col_num(c("age","weight","height","bmi","nihss_0"),dta2)
+dta2<-col_fact(c("sex","smoke_ever","civil","diabetes", "hypertension","pad", "afli", "ami", "tci","thrombolysis", "thrombechtomy","rep_any","pase_0_q","pase_drop"),dta2)
+
+## Partitioning
+library(caret)
+set.seed(100)
+
+## Step 1: Get row numbers for the training data
+trainRowNumbers <- createDataPartition(dta2$pase_drop, p=0.8, list=FALSE)
+
+## Step 2: Create the training dataset
+trainData <- dta2[trainRowNumbers,]
+
+## Step 3: Create the test dataset
+testData <- dta2[-trainRowNumbers,]
+y_test = testData[,"pase_drop"]
+
+# Store X and Y for later use.
+x = trainData %>% select(!matches("pase_drop"))
+y = trainData[,"pase_drop"]
+
+# Normalization and dummy binaries
+
+# One-Hot Encoding
+# Creating dummy variables is converting a categorical variable to as many binary variables as here are categories.
+dummies_model <- dummyVars(pase_drop ~ ., data=trainData)
+
+# Create the dummy variables using predict. The Y variable (Purchase) will not be present in trainData_mat.
+trainData_mat <- predict(dummies_model, newdata = trainData)
+
+# # Convert to dataframe
+trainData <- data.frame(trainData_mat)
+
+# # See the structure of the new dataset
+str(trainData)
+
+dummies_model <- dummyVars(pase_drop ~ ., data=testData)
+testData_mat <- predict(dummies_model, newdata = testData)
+testData <- data.frame(testData_mat)
+preProcess_range_model <- preProcess(testData, method='range')
+testData <- predict(preProcess_range_model, newdata = testData)
+testData$pase_drop<-y_test
+
+# Imputation
+
+library(RANN) # required for knnInpute
+preProcess_missingdata_model <- preProcess(trainData, method='knnImpute')
+# preProcess_missingdata_model
+
+trainData <- predict(preProcess_missingdata_model, newdata = trainData) # Giver fejl??
+anyNA(trainData)
+
+# skimr::skim(trainData)
+# skimr::skim(x)
+
+preProcess_range_model <- preProcess(trainData, method='range')
+trainData <- predict(preProcess_range_model, newdata = trainData)
+
+# Append the Y variable
+trainData$pase_drop <- y
+
+
+# Export
+write.csv(trainData,"/Users/au301842/PhysicalActivityandStrokeOutcome/data/trainData.csv",row.names = FALSE)
+write.csv(testData,"/Users/au301842/PhysicalActivityandStrokeOutcome/data/testData.csv",row.names = FALSE)
diff --git a/1 PA Decline/archive/generation_1/pc_plot.png b/1 PA Decline/archive/generation_1/pc_plot.png
new file mode 100644
index 0000000..a3757f5
Binary files /dev/null and b/1 PA Decline/archive/generation_1/pc_plot.png differ
diff --git a/1 PA Decline/archive/generation_1/regular_fun.R b/1 PA Decline/archive/generation_1/regular_fun.R
new file mode 100644
index 0000000..1b457b0
--- /dev/null
+++ b/1 PA Decline/archive/generation_1/regular_fun.R
@@ -0,0 +1,117 @@
+## ItMLiHSmar2022
+## regular_fun.R, child script
+## Regularisation model building function
+## Andreas Gammelgaard Damsbo, agdamsbo@clin.au.dk
+##
+## Now modified to use in publication
+##
+
+regular_fun<-function(X,y,K,lambdas,alpha){
+n<-nrow(X)
+set.seed(321)
+
+# Using caret function to ensure both levels represented in all folds
+c<-createFolds(y=y, k = K, list = FALSE, returnTrain = TRUE)
+
+B<-yhatTestProbKeep<-list()
+accTrain<-accTest<-err_train<-err_test<-auc_train<-auc_test<-matrix(nrow = K,ncol = length(lambdas))
+
+catinfo<-levels(y)
+
+cMatTrain<-cMatTest<-table(true=factor(c(0,0),levels=catinfo),pred=factor(c(0,0),levels=catinfo))
+
+
+## Iterate over partitions
+for (idx1 in 1:K){
+
+ # Status
+ cat('Processing fold', idx1, 'of', K,'\n')
+
+ # idx1=1
+ # Get training- and test sets
+ I_train = c!=idx1 ## Creating selection vector of TRUE/FALSE
+ I_test = !I_train
+
+ Xtrain = X[I_train,]
+ ytrain = y[I_train]
+ Xtest = X[I_test,]
+ ytest = y[I_test]
+
+
+ ## Model matrices for glmnet
+ ## Using the complicated approach not to include first level.
+ # Xmat.train<-model.matrix(~ .-1, data=Xtrain,
+ # contrasts.arg = lapply(Xtrain[,sapply(Xtrain, is.factor)],
+ # contrasts, contrasts=T))
+ # Xmat.test<-model.matrix(~ .-1, data=Xtest,
+ # contrasts.arg = lapply(Xtest[,sapply(Xtest, is.factor)],
+ # contrasts, contrasts=T))
+
+ # Xmat.train<-model.matrix(~.-1,Xtrain)
+ # Xmat.test<-model.matrix(~.-1,Xtest)
+
+ # Weights
+ ytrain_weight<-as.vector(1 - (table(ytrain)[ytrain] / length(ytrain)))
+ # ytest_weight<-as.vector(1 / (table(ytest)[ytest] / length(ytest)))
+
+ # Fit regularized linear regression model
+ mod<-glmnet(Xtrain, ytrain,
+ alpha = alpha, ## Alpha = 1 for lasso
+ lambda = lambdas, ## Setting lambdas
+ standardize = TRUE, ## Scales and centers
+ weights = ytrain_weight,
+ family = "binomial"
+ )
+
+ # Keep coefficients for plot
+ B[[idx1]] <- as.matrix(coef(mod))
+
+ # Iterate over regularization strengths to compute training- and test
+ # errors for individual regularization strengths.
+ for (idx2 in 1:length(lambdas)){
+ # idx2=1
+
+ # Predict
+ yhatTrainProb<-predict(mod,
+ s = lambdas[idx2],
+ newx = data.matrix(Xtrain),
+ type = "response"
+ )
+
+ yhatTestProb<-predict(mod,
+ s = lambdas[idx2],
+ newx = data.matrix(Xtest),
+ type = "response"
+ )
+
+ # Compute training and test error
+ yhatTrain = round(yhatTrainProb)
+ yhatTest = round(yhatTestProb)
+
+ # Make predictions categorical again (instead of 0/1 coding)
+ yhatTrainCat = factor(round(yhatTrainProb),levels=c("0","1"),labels=catinfo,ordered = TRUE)
+ yhatTestCat = factor(round(yhatTestProb),levels=c("0","1"),labels=catinfo,ordered = TRUE)
+
+ # Evaluate classifier performance
+ # Accuracy
+ # accTrain[idx1,idx2] <- sum(yhatTrainCat==ytrain)/length(ytrain)
+ # accTest [idx1,idx2] <- sum(yhatTestCat==ytest)/length(ytest)
+ # #
+ # # Error rate
+ # err_train[idx1,idx2] = 1 - accTrain[idx1,idx2]
+ # err_test [idx1,idx2] = 1 - accTest[idx1,idx2]
+
+ # AUROC
+ suppressMessages(
+ auc_train[idx1,idx2]<-auc(ytrain, yhatTrainCat))
+ suppressMessages(
+ auc_test [idx1,idx2]<-auc(ytest, yhatTestCat))
+
+ # Compute confusion matrices
+ cMatTrain = cMatTrain + table(true=ytrain,pred=yhatTrainCat)
+ cMatTest = cMatTest + table(true=ytest,pred=yhatTestCat)
+ }
+}
+ls<-list(mod=mod,B=B,auc_train=auc_train,auc_test=auc_test,cMatTrain=cMatTrain,cMatTest=cMatTest)
+return(ls)
+}
diff --git a/1 PA Decline/archive/generation_1/regularisation_steps.R b/1 PA Decline/archive/generation_1/regularisation_steps.R
new file mode 100644
index 0000000..faf9a23
--- /dev/null
+++ b/1 PA Decline/archive/generation_1/regularisation_steps.R
@@ -0,0 +1,142 @@
+## ItMLiHSmar2022
+## regularisation_steps.R, child script
+## Regularised model building and analysation for assignment
+## Andreas Gammelgaard Damsbo, agdamsbo@clin.au.dk
+##
+## Now modified to use in publication
+##
+
+## ====================================================================
+## Step 0: data import and wrangling
+## ====================================================================
+
+setwd("/Users/au301842/PhysicalActivityandStrokeOutcome/1 PA Decline/")
+
+# source("data_format.R")
+y1<-factor(as.integer(y)-1) ## Outcome is required to be factor of 0 or 1.
+
+
+## ====================================================================
+## Step 1: settings
+## ====================================================================
+
+## Folds
+K=10
+set.seed(3)
+c<-caret::createFolds(y=y,
+ k = K,
+ list = FALSE,
+ returnTrain = TRUE) # Foldids for alpha tuning
+
+## Defining tuning parameters
+lambdas=2^seq(-10, 5, 1)
+alphas<-seq(0,1,.1)
+
+## Weights for models
+weighted=TRUE
+if (weighted == TRUE) {
+ wght<-as.vector(1 - (table(y)[y] / length(y)))
+} else {
+ wght <- rep(1, nrow(y))
+}
+
+
+## Standardise numeric
+## Centered and
+
+
+
+## ====================================================================
+## Step 2: all cross validations for each alpha
+## ====================================================================
+
+library(furrr)
+library(purrr)
+library(doMC)
+registerDoMC(cores=6)
+
+# Nested CVs with analysis for all lambdas for each alpha
+#
+set.seed(3)
+cvs <- future_map(alphas, function(a){
+ cv.glmnet(model.matrix(~.-1,X),
+ y1,
+ weights = wght,
+ lambda=lambdas,
+ type.measure = "deviance", # This is standard measure and recommended for tuning
+ foldid = c, # Per recommendation the folds are kept for alpha optimisation
+ alpha=a,
+ standardize=TRUE,
+ family=quasibinomial,
+ keep=TRUE) # Same as binomial, but not as picky
+})
+
+## ====================================================================
+# Step 3: optimum lambda for each alpha
+## ====================================================================
+
+
+# For each alpha, lambda is chosen for the lowest meassure (deviance)
+each_alpha <- sapply(seq_along(alphas), function(id) {
+ each_cv <- cvs[[id]]
+ alpha_val <- alphas[id]
+ index_lmin <- match(each_cv$lambda.min,
+ each_cv$lambda)
+ c(lamb = each_cv$lambda.min,
+ alph = alpha_val,
+ cvm = each_cv$cvm[index_lmin])
+})
+
+# Best lambda
+best_lamb <- min(each_alpha["lamb", ])
+
+# Alpha is chosen for best lambda with lowest model deviance, each_alpha["cvm",]
+best_alph <- each_alpha["alph",][each_alpha["cvm",]==min(each_alpha["cvm",]
+ [each_alpha["lamb",] %in% best_lamb])]
+
+## https://stackoverflow.com/questions/42007313/plot-an-roc-curve-in-r-with-ggplot2
+p_roc<-roc.glmnet(cvs[[1]]$fit.preval, newy = y)[[match(best_alph,alphas)]]|> # Plots performance from model with best alpha
+ ggplot(aes(FPR,TPR)) +
+ geom_step() +
+ coord_cartesian(xlim=c(0,1), ylim=c(0,1)) +
+ geom_abline()+
+ theme_bw()
+
+## ====================================================================
+# Step 4: Creating the final model
+## ====================================================================
+
+source("regular_fun.R") # Custom function
+optimised_model<-regular_fun(X,y1,K,lambdas=best_lamb,alpha=best_alph)
+# With lambda and alpha specified, the function is just a k-fold cross-validation wrapper,
+# but keeps model performance figures from each fold.
+
+list2env(optimised_model,.GlobalEnv)
+# Function outputs a list, which is unwrapped to Env.
+# See source script for reference.
+
+## ====================================================================
+# Step 5: creating table of coefficients for inference
+## ====================================================================
+
+Bmatrix<-matrix(unlist(B),ncol=10)
+Bmedian<-apply(Bmatrix,1,median)
+Bmean<-apply(Bmatrix,1,mean)
+
+reg_coef_tbl<-tibble(
+ name = c("Intercept",Hmisc::label(X)),
+ medianX = round(Bmedian,5),
+ ORmed = round(exp(Bmedian),5),
+ meanX = round(Bmean,5),
+ ORmea = round(exp(Bmean),5))%>%
+ # arrange(desc(abs(medianX)))%>%
+ gt()
+
+reg_coef_tbl
+
+## ====================================================================
+# Step 6: plotting predictive performance
+## ====================================================================
+
+reg_cfm<-confusionMatrix(cMatTest)
+reg_auc_sum<-summary(auc_test[,1])
diff --git a/1 PA Decline/archive/generation_1/roc_plot.png b/1 PA Decline/archive/generation_1/roc_plot.png
new file mode 100644
index 0000000..b1e51b9
Binary files /dev/null and b/1 PA Decline/archive/generation_1/roc_plot.png differ
diff --git a/1 PA Decline/archive/generation_1/sankey.R b/1 PA Decline/archive/generation_1/sankey.R
new file mode 100644
index 0000000..ad6ea82
--- /dev/null
+++ b/1 PA Decline/archive/generation_1/sankey.R
@@ -0,0 +1,72 @@
+#
+# Sankey plot of quartile movement for drops
+#
+
+gth<-X_tbl[,c("pase_0_cut","pase_6_cut","pase_drop_fac")]
+
+gth$pase_drop_fac <- factor(ifelse(gth$pase_0_cut=="1",
+ "low",
+ gth$pase_drop_fac),
+ labels = c("no","yes","low")) # Tried and tried to do vectorised, but failed. Matrices acting up..
+
+# Visuals - sankey
+# https://stackoverflow.com/questions/50395027/beautifying-sankey-alluvial-visualization-using-r
+
+
+## Painting
+# LOOK AT THIS GREAT FUNCTION!! Wide pivot format. Includes factor for possible quartile-colouring.
+
+df<-data.frame(gth %>% count(pase_0_cut,pase_6_cut,pase_drop_fac))
+
+lbs0<-c(paste0("1st\n(n=",sum(df$n[df[1]=="1"]),")"),
+ paste0("2nd\n(n=",sum(df$n[df[1]=="2"]),")"),
+ paste0("3rd\n(n=",sum(df$n[df[1]=="3"]),")"),
+ paste0("4th\n(n=",sum(df$n[df[1]=="4"]),")"))
+
+lbs6<-c(paste0("1st\n(n=",sum(df$n[df[2]=="1"]),")"),
+ paste0("2nd\n(n=",sum(df$n[df[2]=="2"]),")"),
+ paste0("3rd\n(n=",sum(df$n[df[2]=="3"]),")"),
+ paste0("4th\n(n=",sum(df$n[df[2]=="4"]),")"))
+
+df[1:2] <- as_factor(df[1:2])
+
+levels(df[,1])<-lbs0[1:length(levels(df[,1]))]
+levels(df[,2])<-lbs6[1:length(levels(df[,2]))]
+
+df[,3]<-factor(df[,3],levels=c("low","no","yes"))
+
+
+lows <- "grey80" # grey
+drops <- "#990033" # Midtrød
+nos <- "grey50"
+nas <- "grey90"
+border<- "#66c1a3"
+box <- "#7fccb2"
+
+cls <- c(lows,nos,drops)
+alpha <- 0.7
+
+library(ggalluvial)
+(p_delta<-ggplot(df,aes(y = n, axis1 = pase_0_cut, axis2 = pase_6_cut)) +
+ geom_alluvium(aes(fill = pase_drop_fac, color=pase_drop_fac), width = 1/10, alpha = alpha, knot.pos = 0.3)+
+ geom_stratum(width = 1/6, fill = box, color = border) +
+ geom_text(stat = "stratum", aes(label=after_stat(stratum))) +
+ scale_x_continuous(breaks = 1:2, labels = c("Pre-stroke\nPASE score\nquartiles", "Six months\nPASE score\nquartiles")) +
+ scale_fill_manual(values = cls) +
+ scale_color_manual(values = cls) +
+ scale_y_reverse() + # Easy solution to flip y-axis
+ labs(title="Change in physical activity") +
+ ylab("Quartiles")+
+ theme_minimal() +
+ theme(legend.position = "none",
+ panel.grid.major = element_blank(),
+ panel.grid.minor = element_blank(),
+ axis.text.y = element_blank(),
+ axis.title.y = element_blank(),
+ axis.text.x = element_text(size = 14, face = "bold"),
+ plot.title = element_text(hjust = 0.5, size = 20, face = "bold")))
+
+ggsave("sankey.png", plot = last_plot(), device = NULL, path = NULL,
+ scale = 1, width = 120, height = 200, dpi = 450, limitsize = TRUE,
+ units = "mm")
+
\ No newline at end of file
diff --git a/1 PA Decline/archive/generation_1/sankey.png b/1 PA Decline/archive/generation_1/sankey.png
new file mode 100644
index 0000000..aabb3ec
Binary files /dev/null and b/1 PA Decline/archive/generation_1/sankey.png differ
diff --git a/1 PA Decline/archive/generation_1/standardise.R b/1 PA Decline/archive/generation_1/standardise.R
new file mode 100644
index 0000000..2521e6d
--- /dev/null
+++ b/1 PA Decline/archive/generation_1/standardise.R
@@ -0,0 +1,41 @@
+## ItMLiHSmar2022
+## standardise.R, child script
+## Data standardisation, returns list
+## Andreas Gammelgaard Damsbo, agdamsbo@clin.au.dk
+
+standardise<-function(train,test,type){
+ # From:
+ # https://datascience.stackexchange.com/questions/13971/standardization-normalization-test-data-in-r
+
+ sel<-sapply(Xtrain,is.numeric) # Deciding which to stadardise (only numeric)
+ cnm<-colnames(Xtrain) # Saving column names for ordering
+
+ # Subsetting
+
+ ## Data to treat
+ train.tr<-train[,sel]
+ test.tr<-test[,sel]
+
+ ## Data to save
+ train.sv<-train[,!sel]
+ test.sv<-test[,!sel]
+
+ # Calculate mean and SD of train data
+ trainMean <- sapply(train.tr,mean)
+ trainSd <- sapply(train.tr,sd)
+
+ if (type=="c"){
+ ## centered
+ norm.trainData<-sweep(train.tr, 2L, trainMean) # using the default "-" to subtract mean column-wise
+ norm.testData<-sweep(test.tr, 2L, trainMean) # using the default "-" to subtract mean column-wise
+ }
+
+ if (type=="cs"){
+ ## centered AND scaled (Z-score standardisation)
+ norm.trainData<-sweep(sweep(train.tr, 2L, trainMean), 2, trainSd, "/")
+ norm.testData<-sweep(sweep(test.tr, 2L, trainMean), 2, trainSd, "/")
+ }
+ return(list(XtrainSt=cbind(norm.trainData,train.sv)[,cnm], # Reordering columns to original
+ XtestSt=cbind(norm.testData,test.sv)[,cnm]))
+}
+
diff --git a/1 PA Decline/archive/generation_1/table1.RTF b/1 PA Decline/archive/generation_1/table1.RTF
new file mode 100644
index 0000000..6ec9f0e
--- /dev/null
+++ b/1 PA Decline/archive/generation_1/table1.RTF
@@ -0,0 +1,737 @@
+{\rtf\ansi\ansicpg1252{\fonttbl{\f0\froman\fcharset0\fprq0 Courier New;}{\f1\froman\fcharset0\fprq0 Times;}}{\colortbl;\red211\green211\blue211;}
+
+\paperw12240\paperh15840\widowctrl\ftnbj\fet0\sectd\linex0
+\lndscpsxn
+\margl1440\margr1440\margt1440\margb1440
+\headery720\footery720\fs20
+
+\trowd\trrh0\trhdr
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf1 \cellx1872
+\intbl {\f0 {\f0\fs20 {\b Characteristic}}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf1 \cellx3744
+\intbl {\f0 {\f0\fs20 {\b N}}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf1 \cellx5616
+\intbl {\f0 {\f0\fs20 {\b Overall}, N = 391{\super \i 1}}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf1 \cellx7488
+\intbl {\f0 {\f0\fs20 {\b no}, N = 314{\super \i 1}}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf1 \cellx9360
+\intbl {\f0 {\f0\fs20 {\b yes}, N = 77{\super \i 1}}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Age}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 66 (57;74) [24,90]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 64 (56;72) [24,87]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 72 (66;79) [31,90]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Male}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 275 (70%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 227 (72%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 48 (62%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Living alone}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 385}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 107 (28%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 70 (23%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 37 (49%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Pre-stroke PASE score}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 167 (122;225) [85,574]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 174 (135;231) [85,574]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 123 (103;184) [85,407]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Daily or occasinally smoking}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 119 (30%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 90 (29%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 29 (38%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 More alcohol than recommendation}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 381}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 34 (8.9%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 25 (8.2%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 9 (12%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 AFIB}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 386}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 57 (15%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 45 (15%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 12 (16%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Hypertension}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 387}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 184 (48%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 139 (45%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 45 (59%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Diabetes}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 37 (9.5%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 29 (9.2%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 8 (10%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 PAD}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 12 (3.1%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 8 (2.5%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 4 (5.2%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Previous MI}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 33 (8.4%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 24 (7.6%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 9 (12%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Previous TIA}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 386}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 10 (2.6%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 8 (2.6%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 2 (2.7%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Pre-stroke mRS [-1]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 1}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 348 (89%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 284 (90%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 64 (83%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 2}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 32 (8.2%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 25 (8.0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 7 (9.1%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 3}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 10 (2.6%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 5 (1.6%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 5 (6.5%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 4}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 1 (0.3%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 1 (1.3%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Acute NIHSS score}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 388}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 3.0 (2.0;5.0) [0.0,32.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 3.0 (2.0;5.0) [0.0,32.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 3.0 (2.0;7.0) [0.0,22.0]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Any reperfusion therapy}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 151 (39%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 123 (39%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 28 (36%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Active trial treatment}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 190 (49%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 147 (47%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 43 (56%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Six month PASE score}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 159 (101;225) [0,486]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 180 (135;240) [86,486]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 57 (34;68) [0,83]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 One month mRS [-1]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 390}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 157 (40%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 136 (43%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 21 (27%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 One month MFI (General fatigue)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 378}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 10.0 (7.0;13.0) [4.0,20.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 10.0 (7.0;13.0) [4.0,20.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 12.0 (8.0;15.2) [4.0,20.0]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 One month MFI (Physical fatigue)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 376}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 10.0 (7.0;14.0) [4.0,20.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 9.0 (7.0;13.0) [4.0,20.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 13.0 (7.8;17.0) [4.0,20.0]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 One month MFI (Reduced activity)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 377}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 10.0 (7.0;13.0) [4.0,20.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 9.0 (6.0;12.0) [4.0,20.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 12.0 (9.0;16.0) [4.0,20.0]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 One month MFI (Reduced motivation)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 378}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 7.00 (5.00;9.00) [4.00,20.00]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 7.00 (5.00;9.00) [4.00,16.00]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 8.00 (5.00;12.00) [4.00,20.00]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 One month MFI (Mental fatigue)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 373}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 7.0 (4.0;11.0) [4.0,20.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 7.0 (4.0;10.0) [4.0,20.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 8.0 (5.0;12.0) [4.0,20.0]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 One month MDI}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 381}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 5.0 (3.0;9.0) [0.0,45.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 5.0 (2.0;8.0) [0.0,37.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 8.0 (4.0;15.0) [0.0,45.0]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 One month WHO5}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 385}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 76 (64;88) [0,100]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 76 (64;88) [0,100]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 70 (48;88) [0,100]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 PASE absolute decline}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 19 (-43;69) [-272,407]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 1 (-55;38) [-272,349]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 77 (45;127) [7,407]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 PASE relative decline}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 10 (-25;38) [-221,100]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 1 (-34;22) [-221,68]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 60 (41;75) [8,100]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 PASE score difference, relative F}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 PASE score difference, absolute F}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 PASE 0 quartiles}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 130 (33%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 83 (26%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 47 (61%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 PASE 6 quartiles}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 82 (21%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 82 (26%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 PASE first quartile drop F}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 PASE first quartile hop F}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 {\super \i 1}Median (25%;75%) [Minimum,Maximum]; n (%)}}\cell
+
+\row
+
+}
diff --git a/1 PA Decline/archive/generation_1/table1_overall.RTF b/1 PA Decline/archive/generation_1/table1_overall.RTF
new file mode 100644
index 0000000..6ec9f0e
--- /dev/null
+++ b/1 PA Decline/archive/generation_1/table1_overall.RTF
@@ -0,0 +1,737 @@
+{\rtf\ansi\ansicpg1252{\fonttbl{\f0\froman\fcharset0\fprq0 Courier New;}{\f1\froman\fcharset0\fprq0 Times;}}{\colortbl;\red211\green211\blue211;}
+
+\paperw12240\paperh15840\widowctrl\ftnbj\fet0\sectd\linex0
+\lndscpsxn
+\margl1440\margr1440\margt1440\margb1440
+\headery720\footery720\fs20
+
+\trowd\trrh0\trhdr
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf1 \cellx1872
+\intbl {\f0 {\f0\fs20 {\b Characteristic}}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf1 \cellx3744
+\intbl {\f0 {\f0\fs20 {\b N}}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf1 \cellx5616
+\intbl {\f0 {\f0\fs20 {\b Overall}, N = 391{\super \i 1}}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf1 \cellx7488
+\intbl {\f0 {\f0\fs20 {\b no}, N = 314{\super \i 1}}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf1 \cellx9360
+\intbl {\f0 {\f0\fs20 {\b yes}, N = 77{\super \i 1}}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Age}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 66 (57;74) [24,90]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 64 (56;72) [24,87]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 72 (66;79) [31,90]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Male}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 275 (70%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 227 (72%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 48 (62%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Living alone}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 385}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 107 (28%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 70 (23%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 37 (49%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Pre-stroke PASE score}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 167 (122;225) [85,574]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 174 (135;231) [85,574]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 123 (103;184) [85,407]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Daily or occasinally smoking}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 119 (30%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 90 (29%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 29 (38%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 More alcohol than recommendation}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 381}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 34 (8.9%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 25 (8.2%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 9 (12%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 AFIB}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 386}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 57 (15%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 45 (15%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 12 (16%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Hypertension}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 387}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 184 (48%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 139 (45%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 45 (59%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Diabetes}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 37 (9.5%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 29 (9.2%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 8 (10%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 PAD}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 12 (3.1%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 8 (2.5%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 4 (5.2%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Previous MI}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 33 (8.4%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 24 (7.6%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 9 (12%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Previous TIA}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 386}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 10 (2.6%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 8 (2.6%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 2 (2.7%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Pre-stroke mRS [-1]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 1}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 348 (89%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 284 (90%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 64 (83%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 2}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 32 (8.2%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 25 (8.0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 7 (9.1%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 3}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 10 (2.6%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 5 (1.6%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 5 (6.5%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 4}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 1 (0.3%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 1 (1.3%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Acute NIHSS score}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 388}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 3.0 (2.0;5.0) [0.0,32.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 3.0 (2.0;5.0) [0.0,32.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 3.0 (2.0;7.0) [0.0,22.0]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Any reperfusion therapy}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 151 (39%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 123 (39%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 28 (36%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Active trial treatment}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 190 (49%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 147 (47%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 43 (56%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 Six month PASE score}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 159 (101;225) [0,486]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 180 (135;240) [86,486]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 57 (34;68) [0,83]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 One month mRS [-1]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 390}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 157 (40%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 136 (43%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 21 (27%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 One month MFI (General fatigue)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 378}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 10.0 (7.0;13.0) [4.0,20.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 10.0 (7.0;13.0) [4.0,20.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 12.0 (8.0;15.2) [4.0,20.0]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 One month MFI (Physical fatigue)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 376}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 10.0 (7.0;14.0) [4.0,20.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 9.0 (7.0;13.0) [4.0,20.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 13.0 (7.8;17.0) [4.0,20.0]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 One month MFI (Reduced activity)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 377}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 10.0 (7.0;13.0) [4.0,20.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 9.0 (6.0;12.0) [4.0,20.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 12.0 (9.0;16.0) [4.0,20.0]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 One month MFI (Reduced motivation)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 378}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 7.00 (5.00;9.00) [4.00,20.00]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 7.00 (5.00;9.00) [4.00,16.00]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 8.00 (5.00;12.00) [4.00,20.00]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 One month MFI (Mental fatigue)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 373}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 7.0 (4.0;11.0) [4.0,20.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 7.0 (4.0;10.0) [4.0,20.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 8.0 (5.0;12.0) [4.0,20.0]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 One month MDI}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 381}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 5.0 (3.0;9.0) [0.0,45.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 5.0 (2.0;8.0) [0.0,37.0]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 8.0 (4.0;15.0) [0.0,45.0]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 One month WHO5}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 385}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 76 (64;88) [0,100]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 76 (64;88) [0,100]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 70 (48;88) [0,100]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 PASE absolute decline}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 19 (-43;69) [-272,407]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 1 (-55;38) [-272,349]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 77 (45;127) [7,407]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 PASE relative decline}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 10 (-25;38) [-221,100]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 1 (-34;22) [-221,68]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 60 (41;75) [8,100]}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 PASE score difference, relative F}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 PASE score difference, absolute F}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 PASE 0 quartiles}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 130 (33%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 83 (26%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 47 (61%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 PASE 6 quartiles}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 82 (21%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 82 (26%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 PASE first quartile drop F}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1872
+\intbl {\f0 {\f0\fs20 PASE first quartile hop F}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3744
+\intbl {\f0 {\f0\fs20 391}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5616
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7488
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 {\super \i 1}Median (25%;75%) [Minimum,Maximum]; n (%)}}\cell
+
+\row
+
+}
diff --git a/1 PA Decline/archive/generation_1/table2.RTF b/1 PA Decline/archive/generation_1/table2.RTF
new file mode 100644
index 0000000..d0a3072
--- /dev/null
+++ b/1 PA Decline/archive/generation_1/table2.RTF
@@ -0,0 +1,491 @@
+{\rtf\ansi\ansicpg1252{\fonttbl{\f0\froman\fcharset0\fprq0 Courier New;}{\f1\froman\fcharset0\fprq0 Times;}}{\colortbl;\red51\green51\blue51;\red211\green211\blue211;}
+
+\paperw12240\paperh15840\widowctrl\ftnbj\fet0\sectd\linex0
+\lndscpsxn
+\margl1440\margr1440\margt1440\margb1440
+\headery720\footery720\fs20
+
+\trowd\trrh0\trhdr
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0\cf1 {\f0\fs20 Model coefficients} {\f0\fs20\i\super } \line {\f0\fs20 Combined table of both full and regularised model coefficients} {\f0\fs20\i\super }}\cell
+
+\row
+
+\trowd\trrh0\trhdr
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2\clmgf \cellx2340
+\intbl {\f0 {\f0\fs20 Regularised model, (a=1, l=0.031)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2\clmrg \cellx3510
+\intbl {\f0 {\f0\fs20 Regularised model, (a=1, l=0.031)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2\clmrg \cellx4680
+\intbl {\f0 {\f0\fs20 Regularised model, (a=1, l=0.031)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2\clmrg \cellx5850
+\intbl {\f0 {\f0\fs20 Regularised model, (a=1, l=0.031)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2\clmgf \cellx7020
+\intbl {\f0 {\f0\fs20 Full model}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2\clmrg \cellx8190
+\intbl {\f0 {\f0\fs20 Full model}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2\clmrg \cellx9360
+\intbl {\f0 {\f0\fs20 Full model}}\cell
+
+\row
+
+\trowd\trrh0\trhdr
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx1170
+\intbl {\f0 {\f0\fs20 name}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx2340
+\intbl {\f0 {\f0\fs20 medianX}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx3510
+\intbl {\f0 {\f0\fs20 ORmed}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx4680
+\intbl {\f0 {\f0\fs20 meanX}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx5850
+\intbl {\f0 {\f0\fs20 ORmea}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx7020
+\intbl {\f0 {\f0\fs20 coefs}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx8190
+\intbl {\f0 {\f0\fs20 OR}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx9360
+\intbl {\f0 {\f0\fs20 CIs}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Intercept}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 -3.732}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 0.024}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 -3.773}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 0.023}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 -1.023}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 0.360}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.174,0.757)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Age}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.025}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.026}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.027}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.027}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.484}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.622}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (1.259,2.124)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Male}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 -0.023}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 0.977}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 -0.253}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 0.777}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.445,1.378)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Living alone}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.884}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 2.422}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.888}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 2.431}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 1.170}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 3.224}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (1.874,5.693)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Daily or occasinally smoking}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.156}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.169}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.161}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.175}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.546}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.727}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (1.022,3.04)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 More alcohol than recommendation}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.004}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.004}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.300}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.350}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.583,3.27)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 AFIB}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 -0.060}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 0.942}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.472,1.889)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Hypertension}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.083}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.086}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.100}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.105}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.361}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.434}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.871,2.382)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Diabetes}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.015}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.015}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.437,2.396)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 PAD}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.005}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.005}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.514}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.673}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.4,9.834)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Previous MI}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.047}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.049}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.062}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.064}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.516}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.676}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.727,4.083)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Pre-stroke mRS [-1]}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.020}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.020}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.271}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.311}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.608,2.904)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Acute NIHSS score}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.033}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.034}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.037}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.037}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.315}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.370}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (1.066,1.788)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Any reperfusion therapy}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 -0.020}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 0.980}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.571,1.706)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Active trial treatment}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.062}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.064}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.106}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.111}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.380}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.462}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.897,2.445)}}\cell
+
+\row
+
+}
diff --git a/1 PA Decline/archive/generation_1/table2_sec.RTF b/1 PA Decline/archive/generation_1/table2_sec.RTF
new file mode 100644
index 0000000..b2419c3
--- /dev/null
+++ b/1 PA Decline/archive/generation_1/table2_sec.RTF
@@ -0,0 +1,715 @@
+{\rtf\ansi\ansicpg1252{\fonttbl{\f0\froman\fcharset0\fprq0 Courier New;}{\f1\froman\fcharset0\fprq0 Times;}}{\colortbl;\red51\green51\blue51;\red211\green211\blue211;}
+
+\paperw12240\paperh15840\widowctrl\ftnbj\fet0\sectd\linex0
+\lndscpsxn
+\margl1440\margr1440\margt1440\margb1440
+\headery720\footery720\fs20
+
+\trowd\trrh0\trhdr
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0\cf1 {\f0\fs20 Model coefficients} {\f0\fs20\i\super } \line {\f0\fs20 Combined table of both full and regularised model coefficients} {\f0\fs20\i\super }}\cell
+
+\row
+
+\trowd\trrh0\trhdr
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2\clmgf \cellx2340
+\intbl {\f0 {\f0\fs20 Regularised model, (a=0.9, l=0.062)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2\clmrg \cellx3510
+\intbl {\f0 {\f0\fs20 Regularised model, (a=0.9, l=0.062)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2\clmrg \cellx4680
+\intbl {\f0 {\f0\fs20 Regularised model, (a=0.9, l=0.062)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2\clmrg \cellx5850
+\intbl {\f0 {\f0\fs20 Regularised model, (a=0.9, l=0.062)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2\clmgf \cellx7020
+\intbl {\f0 {\f0\fs20 Full model}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2\clmrg \cellx8190
+\intbl {\f0 {\f0\fs20 Full model}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2\clmrg \cellx9360
+\intbl {\f0 {\f0\fs20 Full model}}\cell
+
+\row
+
+\trowd\trrh0\trhdr
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx1170
+\intbl {\f0 {\f0\fs20 name}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx2340
+\intbl {\f0 {\f0\fs20 medianX}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx3510
+\intbl {\f0 {\f0\fs20 ORmed}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx4680
+\intbl {\f0 {\f0\fs20 meanX}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx5850
+\intbl {\f0 {\f0\fs20 ORmea}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx7020
+\intbl {\f0 {\f0\fs20 coefs}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx8190
+\intbl {\f0 {\f0\fs20 OR}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx9360
+\intbl {\f0 {\f0\fs20 CIs}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Intercept}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 -0.890}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 0.411}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 -0.949}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 0.387}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 -1.203}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 0.300}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.112,0.808)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Age}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.004}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.004}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.004}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.004}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.373}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.452}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (1.147,1.857)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Male}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.014}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.014}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.597,1.745)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Living alone}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.186}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.204}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.208}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.231}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.702}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 2.017}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (1.23,3.377)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Daily or occasinally smoking}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.003}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.003}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.403}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.496}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.927,2.479)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 More alcohol than recommendation}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 -0.154}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 0.857}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.389,1.898)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 AFIB}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 -0.165}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 0.848}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.451,1.612)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Hypertension}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.241}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.273}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.8,2.07)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Diabetes}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 -0.193}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 0.824}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.385,1.788)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 PAD}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 -0.169}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 0.845}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.245,3.202)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Previous MI}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.591}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.807}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.802,4.422)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Pre-stroke mRS [-1]}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 -0.028}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 0.973}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 -0.843}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 0.430}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.219,0.892)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Acute NIHSS score}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.001}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.001}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.323}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.382}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (1.084,1.787)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Any reperfusion therapy}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 -0.177}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 0.838}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.496,1.423)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 Active trial treatment}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.007}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.007}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.343}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.409}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.897,2.25)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 One month mRS [-1]}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.077}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.080}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.572}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.773}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.876,4.094)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 One month MFI (General fatigue)}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 -0.565}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 0.568}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.396,0.808)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 One month MFI (Physical fatigue)}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.214}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.238}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.894,1.729)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 One month MFI (Reduced activity)}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.002}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.002}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.072}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.074}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.765,1.516)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 One month MFI (Reduced motivation)}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.102}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.107}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.844,1.457)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 One month MFI (Mental fatigue)}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.093}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.097}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.853,1.42)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 One month MDI}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.027}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.028}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.025}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.025}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 0.490}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 1.632}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (1.193,2.299)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1170
+\intbl {\f0 {\f0\fs20 One month WHO5}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2340
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3510
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4680
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5850
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7020
+\intbl {\f0 {\f0\fs20 -0.108}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8190
+\intbl {\f0 {\f0\fs20 0.898}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 (0.653,1.239)}}\cell
+
+\row
+
+}
diff --git a/1 PA Decline/archive/generation_1/table3.RTF b/1 PA Decline/archive/generation_1/table3.RTF
new file mode 100644
index 0000000..3a9caa1
--- /dev/null
+++ b/1 PA Decline/archive/generation_1/table3.RTF
@@ -0,0 +1,184 @@
+{\rtf\ansi\ansicpg1252{\fonttbl{\f0\froman\fcharset0\fprq0 Courier New;}{\f1\froman\fcharset0\fprq0 Times;}}{\colortbl;\red51\green51\blue51;\red211\green211\blue211;}
+
+\paperw12240\paperh15840\widowctrl\ftnbj\fet0\sectd\linex0
+\lndscpsxn
+\margl1440\margr1440\margt1440\margb1440
+\headery720\footery720\fs20
+
+\trowd\trrh0\trhdr
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0\cf1 {\f0\fs20 Performance meassures} {\f0\fs20\i\super } \line {\f0\fs20 Combined table of both full and regularised performance meassures} {\f0\fs20\i\super }}\cell
+
+\row
+
+\trowd\trrh0\trhdr
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx3120
+\intbl {\f0 {\f0\fs20 Meassure}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx6240
+\intbl {\f0 {\f0\fs20 Regularised.model}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx9360
+\intbl {\f0 {\f0\fs20 Full.model}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Sensitivity}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.862}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.864}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Specificity}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.290}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.281}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Pos Pred Value}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.712}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.671}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Neg Pred Value}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.507}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.549}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Precision}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.712}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.671}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Recall}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.862}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.864}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 F1}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.780}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.756}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Prevalence}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.671}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.629}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Detection Rate}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.578}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.544}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Detection Prevalence}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.812}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.811}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Balanced Accuracy}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.576}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.572}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Mean AUC}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.607}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.609}}\cell
+
+\row
+
+}
diff --git a/1 PA Decline/archive/generation_1/table3_sec.RTF b/1 PA Decline/archive/generation_1/table3_sec.RTF
new file mode 100644
index 0000000..a301391
--- /dev/null
+++ b/1 PA Decline/archive/generation_1/table3_sec.RTF
@@ -0,0 +1,184 @@
+{\rtf\ansi\ansicpg1252{\fonttbl{\f0\froman\fcharset0\fprq0 Courier New;}{\f1\froman\fcharset0\fprq0 Times;}}{\colortbl;\red51\green51\blue51;\red211\green211\blue211;}
+
+\paperw12240\paperh15840\widowctrl\ftnbj\fet0\sectd\linex0
+\lndscpsxn
+\margl1440\margr1440\margt1440\margb1440
+\headery720\footery720\fs20
+
+\trowd\trrh0\trhdr
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0\cf1 {\f0\fs20 Performance meassures} {\f0\fs20\i\super } \line {\f0\fs20 Combined table of both full and regularised performance meassures} {\f0\fs20\i\super }}\cell
+
+\row
+
+\trowd\trrh0\trhdr
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx3120
+\intbl {\f0 {\f0\fs20 Meassure}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx6240
+\intbl {\f0 {\f0\fs20 Regularised.model}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx9360
+\intbl {\f0 {\f0\fs20 Full.model}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Sensitivity}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.890}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.896}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Specificity}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.184}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.201}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Pos Pred Value}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.646}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.672}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Neg Pred Value}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.500}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.516}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Precision}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.646}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.672}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Recall}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.890}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.896}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 F1}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.749}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.768}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Prevalence}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.626}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.646}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Detection Rate}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.557}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.579}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Detection Prevalence}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.862}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.862}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Balanced Accuracy}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.537}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.549}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Mean AUC}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.577}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.594}}\cell
+
+\row
+
+}
diff --git a/1 PA Decline/archive/prediction exercise.R b/1 PA Decline/archive/prediction exercise.R
new file mode 100644
index 0000000..fd04c04
--- /dev/null
+++ b/1 PA Decline/archive/prediction exercise.R
@@ -0,0 +1,142 @@
+# https://www.machinelearningplus.com/machine-learning/caret-package/
+
+# install.packages(c('caret', 'skimr', 'RANN', 'randomForest', 'fastAdaboost', 'gbm', 'xgboost', 'caretEnsemble', 'C50', 'earth'))
+
+# Load the caret package
+library(caret)
+
+# Import dataset
+orange <- read.csv('https://raw.githubusercontent.com/selva86/datasets/master/orange_juice_withmissing.csv')
+
+# Structure of the dataframe
+str(orange)
+
+# See top 6 rows and 10 columns
+head(orange[, 1:10])
+
+# Create the training and test datasets
+set.seed(100)
+
+# Step 1: Get row numbers for the training data
+trainRowNumbers <- createDataPartition(orange$Purchase, p=0.8, list=FALSE)
+
+# Step 2: Create the training dataset
+trainData <- orange[trainRowNumbers,]
+
+# Step 3: Create the test dataset
+testData <- orange[-trainRowNumbers,]
+
+# Store X and Y for later use.
+x = trainData[, 2:18]
+y = trainData$Purchase
+
+library(skimr)
+skimmed <- skim(trainData)
+skimmed
+
+# Create the knn imputation model on the training data
+preProcess_missingdata_model <- preProcess(trainData, method='knnImpute')
+preProcess_missingdata_model
+
+# Use the imputation model to predict the values of missing data points
+library(RANN) # required for knnInpute
+trainData <- predict(preProcess_missingdata_model, newdata = trainData)
+anyNA(trainData)
+
+# One-Hot Encoding
+# Creating dummy variables is converting a categorical variable to as many binary variables as here are categories.
+dummies_model <- dummyVars(Purchase ~ ., data=trainData)
+
+# Create the dummy variables using predict. The Y variable (Purchase) will not be present in trainData_mat.
+trainData_mat <- predict(dummies_model, newdata = trainData)
+
+# # Convert to dataframe
+trainData <- data.frame(trainData_mat)
+
+# # See the structure of the new dataset
+str(trainData)
+
+
+preProcess_range_model <- preProcess(trainData, method='range')
+trainData <- predict(preProcess_range_model, newdata = trainData)
+
+# Append the Y variable
+trainData$Purchase <- y
+
+apply(trainData[, 1:10], 2, FUN=function(x){c('min'=min(x), 'max'=max(x))})
+
+
+featurePlot(x=trainData[,1:18],
+ y=factor(trainData$Purchase),
+ plot="box",
+ strip=strip.custom(par.strip.text=list(cex=.7)),
+ scales = list(x = list(relation="free"),
+ y = list(relation="free")))
+
+featurePlot(x=trainData[,1:18],
+ y=factor(trainData$Purchase),
+ plot="density",
+ strip=strip.custom(par.strip.text=list(cex=.7)),
+ scales = list(x = list(relation="free"),
+ y = list(relation="free")))
+
+# 5
+
+set.seed(100)
+options(warn=-1)
+
+subsets <- c(1:5, 10, 15, 18)
+
+ctrl <- rfeControl(functions = rfFuncs,
+ method = "repeatedcv",
+ repeats = 5,
+ verbose = FALSE)
+
+lmProfile <- rfe(x=trainData[, 1:18], y=factor(trainData$Purchase),
+ sizes = subsets,
+ rfeControl = ctrl)
+
+lmProfile
+
+
+# See available algorithms in caret
+modelnames <- dput(names(getModelInfo()))
+# modelnames <- paste(names(getModelInfo()), collapse=', ')
+modelnames
+
+
+# Set the seed for reproducibility
+set.seed(100)
+
+# Train the model using randomForest and predict on the training data itself.
+model_mars = train(Purchase ~ ., data=trainData, method='earth')
+fitted <- predict(model_mars)
+
+model_mars
+
+
+plot(model_mars, main="Model Accuracies with MARS")
+
+varimp_mars <- varImp(model_mars)
+plot(varimp_mars, main="Variable Importance with MARS")
+
+
+## 6.4
+
+# Step 1: Impute missing values
+testData2 <- predict(preProcess_missingdata_model, testData)
+
+# Step 2: Create one-hot encodings (dummy variables)
+testData3 <- predict(dummies_model, testData2)
+
+# Step 3: Transform the features to range between 0 and 1
+testData4 <- predict(preProcess_range_model, testData3)
+
+# View
+head(testData4[, 1:10])
+
+predicted <- predict(model_mars, testData4)
+head(predicted)
+
+# Compute the confusion matrix
+confusionMatrix(reference = factor(testData$Purchase), data = predicted, mode='everything', positive='MM')
diff --git a/1 PA Decline/archive/predictive_model.Rmd b/1 PA Decline/archive/predictive_model.Rmd
new file mode 100644
index 0000000..b774729
--- /dev/null
+++ b/1 PA Decline/archive/predictive_model.Rmd
@@ -0,0 +1,101 @@
+---
+title: "predictive_model"
+output: pdf_document
+---
+
+```{r setup, include=FALSE}
+knitr::opts_chunk$set(echo = TRUE)
+```
+
+# Data
+```{r}
+library(caret)
+library(pROC)
+library(daDoctoR)
+library(dplyr)
+```
+
+Import
+```{r}
+trainData<-read.csv("/Users/au301842/PhysicalActivityandStrokeOutcome/data/trainData.csv",)
+testData<-read.csv("/Users/au301842/PhysicalActivityandStrokeOutcome/data/testData.csv",)
+```
+
+
+# Prediction
+Inspiration: https://stackoverflow.com/questions/30366143/how-to-compute-roc-and-auc-under-roc-after-training-using-caret-in-r and https://www.machinelearningplus.com/machine-learning/caret-package/
+
+## Early visualisation
+
+```{r}
+featurePlot(x = trainData %>% select(!matches("pase_drop")),
+ y = factor(trainData$pase_drop),
+ plot = "box",
+ strip=strip.custom(par.strip.text=list(cex=.7)),
+ scales = list(x = list(relation="free"),
+ y = list(relation="free")))
+
+featurePlot(x = trainData %>% select(!matches("pase_drop")),
+ y = factor(trainData$pase_drop),
+ plot = "density",
+ strip=strip.custom(par.strip.text=list(cex=.7)),
+ scales = list(x = list(relation="free"),
+ y = list(relation="free")))
+```
+
+
+```{r}
+subsets <- c(1:10, 15, 18,33)
+
+ctrl <- rfeControl(functions = rfFuncs,
+ method = "repeatedcv",
+ repeats = 5,
+ verbose = FALSE)
+
+lmProfile <- rfe(x = trainData %>% select(!matches("pase_drop")),
+ y = trainData$pase_drop,
+ sizes = subsets,
+ rfeControl = ctrl)
+
+lmProfile
+```
+
+
+```{r}
+set.seed(1000)
+
+forest.model <- train(pase_drop ~., trainData)
+
+result.predicted.prob <- predict(forest.model, testData, type="prob") # Prediction
+
+result.roc <- roc(factor(testData$pase_drop), result.predicted.prob$no) # Draw ROC curve.
+
+plot(result.roc, print.thres="best", print.thres.best.method="closest.topleft")
+
+result.coords <- coords(result.roc, "best", best.method="closest.topleft", ret=c("threshold", "accuracy"))
+print(result.coords)#to get threshold and accuracy
+```
+
+```{r}
+library(MLeval)
+
+myTrainingControl <- trainControl(method = "cv",
+ number = 10,
+ savePredictions = TRUE,
+ classProbs = TRUE,
+ verboseIter = TRUE)
+
+randomForestFit = train(x = trainData[,1:32],
+ y = as.factor(trainData$pase_drop),
+ method = "rf",
+ trControl = myTrainingControl,
+ preProcess = c("center","scale"),
+ ntree = 50)
+
+x <- evalm(randomForestFit)
+
+x$roc
+
+x$stdres
+```
+
diff --git a/1 PA Decline/archive/regularised model.R b/1 PA Decline/archive/regularised model.R
new file mode 100644
index 0000000..c1015ce
--- /dev/null
+++ b/1 PA Decline/archive/regularised model.R
@@ -0,0 +1,6 @@
+##
+## Regularisation
+##
+##
+
+
diff --git a/1 PA Decline/article ready.docx b/1 PA Decline/article ready.docx
new file mode 100644
index 0000000..ab90991
Binary files /dev/null and b/1 PA Decline/article ready.docx differ
diff --git a/1 PA Decline/article ready.html b/1 PA Decline/article ready.html
new file mode 100644
index 0000000..2b01493
--- /dev/null
+++ b/1 PA Decline/article ready.html
@@ -0,0 +1,1379 @@
+
+
+
+
+
+
+
+
+
+Article A: Final renders
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# ds <- readr::read_csv(here::here("/Volumes/Data/REDCap/DDV/talos_ddv.csv"))
+
+
+
# ds |> finalfit::missing_plot()
+
+On hanlding missings: https://finalfit.org/articles/missing.html
+
+
source (here:: here ("1 PA Decline/dst import.R" ))
+ ls_tbl <- docx2ds (
+ path = "/Users/au301842/Library/CloudStorage/OneDrive-Personal/Research/PhD/1 Change in PA/Manuscript/Manuscript_Change in PA_v2_0.docx"
+ )
+
+
Content types in the current document are as follows:
+
+
+
[1] "paragraph" "table cell"
+
+
+
Warning: The `value` argument of `names<-()` must have the same length as `x` as of
+tibble 3.0.0.
+
+
+
Warning: The `value` argument of `names<-()` can't be empty as of tibble 3.0.0.
+
+
ls <- ls_tbl |> purrr:: pluck (2 ) |>
+ (\(.x){
+ .x[- c (1 : 3 ,nrow (.x)),]
+ })()
+
+ n <- 0
+for (i in seq_len (nrow (ls))){
+ if (ls[[2 ]][i]!= "" ){
+ n[i]<- n[length (n)]+ 1
+ } else {
+ n[i] <- n[length (n)]
+ }
+ }
+
+split (ls,n) |> lapply (function (.x){
+
+ if (" TRUE" %in% .x[[1 ]]){
+ cbind (.x[1 ,1 : 2 ],.x[3 ,3 : 5 ],.x[1 ,6 ],.x[3 ,7 : 9 ])
+ } else {
+ .x
+ }
+ }) |> dplyr:: bind_rows () |>
+ gt:: gt ()
+
+
New names:
+• `` -> `...1`
+• `` -> `...2`
+• `` -> `...3`
+• `` -> `...4`
+• `` -> `...5`
+• `` -> `...6`
+• `` -> `...7`
+• `` -> `...8`
+• `` -> `...9`
+
+
+
New names:
+New names:
+New names:
+New names:
+New names:
+New names:
+New names:
+New names:
+New names:
+New names:
+New names:
+New names:
+New names:
+New names:
+New names:
+New names:
+New names:
+New names:
+New names:
+New names:
+New names:
+• `` -> `...1`
+• `` -> `...2`
+• `` -> `...3`
+• `` -> `...4`
+• `` -> `...5`
+• `` -> `...6`
+• `` -> `...7`
+• `` -> `...8`
+• `` -> `...9`
+
+
+
+
+
+
+
+
+
+
+
+Age
+523
+-2.4
+-3.0, -1.9
+<0.001
+423
+-0.90
+-1.7, -0.12
+0.025
+
+
+Female sex
+523
+-38
+-53, -22
+<0.001
+423
+-3.5
+-19, 12
+0.7
+
+
+Body mass index
+358
+1.8
+0.14, 3.5
+0.034
+-
+-
+-
+-
+
+
+Current smoker
+507
+-18
+-34, -1.9
+0.029
+423
+-5.8
+-21, 9.5
+0.5
+
+
+Living with somebody
+517
+46
+30, 61
+<0.001
+423
+10
+-5.6, 26
+0.2
+
+
+Alchohol consumption
+510
+5.6
+-21, 32
+0.7
+423
+4.8
+-19, 28
+0.7
+
+
+Hypertension
+519
+-32
+-47, -17
+<0.001
+423
+-3.0
+-17, 11
+0.7
+
+
+Diabetes
+517
+-19
+-43, 5.0
+0.12
+423
+-16
+-38, 6.4
+0.2
+
+
+Atrial fibrilation
+518
+1.3
+-19, 22
+>0.9
+423
+21
+2.0, 40
+0.030
+
+
+Periferal arterial disease
+511
+-38
+-76, 0.70
+0.054
+423
+-9.0
+-45, 27
+0.6
+
+
+Previous TIA
+517
+-2.8
+-51, 46
+>0.9
+423
+9.7
+-32, 51
+0.6
+
+
+Previous MI
+517
+2.8
+-25, 31
+0.8
+423
+3.8
+-23, 31
+0.8
+
+
+Treated with IVT
+509
+14
+-2.3, 29
+0.094
+423
+5.9
+-9.2, 21
+0.4
+
+
+Treated with EVT
+510
+-9.5
+-39, 20
+0.5
+423
+-3.6
+-35, 28
+0.8
+
+
+Study group allocation
+523
+
+
+
+423
+
+
+
+
+
+Aktiv (Citalopram)
+
+0.00
+Reference
+
+
+0.00
+Reference
+
+
+
+Placebo
+
+7.2
+-8.0, 22
+0.4
+
+2.7
+-11, 16
+0.7
+
+
+Pre-stroke PASE score
+523
+0.51
+0.44, 0.59
+<0.001
+423
+0.33
+0.23, 0.43
+<0.001
+
+
+Acute NIHSS
+513
+-3.7
+-5.4, -2.0
+<0.001
+423
+-2.3
+-4.2, -0.35
+0.021
+
+
+Employed
+523
+70
+56, 84
+<0.001
+423
+13
+-5.4, 31
+0.2
+
+
+Family income group
+523
+
+
+
+423
+
+
+
+
+
+low
+
+0.00
+Reference
+
+
+0.00
+Reference
+
+
+
+medium
+
+39
+22, 57
+<0.001
+
+15
+-2.7, 32
+0.10
+
+
+high
+
+79
+62, 97
+<0.001
+
+30
+9.8, 50
+0.004
+
+
+Educational level group
+474
+
+
+
+423
+
+
+
+
+
+low
+
+0.00
+Reference
+
+
+0.00
+Reference
+
+
+
+medium
+
+28
+11, 46
+0.001
+
+1.6
+-14, 17
+0.8
+
+
+high
+
+46
+24, 67
+<0.001
+
+6.9
+-14, 27
+0.5
+
+
+Pre-stroke WHO-5 score
+521
+0.87
+0.49, 1.3
+<0.001
+423
+0.62
+0.27, 0.97
+<0.001
+
+
+Pre-stroke mRS > 0
+523
+-58
+-77, -38
+<0.001
+423
+-16
+-34, 2.5
+0.091
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/1 PA Decline/article ready_files/libs/bootstrap/bootstrap-icons.css b/1 PA Decline/article ready_files/libs/bootstrap/bootstrap-icons.css
new file mode 100644
index 0000000..285e444
--- /dev/null
+++ b/1 PA Decline/article ready_files/libs/bootstrap/bootstrap-icons.css
@@ -0,0 +1,2078 @@
+/*!
+ * Bootstrap Icons v1.11.1 (https://icons.getbootstrap.com/)
+ * Copyright 2019-2023 The Bootstrap Authors
+ * Licensed under MIT (https://github.com/twbs/icons/blob/main/LICENSE)
+ */
+
+@font-face {
+ font-display: block;
+ font-family: "bootstrap-icons";
+ src:
+url("./bootstrap-icons.woff?2820a3852bdb9a5832199cc61cec4e65") format("woff");
+}
+
+.bi::before,
+[class^="bi-"]::before,
+[class*=" bi-"]::before {
+ display: inline-block;
+ font-family: bootstrap-icons !important;
+ font-style: normal;
+ font-weight: normal !important;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+ vertical-align: -.125em;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.bi-123::before { content: "\f67f"; }
+.bi-alarm-fill::before { content: "\f101"; }
+.bi-alarm::before { content: "\f102"; }
+.bi-align-bottom::before { content: "\f103"; }
+.bi-align-center::before { content: "\f104"; }
+.bi-align-end::before { content: "\f105"; }
+.bi-align-middle::before { content: "\f106"; }
+.bi-align-start::before { content: "\f107"; }
+.bi-align-top::before { content: "\f108"; }
+.bi-alt::before { content: "\f109"; }
+.bi-app-indicator::before { content: "\f10a"; }
+.bi-app::before { content: "\f10b"; }
+.bi-archive-fill::before { content: "\f10c"; }
+.bi-archive::before { content: "\f10d"; }
+.bi-arrow-90deg-down::before { content: "\f10e"; }
+.bi-arrow-90deg-left::before { content: "\f10f"; }
+.bi-arrow-90deg-right::before { content: "\f110"; }
+.bi-arrow-90deg-up::before { content: "\f111"; }
+.bi-arrow-bar-down::before { content: "\f112"; }
+.bi-arrow-bar-left::before { content: "\f113"; }
+.bi-arrow-bar-right::before { content: "\f114"; }
+.bi-arrow-bar-up::before { content: "\f115"; }
+.bi-arrow-clockwise::before { content: "\f116"; }
+.bi-arrow-counterclockwise::before { content: "\f117"; }
+.bi-arrow-down-circle-fill::before { content: "\f118"; }
+.bi-arrow-down-circle::before { content: "\f119"; }
+.bi-arrow-down-left-circle-fill::before { content: "\f11a"; }
+.bi-arrow-down-left-circle::before { content: "\f11b"; }
+.bi-arrow-down-left-square-fill::before { content: "\f11c"; }
+.bi-arrow-down-left-square::before { content: "\f11d"; }
+.bi-arrow-down-left::before { content: "\f11e"; }
+.bi-arrow-down-right-circle-fill::before { content: "\f11f"; }
+.bi-arrow-down-right-circle::before { content: "\f120"; }
+.bi-arrow-down-right-square-fill::before { content: "\f121"; }
+.bi-arrow-down-right-square::before { content: "\f122"; }
+.bi-arrow-down-right::before { content: "\f123"; }
+.bi-arrow-down-short::before { content: "\f124"; }
+.bi-arrow-down-square-fill::before { content: "\f125"; }
+.bi-arrow-down-square::before { content: "\f126"; }
+.bi-arrow-down-up::before { content: "\f127"; }
+.bi-arrow-down::before { content: "\f128"; }
+.bi-arrow-left-circle-fill::before { content: "\f129"; }
+.bi-arrow-left-circle::before { content: "\f12a"; }
+.bi-arrow-left-right::before { content: "\f12b"; }
+.bi-arrow-left-short::before { content: "\f12c"; }
+.bi-arrow-left-square-fill::before { content: "\f12d"; }
+.bi-arrow-left-square::before { content: "\f12e"; }
+.bi-arrow-left::before { content: "\f12f"; }
+.bi-arrow-repeat::before { content: "\f130"; }
+.bi-arrow-return-left::before { content: "\f131"; }
+.bi-arrow-return-right::before { content: "\f132"; }
+.bi-arrow-right-circle-fill::before { content: "\f133"; }
+.bi-arrow-right-circle::before { content: "\f134"; }
+.bi-arrow-right-short::before { content: "\f135"; }
+.bi-arrow-right-square-fill::before { content: "\f136"; }
+.bi-arrow-right-square::before { content: "\f137"; }
+.bi-arrow-right::before { content: "\f138"; }
+.bi-arrow-up-circle-fill::before { content: "\f139"; }
+.bi-arrow-up-circle::before { content: "\f13a"; }
+.bi-arrow-up-left-circle-fill::before { content: "\f13b"; }
+.bi-arrow-up-left-circle::before { content: "\f13c"; }
+.bi-arrow-up-left-square-fill::before { content: "\f13d"; }
+.bi-arrow-up-left-square::before { content: "\f13e"; }
+.bi-arrow-up-left::before { content: "\f13f"; }
+.bi-arrow-up-right-circle-fill::before { content: "\f140"; }
+.bi-arrow-up-right-circle::before { content: "\f141"; }
+.bi-arrow-up-right-square-fill::before { content: "\f142"; }
+.bi-arrow-up-right-square::before { content: "\f143"; }
+.bi-arrow-up-right::before { content: "\f144"; }
+.bi-arrow-up-short::before { content: "\f145"; }
+.bi-arrow-up-square-fill::before { content: "\f146"; }
+.bi-arrow-up-square::before { content: "\f147"; }
+.bi-arrow-up::before { content: "\f148"; }
+.bi-arrows-angle-contract::before { content: "\f149"; }
+.bi-arrows-angle-expand::before { content: "\f14a"; }
+.bi-arrows-collapse::before { content: "\f14b"; }
+.bi-arrows-expand::before { content: "\f14c"; }
+.bi-arrows-fullscreen::before { content: "\f14d"; }
+.bi-arrows-move::before { content: "\f14e"; }
+.bi-aspect-ratio-fill::before { content: "\f14f"; }
+.bi-aspect-ratio::before { content: "\f150"; }
+.bi-asterisk::before { content: "\f151"; }
+.bi-at::before { content: "\f152"; }
+.bi-award-fill::before { content: "\f153"; }
+.bi-award::before { content: "\f154"; }
+.bi-back::before { content: "\f155"; }
+.bi-backspace-fill::before { content: "\f156"; }
+.bi-backspace-reverse-fill::before { content: "\f157"; }
+.bi-backspace-reverse::before { content: "\f158"; }
+.bi-backspace::before { content: "\f159"; }
+.bi-badge-3d-fill::before { content: "\f15a"; }
+.bi-badge-3d::before { content: "\f15b"; }
+.bi-badge-4k-fill::before { content: "\f15c"; }
+.bi-badge-4k::before { content: "\f15d"; }
+.bi-badge-8k-fill::before { content: "\f15e"; }
+.bi-badge-8k::before { content: "\f15f"; }
+.bi-badge-ad-fill::before { content: "\f160"; }
+.bi-badge-ad::before { content: "\f161"; }
+.bi-badge-ar-fill::before { content: "\f162"; }
+.bi-badge-ar::before { content: "\f163"; }
+.bi-badge-cc-fill::before { content: "\f164"; }
+.bi-badge-cc::before { content: "\f165"; }
+.bi-badge-hd-fill::before { content: "\f166"; }
+.bi-badge-hd::before { content: "\f167"; }
+.bi-badge-tm-fill::before { content: "\f168"; }
+.bi-badge-tm::before { content: "\f169"; }
+.bi-badge-vo-fill::before { content: "\f16a"; }
+.bi-badge-vo::before { content: "\f16b"; }
+.bi-badge-vr-fill::before { content: "\f16c"; }
+.bi-badge-vr::before { content: "\f16d"; }
+.bi-badge-wc-fill::before { content: "\f16e"; }
+.bi-badge-wc::before { content: "\f16f"; }
+.bi-bag-check-fill::before { content: "\f170"; }
+.bi-bag-check::before { content: "\f171"; }
+.bi-bag-dash-fill::before { content: "\f172"; }
+.bi-bag-dash::before { content: "\f173"; }
+.bi-bag-fill::before { content: "\f174"; }
+.bi-bag-plus-fill::before { content: "\f175"; }
+.bi-bag-plus::before { content: "\f176"; }
+.bi-bag-x-fill::before { content: "\f177"; }
+.bi-bag-x::before { content: "\f178"; }
+.bi-bag::before { content: "\f179"; }
+.bi-bar-chart-fill::before { content: "\f17a"; }
+.bi-bar-chart-line-fill::before { content: "\f17b"; }
+.bi-bar-chart-line::before { content: "\f17c"; }
+.bi-bar-chart-steps::before { content: "\f17d"; }
+.bi-bar-chart::before { content: "\f17e"; }
+.bi-basket-fill::before { content: "\f17f"; }
+.bi-basket::before { content: "\f180"; }
+.bi-basket2-fill::before { content: "\f181"; }
+.bi-basket2::before { content: "\f182"; }
+.bi-basket3-fill::before { content: "\f183"; }
+.bi-basket3::before { content: "\f184"; }
+.bi-battery-charging::before { content: "\f185"; }
+.bi-battery-full::before { content: "\f186"; }
+.bi-battery-half::before { content: "\f187"; }
+.bi-battery::before { content: "\f188"; }
+.bi-bell-fill::before { content: "\f189"; }
+.bi-bell::before { content: "\f18a"; }
+.bi-bezier::before { content: "\f18b"; }
+.bi-bezier2::before { content: "\f18c"; }
+.bi-bicycle::before { content: "\f18d"; }
+.bi-binoculars-fill::before { content: "\f18e"; }
+.bi-binoculars::before { content: "\f18f"; }
+.bi-blockquote-left::before { content: "\f190"; }
+.bi-blockquote-right::before { content: "\f191"; }
+.bi-book-fill::before { content: "\f192"; }
+.bi-book-half::before { content: "\f193"; }
+.bi-book::before { content: "\f194"; }
+.bi-bookmark-check-fill::before { content: "\f195"; }
+.bi-bookmark-check::before { content: "\f196"; }
+.bi-bookmark-dash-fill::before { content: "\f197"; }
+.bi-bookmark-dash::before { content: "\f198"; }
+.bi-bookmark-fill::before { content: "\f199"; }
+.bi-bookmark-heart-fill::before { content: "\f19a"; }
+.bi-bookmark-heart::before { content: "\f19b"; }
+.bi-bookmark-plus-fill::before { content: "\f19c"; }
+.bi-bookmark-plus::before { content: "\f19d"; }
+.bi-bookmark-star-fill::before { content: "\f19e"; }
+.bi-bookmark-star::before { content: "\f19f"; }
+.bi-bookmark-x-fill::before { content: "\f1a0"; }
+.bi-bookmark-x::before { content: "\f1a1"; }
+.bi-bookmark::before { content: "\f1a2"; }
+.bi-bookmarks-fill::before { content: "\f1a3"; }
+.bi-bookmarks::before { content: "\f1a4"; }
+.bi-bookshelf::before { content: "\f1a5"; }
+.bi-bootstrap-fill::before { content: "\f1a6"; }
+.bi-bootstrap-reboot::before { content: "\f1a7"; }
+.bi-bootstrap::before { content: "\f1a8"; }
+.bi-border-all::before { content: "\f1a9"; }
+.bi-border-bottom::before { content: "\f1aa"; }
+.bi-border-center::before { content: "\f1ab"; }
+.bi-border-inner::before { content: "\f1ac"; }
+.bi-border-left::before { content: "\f1ad"; }
+.bi-border-middle::before { content: "\f1ae"; }
+.bi-border-outer::before { content: "\f1af"; }
+.bi-border-right::before { content: "\f1b0"; }
+.bi-border-style::before { content: "\f1b1"; }
+.bi-border-top::before { content: "\f1b2"; }
+.bi-border-width::before { content: "\f1b3"; }
+.bi-border::before { content: "\f1b4"; }
+.bi-bounding-box-circles::before { content: "\f1b5"; }
+.bi-bounding-box::before { content: "\f1b6"; }
+.bi-box-arrow-down-left::before { content: "\f1b7"; }
+.bi-box-arrow-down-right::before { content: "\f1b8"; }
+.bi-box-arrow-down::before { content: "\f1b9"; }
+.bi-box-arrow-in-down-left::before { content: "\f1ba"; }
+.bi-box-arrow-in-down-right::before { content: "\f1bb"; }
+.bi-box-arrow-in-down::before { content: "\f1bc"; }
+.bi-box-arrow-in-left::before { content: "\f1bd"; }
+.bi-box-arrow-in-right::before { content: "\f1be"; }
+.bi-box-arrow-in-up-left::before { content: "\f1bf"; }
+.bi-box-arrow-in-up-right::before { content: "\f1c0"; }
+.bi-box-arrow-in-up::before { content: "\f1c1"; }
+.bi-box-arrow-left::before { content: "\f1c2"; }
+.bi-box-arrow-right::before { content: "\f1c3"; }
+.bi-box-arrow-up-left::before { content: "\f1c4"; }
+.bi-box-arrow-up-right::before { content: "\f1c5"; }
+.bi-box-arrow-up::before { content: "\f1c6"; }
+.bi-box-seam::before { content: "\f1c7"; }
+.bi-box::before { content: "\f1c8"; }
+.bi-braces::before { content: "\f1c9"; }
+.bi-bricks::before { content: "\f1ca"; }
+.bi-briefcase-fill::before { content: "\f1cb"; }
+.bi-briefcase::before { content: "\f1cc"; }
+.bi-brightness-alt-high-fill::before { content: "\f1cd"; }
+.bi-brightness-alt-high::before { content: "\f1ce"; }
+.bi-brightness-alt-low-fill::before { content: "\f1cf"; }
+.bi-brightness-alt-low::before { content: "\f1d0"; }
+.bi-brightness-high-fill::before { content: "\f1d1"; }
+.bi-brightness-high::before { content: "\f1d2"; }
+.bi-brightness-low-fill::before { content: "\f1d3"; }
+.bi-brightness-low::before { content: "\f1d4"; }
+.bi-broadcast-pin::before { content: "\f1d5"; }
+.bi-broadcast::before { content: "\f1d6"; }
+.bi-brush-fill::before { content: "\f1d7"; }
+.bi-brush::before { content: "\f1d8"; }
+.bi-bucket-fill::before { content: "\f1d9"; }
+.bi-bucket::before { content: "\f1da"; }
+.bi-bug-fill::before { content: "\f1db"; }
+.bi-bug::before { content: "\f1dc"; }
+.bi-building::before { content: "\f1dd"; }
+.bi-bullseye::before { content: "\f1de"; }
+.bi-calculator-fill::before { content: "\f1df"; }
+.bi-calculator::before { content: "\f1e0"; }
+.bi-calendar-check-fill::before { content: "\f1e1"; }
+.bi-calendar-check::before { content: "\f1e2"; }
+.bi-calendar-date-fill::before { content: "\f1e3"; }
+.bi-calendar-date::before { content: "\f1e4"; }
+.bi-calendar-day-fill::before { content: "\f1e5"; }
+.bi-calendar-day::before { content: "\f1e6"; }
+.bi-calendar-event-fill::before { content: "\f1e7"; }
+.bi-calendar-event::before { content: "\f1e8"; }
+.bi-calendar-fill::before { content: "\f1e9"; }
+.bi-calendar-minus-fill::before { content: "\f1ea"; }
+.bi-calendar-minus::before { content: "\f1eb"; }
+.bi-calendar-month-fill::before { content: "\f1ec"; }
+.bi-calendar-month::before { content: "\f1ed"; }
+.bi-calendar-plus-fill::before { content: "\f1ee"; }
+.bi-calendar-plus::before { content: "\f1ef"; }
+.bi-calendar-range-fill::before { content: "\f1f0"; }
+.bi-calendar-range::before { content: "\f1f1"; }
+.bi-calendar-week-fill::before { content: "\f1f2"; }
+.bi-calendar-week::before { content: "\f1f3"; }
+.bi-calendar-x-fill::before { content: "\f1f4"; }
+.bi-calendar-x::before { content: "\f1f5"; }
+.bi-calendar::before { content: "\f1f6"; }
+.bi-calendar2-check-fill::before { content: "\f1f7"; }
+.bi-calendar2-check::before { content: "\f1f8"; }
+.bi-calendar2-date-fill::before { content: "\f1f9"; }
+.bi-calendar2-date::before { content: "\f1fa"; }
+.bi-calendar2-day-fill::before { content: "\f1fb"; }
+.bi-calendar2-day::before { content: "\f1fc"; }
+.bi-calendar2-event-fill::before { content: "\f1fd"; }
+.bi-calendar2-event::before { content: "\f1fe"; }
+.bi-calendar2-fill::before { content: "\f1ff"; }
+.bi-calendar2-minus-fill::before { content: "\f200"; }
+.bi-calendar2-minus::before { content: "\f201"; }
+.bi-calendar2-month-fill::before { content: "\f202"; }
+.bi-calendar2-month::before { content: "\f203"; }
+.bi-calendar2-plus-fill::before { content: "\f204"; }
+.bi-calendar2-plus::before { content: "\f205"; }
+.bi-calendar2-range-fill::before { content: "\f206"; }
+.bi-calendar2-range::before { content: "\f207"; }
+.bi-calendar2-week-fill::before { content: "\f208"; }
+.bi-calendar2-week::before { content: "\f209"; }
+.bi-calendar2-x-fill::before { content: "\f20a"; }
+.bi-calendar2-x::before { content: "\f20b"; }
+.bi-calendar2::before { content: "\f20c"; }
+.bi-calendar3-event-fill::before { content: "\f20d"; }
+.bi-calendar3-event::before { content: "\f20e"; }
+.bi-calendar3-fill::before { content: "\f20f"; }
+.bi-calendar3-range-fill::before { content: "\f210"; }
+.bi-calendar3-range::before { content: "\f211"; }
+.bi-calendar3-week-fill::before { content: "\f212"; }
+.bi-calendar3-week::before { content: "\f213"; }
+.bi-calendar3::before { content: "\f214"; }
+.bi-calendar4-event::before { content: "\f215"; }
+.bi-calendar4-range::before { content: "\f216"; }
+.bi-calendar4-week::before { content: "\f217"; }
+.bi-calendar4::before { content: "\f218"; }
+.bi-camera-fill::before { content: "\f219"; }
+.bi-camera-reels-fill::before { content: "\f21a"; }
+.bi-camera-reels::before { content: "\f21b"; }
+.bi-camera-video-fill::before { content: "\f21c"; }
+.bi-camera-video-off-fill::before { content: "\f21d"; }
+.bi-camera-video-off::before { content: "\f21e"; }
+.bi-camera-video::before { content: "\f21f"; }
+.bi-camera::before { content: "\f220"; }
+.bi-camera2::before { content: "\f221"; }
+.bi-capslock-fill::before { content: "\f222"; }
+.bi-capslock::before { content: "\f223"; }
+.bi-card-checklist::before { content: "\f224"; }
+.bi-card-heading::before { content: "\f225"; }
+.bi-card-image::before { content: "\f226"; }
+.bi-card-list::before { content: "\f227"; }
+.bi-card-text::before { content: "\f228"; }
+.bi-caret-down-fill::before { content: "\f229"; }
+.bi-caret-down-square-fill::before { content: "\f22a"; }
+.bi-caret-down-square::before { content: "\f22b"; }
+.bi-caret-down::before { content: "\f22c"; }
+.bi-caret-left-fill::before { content: "\f22d"; }
+.bi-caret-left-square-fill::before { content: "\f22e"; }
+.bi-caret-left-square::before { content: "\f22f"; }
+.bi-caret-left::before { content: "\f230"; }
+.bi-caret-right-fill::before { content: "\f231"; }
+.bi-caret-right-square-fill::before { content: "\f232"; }
+.bi-caret-right-square::before { content: "\f233"; }
+.bi-caret-right::before { content: "\f234"; }
+.bi-caret-up-fill::before { content: "\f235"; }
+.bi-caret-up-square-fill::before { content: "\f236"; }
+.bi-caret-up-square::before { content: "\f237"; }
+.bi-caret-up::before { content: "\f238"; }
+.bi-cart-check-fill::before { content: "\f239"; }
+.bi-cart-check::before { content: "\f23a"; }
+.bi-cart-dash-fill::before { content: "\f23b"; }
+.bi-cart-dash::before { content: "\f23c"; }
+.bi-cart-fill::before { content: "\f23d"; }
+.bi-cart-plus-fill::before { content: "\f23e"; }
+.bi-cart-plus::before { content: "\f23f"; }
+.bi-cart-x-fill::before { content: "\f240"; }
+.bi-cart-x::before { content: "\f241"; }
+.bi-cart::before { content: "\f242"; }
+.bi-cart2::before { content: "\f243"; }
+.bi-cart3::before { content: "\f244"; }
+.bi-cart4::before { content: "\f245"; }
+.bi-cash-stack::before { content: "\f246"; }
+.bi-cash::before { content: "\f247"; }
+.bi-cast::before { content: "\f248"; }
+.bi-chat-dots-fill::before { content: "\f249"; }
+.bi-chat-dots::before { content: "\f24a"; }
+.bi-chat-fill::before { content: "\f24b"; }
+.bi-chat-left-dots-fill::before { content: "\f24c"; }
+.bi-chat-left-dots::before { content: "\f24d"; }
+.bi-chat-left-fill::before { content: "\f24e"; }
+.bi-chat-left-quote-fill::before { content: "\f24f"; }
+.bi-chat-left-quote::before { content: "\f250"; }
+.bi-chat-left-text-fill::before { content: "\f251"; }
+.bi-chat-left-text::before { content: "\f252"; }
+.bi-chat-left::before { content: "\f253"; }
+.bi-chat-quote-fill::before { content: "\f254"; }
+.bi-chat-quote::before { content: "\f255"; }
+.bi-chat-right-dots-fill::before { content: "\f256"; }
+.bi-chat-right-dots::before { content: "\f257"; }
+.bi-chat-right-fill::before { content: "\f258"; }
+.bi-chat-right-quote-fill::before { content: "\f259"; }
+.bi-chat-right-quote::before { content: "\f25a"; }
+.bi-chat-right-text-fill::before { content: "\f25b"; }
+.bi-chat-right-text::before { content: "\f25c"; }
+.bi-chat-right::before { content: "\f25d"; }
+.bi-chat-square-dots-fill::before { content: "\f25e"; }
+.bi-chat-square-dots::before { content: "\f25f"; }
+.bi-chat-square-fill::before { content: "\f260"; }
+.bi-chat-square-quote-fill::before { content: "\f261"; }
+.bi-chat-square-quote::before { content: "\f262"; }
+.bi-chat-square-text-fill::before { content: "\f263"; }
+.bi-chat-square-text::before { content: "\f264"; }
+.bi-chat-square::before { content: "\f265"; }
+.bi-chat-text-fill::before { content: "\f266"; }
+.bi-chat-text::before { content: "\f267"; }
+.bi-chat::before { content: "\f268"; }
+.bi-check-all::before { content: "\f269"; }
+.bi-check-circle-fill::before { content: "\f26a"; }
+.bi-check-circle::before { content: "\f26b"; }
+.bi-check-square-fill::before { content: "\f26c"; }
+.bi-check-square::before { content: "\f26d"; }
+.bi-check::before { content: "\f26e"; }
+.bi-check2-all::before { content: "\f26f"; }
+.bi-check2-circle::before { content: "\f270"; }
+.bi-check2-square::before { content: "\f271"; }
+.bi-check2::before { content: "\f272"; }
+.bi-chevron-bar-contract::before { content: "\f273"; }
+.bi-chevron-bar-down::before { content: "\f274"; }
+.bi-chevron-bar-expand::before { content: "\f275"; }
+.bi-chevron-bar-left::before { content: "\f276"; }
+.bi-chevron-bar-right::before { content: "\f277"; }
+.bi-chevron-bar-up::before { content: "\f278"; }
+.bi-chevron-compact-down::before { content: "\f279"; }
+.bi-chevron-compact-left::before { content: "\f27a"; }
+.bi-chevron-compact-right::before { content: "\f27b"; }
+.bi-chevron-compact-up::before { content: "\f27c"; }
+.bi-chevron-contract::before { content: "\f27d"; }
+.bi-chevron-double-down::before { content: "\f27e"; }
+.bi-chevron-double-left::before { content: "\f27f"; }
+.bi-chevron-double-right::before { content: "\f280"; }
+.bi-chevron-double-up::before { content: "\f281"; }
+.bi-chevron-down::before { content: "\f282"; }
+.bi-chevron-expand::before { content: "\f283"; }
+.bi-chevron-left::before { content: "\f284"; }
+.bi-chevron-right::before { content: "\f285"; }
+.bi-chevron-up::before { content: "\f286"; }
+.bi-circle-fill::before { content: "\f287"; }
+.bi-circle-half::before { content: "\f288"; }
+.bi-circle-square::before { content: "\f289"; }
+.bi-circle::before { content: "\f28a"; }
+.bi-clipboard-check::before { content: "\f28b"; }
+.bi-clipboard-data::before { content: "\f28c"; }
+.bi-clipboard-minus::before { content: "\f28d"; }
+.bi-clipboard-plus::before { content: "\f28e"; }
+.bi-clipboard-x::before { content: "\f28f"; }
+.bi-clipboard::before { content: "\f290"; }
+.bi-clock-fill::before { content: "\f291"; }
+.bi-clock-history::before { content: "\f292"; }
+.bi-clock::before { content: "\f293"; }
+.bi-cloud-arrow-down-fill::before { content: "\f294"; }
+.bi-cloud-arrow-down::before { content: "\f295"; }
+.bi-cloud-arrow-up-fill::before { content: "\f296"; }
+.bi-cloud-arrow-up::before { content: "\f297"; }
+.bi-cloud-check-fill::before { content: "\f298"; }
+.bi-cloud-check::before { content: "\f299"; }
+.bi-cloud-download-fill::before { content: "\f29a"; }
+.bi-cloud-download::before { content: "\f29b"; }
+.bi-cloud-drizzle-fill::before { content: "\f29c"; }
+.bi-cloud-drizzle::before { content: "\f29d"; }
+.bi-cloud-fill::before { content: "\f29e"; }
+.bi-cloud-fog-fill::before { content: "\f29f"; }
+.bi-cloud-fog::before { content: "\f2a0"; }
+.bi-cloud-fog2-fill::before { content: "\f2a1"; }
+.bi-cloud-fog2::before { content: "\f2a2"; }
+.bi-cloud-hail-fill::before { content: "\f2a3"; }
+.bi-cloud-hail::before { content: "\f2a4"; }
+.bi-cloud-haze-fill::before { content: "\f2a6"; }
+.bi-cloud-haze::before { content: "\f2a7"; }
+.bi-cloud-haze2-fill::before { content: "\f2a8"; }
+.bi-cloud-lightning-fill::before { content: "\f2a9"; }
+.bi-cloud-lightning-rain-fill::before { content: "\f2aa"; }
+.bi-cloud-lightning-rain::before { content: "\f2ab"; }
+.bi-cloud-lightning::before { content: "\f2ac"; }
+.bi-cloud-minus-fill::before { content: "\f2ad"; }
+.bi-cloud-minus::before { content: "\f2ae"; }
+.bi-cloud-moon-fill::before { content: "\f2af"; }
+.bi-cloud-moon::before { content: "\f2b0"; }
+.bi-cloud-plus-fill::before { content: "\f2b1"; }
+.bi-cloud-plus::before { content: "\f2b2"; }
+.bi-cloud-rain-fill::before { content: "\f2b3"; }
+.bi-cloud-rain-heavy-fill::before { content: "\f2b4"; }
+.bi-cloud-rain-heavy::before { content: "\f2b5"; }
+.bi-cloud-rain::before { content: "\f2b6"; }
+.bi-cloud-slash-fill::before { content: "\f2b7"; }
+.bi-cloud-slash::before { content: "\f2b8"; }
+.bi-cloud-sleet-fill::before { content: "\f2b9"; }
+.bi-cloud-sleet::before { content: "\f2ba"; }
+.bi-cloud-snow-fill::before { content: "\f2bb"; }
+.bi-cloud-snow::before { content: "\f2bc"; }
+.bi-cloud-sun-fill::before { content: "\f2bd"; }
+.bi-cloud-sun::before { content: "\f2be"; }
+.bi-cloud-upload-fill::before { content: "\f2bf"; }
+.bi-cloud-upload::before { content: "\f2c0"; }
+.bi-cloud::before { content: "\f2c1"; }
+.bi-clouds-fill::before { content: "\f2c2"; }
+.bi-clouds::before { content: "\f2c3"; }
+.bi-cloudy-fill::before { content: "\f2c4"; }
+.bi-cloudy::before { content: "\f2c5"; }
+.bi-code-slash::before { content: "\f2c6"; }
+.bi-code-square::before { content: "\f2c7"; }
+.bi-code::before { content: "\f2c8"; }
+.bi-collection-fill::before { content: "\f2c9"; }
+.bi-collection-play-fill::before { content: "\f2ca"; }
+.bi-collection-play::before { content: "\f2cb"; }
+.bi-collection::before { content: "\f2cc"; }
+.bi-columns-gap::before { content: "\f2cd"; }
+.bi-columns::before { content: "\f2ce"; }
+.bi-command::before { content: "\f2cf"; }
+.bi-compass-fill::before { content: "\f2d0"; }
+.bi-compass::before { content: "\f2d1"; }
+.bi-cone-striped::before { content: "\f2d2"; }
+.bi-cone::before { content: "\f2d3"; }
+.bi-controller::before { content: "\f2d4"; }
+.bi-cpu-fill::before { content: "\f2d5"; }
+.bi-cpu::before { content: "\f2d6"; }
+.bi-credit-card-2-back-fill::before { content: "\f2d7"; }
+.bi-credit-card-2-back::before { content: "\f2d8"; }
+.bi-credit-card-2-front-fill::before { content: "\f2d9"; }
+.bi-credit-card-2-front::before { content: "\f2da"; }
+.bi-credit-card-fill::before { content: "\f2db"; }
+.bi-credit-card::before { content: "\f2dc"; }
+.bi-crop::before { content: "\f2dd"; }
+.bi-cup-fill::before { content: "\f2de"; }
+.bi-cup-straw::before { content: "\f2df"; }
+.bi-cup::before { content: "\f2e0"; }
+.bi-cursor-fill::before { content: "\f2e1"; }
+.bi-cursor-text::before { content: "\f2e2"; }
+.bi-cursor::before { content: "\f2e3"; }
+.bi-dash-circle-dotted::before { content: "\f2e4"; }
+.bi-dash-circle-fill::before { content: "\f2e5"; }
+.bi-dash-circle::before { content: "\f2e6"; }
+.bi-dash-square-dotted::before { content: "\f2e7"; }
+.bi-dash-square-fill::before { content: "\f2e8"; }
+.bi-dash-square::before { content: "\f2e9"; }
+.bi-dash::before { content: "\f2ea"; }
+.bi-diagram-2-fill::before { content: "\f2eb"; }
+.bi-diagram-2::before { content: "\f2ec"; }
+.bi-diagram-3-fill::before { content: "\f2ed"; }
+.bi-diagram-3::before { content: "\f2ee"; }
+.bi-diamond-fill::before { content: "\f2ef"; }
+.bi-diamond-half::before { content: "\f2f0"; }
+.bi-diamond::before { content: "\f2f1"; }
+.bi-dice-1-fill::before { content: "\f2f2"; }
+.bi-dice-1::before { content: "\f2f3"; }
+.bi-dice-2-fill::before { content: "\f2f4"; }
+.bi-dice-2::before { content: "\f2f5"; }
+.bi-dice-3-fill::before { content: "\f2f6"; }
+.bi-dice-3::before { content: "\f2f7"; }
+.bi-dice-4-fill::before { content: "\f2f8"; }
+.bi-dice-4::before { content: "\f2f9"; }
+.bi-dice-5-fill::before { content: "\f2fa"; }
+.bi-dice-5::before { content: "\f2fb"; }
+.bi-dice-6-fill::before { content: "\f2fc"; }
+.bi-dice-6::before { content: "\f2fd"; }
+.bi-disc-fill::before { content: "\f2fe"; }
+.bi-disc::before { content: "\f2ff"; }
+.bi-discord::before { content: "\f300"; }
+.bi-display-fill::before { content: "\f301"; }
+.bi-display::before { content: "\f302"; }
+.bi-distribute-horizontal::before { content: "\f303"; }
+.bi-distribute-vertical::before { content: "\f304"; }
+.bi-door-closed-fill::before { content: "\f305"; }
+.bi-door-closed::before { content: "\f306"; }
+.bi-door-open-fill::before { content: "\f307"; }
+.bi-door-open::before { content: "\f308"; }
+.bi-dot::before { content: "\f309"; }
+.bi-download::before { content: "\f30a"; }
+.bi-droplet-fill::before { content: "\f30b"; }
+.bi-droplet-half::before { content: "\f30c"; }
+.bi-droplet::before { content: "\f30d"; }
+.bi-earbuds::before { content: "\f30e"; }
+.bi-easel-fill::before { content: "\f30f"; }
+.bi-easel::before { content: "\f310"; }
+.bi-egg-fill::before { content: "\f311"; }
+.bi-egg-fried::before { content: "\f312"; }
+.bi-egg::before { content: "\f313"; }
+.bi-eject-fill::before { content: "\f314"; }
+.bi-eject::before { content: "\f315"; }
+.bi-emoji-angry-fill::before { content: "\f316"; }
+.bi-emoji-angry::before { content: "\f317"; }
+.bi-emoji-dizzy-fill::before { content: "\f318"; }
+.bi-emoji-dizzy::before { content: "\f319"; }
+.bi-emoji-expressionless-fill::before { content: "\f31a"; }
+.bi-emoji-expressionless::before { content: "\f31b"; }
+.bi-emoji-frown-fill::before { content: "\f31c"; }
+.bi-emoji-frown::before { content: "\f31d"; }
+.bi-emoji-heart-eyes-fill::before { content: "\f31e"; }
+.bi-emoji-heart-eyes::before { content: "\f31f"; }
+.bi-emoji-laughing-fill::before { content: "\f320"; }
+.bi-emoji-laughing::before { content: "\f321"; }
+.bi-emoji-neutral-fill::before { content: "\f322"; }
+.bi-emoji-neutral::before { content: "\f323"; }
+.bi-emoji-smile-fill::before { content: "\f324"; }
+.bi-emoji-smile-upside-down-fill::before { content: "\f325"; }
+.bi-emoji-smile-upside-down::before { content: "\f326"; }
+.bi-emoji-smile::before { content: "\f327"; }
+.bi-emoji-sunglasses-fill::before { content: "\f328"; }
+.bi-emoji-sunglasses::before { content: "\f329"; }
+.bi-emoji-wink-fill::before { content: "\f32a"; }
+.bi-emoji-wink::before { content: "\f32b"; }
+.bi-envelope-fill::before { content: "\f32c"; }
+.bi-envelope-open-fill::before { content: "\f32d"; }
+.bi-envelope-open::before { content: "\f32e"; }
+.bi-envelope::before { content: "\f32f"; }
+.bi-eraser-fill::before { content: "\f330"; }
+.bi-eraser::before { content: "\f331"; }
+.bi-exclamation-circle-fill::before { content: "\f332"; }
+.bi-exclamation-circle::before { content: "\f333"; }
+.bi-exclamation-diamond-fill::before { content: "\f334"; }
+.bi-exclamation-diamond::before { content: "\f335"; }
+.bi-exclamation-octagon-fill::before { content: "\f336"; }
+.bi-exclamation-octagon::before { content: "\f337"; }
+.bi-exclamation-square-fill::before { content: "\f338"; }
+.bi-exclamation-square::before { content: "\f339"; }
+.bi-exclamation-triangle-fill::before { content: "\f33a"; }
+.bi-exclamation-triangle::before { content: "\f33b"; }
+.bi-exclamation::before { content: "\f33c"; }
+.bi-exclude::before { content: "\f33d"; }
+.bi-eye-fill::before { content: "\f33e"; }
+.bi-eye-slash-fill::before { content: "\f33f"; }
+.bi-eye-slash::before { content: "\f340"; }
+.bi-eye::before { content: "\f341"; }
+.bi-eyedropper::before { content: "\f342"; }
+.bi-eyeglasses::before { content: "\f343"; }
+.bi-facebook::before { content: "\f344"; }
+.bi-file-arrow-down-fill::before { content: "\f345"; }
+.bi-file-arrow-down::before { content: "\f346"; }
+.bi-file-arrow-up-fill::before { content: "\f347"; }
+.bi-file-arrow-up::before { content: "\f348"; }
+.bi-file-bar-graph-fill::before { content: "\f349"; }
+.bi-file-bar-graph::before { content: "\f34a"; }
+.bi-file-binary-fill::before { content: "\f34b"; }
+.bi-file-binary::before { content: "\f34c"; }
+.bi-file-break-fill::before { content: "\f34d"; }
+.bi-file-break::before { content: "\f34e"; }
+.bi-file-check-fill::before { content: "\f34f"; }
+.bi-file-check::before { content: "\f350"; }
+.bi-file-code-fill::before { content: "\f351"; }
+.bi-file-code::before { content: "\f352"; }
+.bi-file-diff-fill::before { content: "\f353"; }
+.bi-file-diff::before { content: "\f354"; }
+.bi-file-earmark-arrow-down-fill::before { content: "\f355"; }
+.bi-file-earmark-arrow-down::before { content: "\f356"; }
+.bi-file-earmark-arrow-up-fill::before { content: "\f357"; }
+.bi-file-earmark-arrow-up::before { content: "\f358"; }
+.bi-file-earmark-bar-graph-fill::before { content: "\f359"; }
+.bi-file-earmark-bar-graph::before { content: "\f35a"; }
+.bi-file-earmark-binary-fill::before { content: "\f35b"; }
+.bi-file-earmark-binary::before { content: "\f35c"; }
+.bi-file-earmark-break-fill::before { content: "\f35d"; }
+.bi-file-earmark-break::before { content: "\f35e"; }
+.bi-file-earmark-check-fill::before { content: "\f35f"; }
+.bi-file-earmark-check::before { content: "\f360"; }
+.bi-file-earmark-code-fill::before { content: "\f361"; }
+.bi-file-earmark-code::before { content: "\f362"; }
+.bi-file-earmark-diff-fill::before { content: "\f363"; }
+.bi-file-earmark-diff::before { content: "\f364"; }
+.bi-file-earmark-easel-fill::before { content: "\f365"; }
+.bi-file-earmark-easel::before { content: "\f366"; }
+.bi-file-earmark-excel-fill::before { content: "\f367"; }
+.bi-file-earmark-excel::before { content: "\f368"; }
+.bi-file-earmark-fill::before { content: "\f369"; }
+.bi-file-earmark-font-fill::before { content: "\f36a"; }
+.bi-file-earmark-font::before { content: "\f36b"; }
+.bi-file-earmark-image-fill::before { content: "\f36c"; }
+.bi-file-earmark-image::before { content: "\f36d"; }
+.bi-file-earmark-lock-fill::before { content: "\f36e"; }
+.bi-file-earmark-lock::before { content: "\f36f"; }
+.bi-file-earmark-lock2-fill::before { content: "\f370"; }
+.bi-file-earmark-lock2::before { content: "\f371"; }
+.bi-file-earmark-medical-fill::before { content: "\f372"; }
+.bi-file-earmark-medical::before { content: "\f373"; }
+.bi-file-earmark-minus-fill::before { content: "\f374"; }
+.bi-file-earmark-minus::before { content: "\f375"; }
+.bi-file-earmark-music-fill::before { content: "\f376"; }
+.bi-file-earmark-music::before { content: "\f377"; }
+.bi-file-earmark-person-fill::before { content: "\f378"; }
+.bi-file-earmark-person::before { content: "\f379"; }
+.bi-file-earmark-play-fill::before { content: "\f37a"; }
+.bi-file-earmark-play::before { content: "\f37b"; }
+.bi-file-earmark-plus-fill::before { content: "\f37c"; }
+.bi-file-earmark-plus::before { content: "\f37d"; }
+.bi-file-earmark-post-fill::before { content: "\f37e"; }
+.bi-file-earmark-post::before { content: "\f37f"; }
+.bi-file-earmark-ppt-fill::before { content: "\f380"; }
+.bi-file-earmark-ppt::before { content: "\f381"; }
+.bi-file-earmark-richtext-fill::before { content: "\f382"; }
+.bi-file-earmark-richtext::before { content: "\f383"; }
+.bi-file-earmark-ruled-fill::before { content: "\f384"; }
+.bi-file-earmark-ruled::before { content: "\f385"; }
+.bi-file-earmark-slides-fill::before { content: "\f386"; }
+.bi-file-earmark-slides::before { content: "\f387"; }
+.bi-file-earmark-spreadsheet-fill::before { content: "\f388"; }
+.bi-file-earmark-spreadsheet::before { content: "\f389"; }
+.bi-file-earmark-text-fill::before { content: "\f38a"; }
+.bi-file-earmark-text::before { content: "\f38b"; }
+.bi-file-earmark-word-fill::before { content: "\f38c"; }
+.bi-file-earmark-word::before { content: "\f38d"; }
+.bi-file-earmark-x-fill::before { content: "\f38e"; }
+.bi-file-earmark-x::before { content: "\f38f"; }
+.bi-file-earmark-zip-fill::before { content: "\f390"; }
+.bi-file-earmark-zip::before { content: "\f391"; }
+.bi-file-earmark::before { content: "\f392"; }
+.bi-file-easel-fill::before { content: "\f393"; }
+.bi-file-easel::before { content: "\f394"; }
+.bi-file-excel-fill::before { content: "\f395"; }
+.bi-file-excel::before { content: "\f396"; }
+.bi-file-fill::before { content: "\f397"; }
+.bi-file-font-fill::before { content: "\f398"; }
+.bi-file-font::before { content: "\f399"; }
+.bi-file-image-fill::before { content: "\f39a"; }
+.bi-file-image::before { content: "\f39b"; }
+.bi-file-lock-fill::before { content: "\f39c"; }
+.bi-file-lock::before { content: "\f39d"; }
+.bi-file-lock2-fill::before { content: "\f39e"; }
+.bi-file-lock2::before { content: "\f39f"; }
+.bi-file-medical-fill::before { content: "\f3a0"; }
+.bi-file-medical::before { content: "\f3a1"; }
+.bi-file-minus-fill::before { content: "\f3a2"; }
+.bi-file-minus::before { content: "\f3a3"; }
+.bi-file-music-fill::before { content: "\f3a4"; }
+.bi-file-music::before { content: "\f3a5"; }
+.bi-file-person-fill::before { content: "\f3a6"; }
+.bi-file-person::before { content: "\f3a7"; }
+.bi-file-play-fill::before { content: "\f3a8"; }
+.bi-file-play::before { content: "\f3a9"; }
+.bi-file-plus-fill::before { content: "\f3aa"; }
+.bi-file-plus::before { content: "\f3ab"; }
+.bi-file-post-fill::before { content: "\f3ac"; }
+.bi-file-post::before { content: "\f3ad"; }
+.bi-file-ppt-fill::before { content: "\f3ae"; }
+.bi-file-ppt::before { content: "\f3af"; }
+.bi-file-richtext-fill::before { content: "\f3b0"; }
+.bi-file-richtext::before { content: "\f3b1"; }
+.bi-file-ruled-fill::before { content: "\f3b2"; }
+.bi-file-ruled::before { content: "\f3b3"; }
+.bi-file-slides-fill::before { content: "\f3b4"; }
+.bi-file-slides::before { content: "\f3b5"; }
+.bi-file-spreadsheet-fill::before { content: "\f3b6"; }
+.bi-file-spreadsheet::before { content: "\f3b7"; }
+.bi-file-text-fill::before { content: "\f3b8"; }
+.bi-file-text::before { content: "\f3b9"; }
+.bi-file-word-fill::before { content: "\f3ba"; }
+.bi-file-word::before { content: "\f3bb"; }
+.bi-file-x-fill::before { content: "\f3bc"; }
+.bi-file-x::before { content: "\f3bd"; }
+.bi-file-zip-fill::before { content: "\f3be"; }
+.bi-file-zip::before { content: "\f3bf"; }
+.bi-file::before { content: "\f3c0"; }
+.bi-files-alt::before { content: "\f3c1"; }
+.bi-files::before { content: "\f3c2"; }
+.bi-film::before { content: "\f3c3"; }
+.bi-filter-circle-fill::before { content: "\f3c4"; }
+.bi-filter-circle::before { content: "\f3c5"; }
+.bi-filter-left::before { content: "\f3c6"; }
+.bi-filter-right::before { content: "\f3c7"; }
+.bi-filter-square-fill::before { content: "\f3c8"; }
+.bi-filter-square::before { content: "\f3c9"; }
+.bi-filter::before { content: "\f3ca"; }
+.bi-flag-fill::before { content: "\f3cb"; }
+.bi-flag::before { content: "\f3cc"; }
+.bi-flower1::before { content: "\f3cd"; }
+.bi-flower2::before { content: "\f3ce"; }
+.bi-flower3::before { content: "\f3cf"; }
+.bi-folder-check::before { content: "\f3d0"; }
+.bi-folder-fill::before { content: "\f3d1"; }
+.bi-folder-minus::before { content: "\f3d2"; }
+.bi-folder-plus::before { content: "\f3d3"; }
+.bi-folder-symlink-fill::before { content: "\f3d4"; }
+.bi-folder-symlink::before { content: "\f3d5"; }
+.bi-folder-x::before { content: "\f3d6"; }
+.bi-folder::before { content: "\f3d7"; }
+.bi-folder2-open::before { content: "\f3d8"; }
+.bi-folder2::before { content: "\f3d9"; }
+.bi-fonts::before { content: "\f3da"; }
+.bi-forward-fill::before { content: "\f3db"; }
+.bi-forward::before { content: "\f3dc"; }
+.bi-front::before { content: "\f3dd"; }
+.bi-fullscreen-exit::before { content: "\f3de"; }
+.bi-fullscreen::before { content: "\f3df"; }
+.bi-funnel-fill::before { content: "\f3e0"; }
+.bi-funnel::before { content: "\f3e1"; }
+.bi-gear-fill::before { content: "\f3e2"; }
+.bi-gear-wide-connected::before { content: "\f3e3"; }
+.bi-gear-wide::before { content: "\f3e4"; }
+.bi-gear::before { content: "\f3e5"; }
+.bi-gem::before { content: "\f3e6"; }
+.bi-geo-alt-fill::before { content: "\f3e7"; }
+.bi-geo-alt::before { content: "\f3e8"; }
+.bi-geo-fill::before { content: "\f3e9"; }
+.bi-geo::before { content: "\f3ea"; }
+.bi-gift-fill::before { content: "\f3eb"; }
+.bi-gift::before { content: "\f3ec"; }
+.bi-github::before { content: "\f3ed"; }
+.bi-globe::before { content: "\f3ee"; }
+.bi-globe2::before { content: "\f3ef"; }
+.bi-google::before { content: "\f3f0"; }
+.bi-graph-down::before { content: "\f3f1"; }
+.bi-graph-up::before { content: "\f3f2"; }
+.bi-grid-1x2-fill::before { content: "\f3f3"; }
+.bi-grid-1x2::before { content: "\f3f4"; }
+.bi-grid-3x2-gap-fill::before { content: "\f3f5"; }
+.bi-grid-3x2-gap::before { content: "\f3f6"; }
+.bi-grid-3x2::before { content: "\f3f7"; }
+.bi-grid-3x3-gap-fill::before { content: "\f3f8"; }
+.bi-grid-3x3-gap::before { content: "\f3f9"; }
+.bi-grid-3x3::before { content: "\f3fa"; }
+.bi-grid-fill::before { content: "\f3fb"; }
+.bi-grid::before { content: "\f3fc"; }
+.bi-grip-horizontal::before { content: "\f3fd"; }
+.bi-grip-vertical::before { content: "\f3fe"; }
+.bi-hammer::before { content: "\f3ff"; }
+.bi-hand-index-fill::before { content: "\f400"; }
+.bi-hand-index-thumb-fill::before { content: "\f401"; }
+.bi-hand-index-thumb::before { content: "\f402"; }
+.bi-hand-index::before { content: "\f403"; }
+.bi-hand-thumbs-down-fill::before { content: "\f404"; }
+.bi-hand-thumbs-down::before { content: "\f405"; }
+.bi-hand-thumbs-up-fill::before { content: "\f406"; }
+.bi-hand-thumbs-up::before { content: "\f407"; }
+.bi-handbag-fill::before { content: "\f408"; }
+.bi-handbag::before { content: "\f409"; }
+.bi-hash::before { content: "\f40a"; }
+.bi-hdd-fill::before { content: "\f40b"; }
+.bi-hdd-network-fill::before { content: "\f40c"; }
+.bi-hdd-network::before { content: "\f40d"; }
+.bi-hdd-rack-fill::before { content: "\f40e"; }
+.bi-hdd-rack::before { content: "\f40f"; }
+.bi-hdd-stack-fill::before { content: "\f410"; }
+.bi-hdd-stack::before { content: "\f411"; }
+.bi-hdd::before { content: "\f412"; }
+.bi-headphones::before { content: "\f413"; }
+.bi-headset::before { content: "\f414"; }
+.bi-heart-fill::before { content: "\f415"; }
+.bi-heart-half::before { content: "\f416"; }
+.bi-heart::before { content: "\f417"; }
+.bi-heptagon-fill::before { content: "\f418"; }
+.bi-heptagon-half::before { content: "\f419"; }
+.bi-heptagon::before { content: "\f41a"; }
+.bi-hexagon-fill::before { content: "\f41b"; }
+.bi-hexagon-half::before { content: "\f41c"; }
+.bi-hexagon::before { content: "\f41d"; }
+.bi-hourglass-bottom::before { content: "\f41e"; }
+.bi-hourglass-split::before { content: "\f41f"; }
+.bi-hourglass-top::before { content: "\f420"; }
+.bi-hourglass::before { content: "\f421"; }
+.bi-house-door-fill::before { content: "\f422"; }
+.bi-house-door::before { content: "\f423"; }
+.bi-house-fill::before { content: "\f424"; }
+.bi-house::before { content: "\f425"; }
+.bi-hr::before { content: "\f426"; }
+.bi-hurricane::before { content: "\f427"; }
+.bi-image-alt::before { content: "\f428"; }
+.bi-image-fill::before { content: "\f429"; }
+.bi-image::before { content: "\f42a"; }
+.bi-images::before { content: "\f42b"; }
+.bi-inbox-fill::before { content: "\f42c"; }
+.bi-inbox::before { content: "\f42d"; }
+.bi-inboxes-fill::before { content: "\f42e"; }
+.bi-inboxes::before { content: "\f42f"; }
+.bi-info-circle-fill::before { content: "\f430"; }
+.bi-info-circle::before { content: "\f431"; }
+.bi-info-square-fill::before { content: "\f432"; }
+.bi-info-square::before { content: "\f433"; }
+.bi-info::before { content: "\f434"; }
+.bi-input-cursor-text::before { content: "\f435"; }
+.bi-input-cursor::before { content: "\f436"; }
+.bi-instagram::before { content: "\f437"; }
+.bi-intersect::before { content: "\f438"; }
+.bi-journal-album::before { content: "\f439"; }
+.bi-journal-arrow-down::before { content: "\f43a"; }
+.bi-journal-arrow-up::before { content: "\f43b"; }
+.bi-journal-bookmark-fill::before { content: "\f43c"; }
+.bi-journal-bookmark::before { content: "\f43d"; }
+.bi-journal-check::before { content: "\f43e"; }
+.bi-journal-code::before { content: "\f43f"; }
+.bi-journal-medical::before { content: "\f440"; }
+.bi-journal-minus::before { content: "\f441"; }
+.bi-journal-plus::before { content: "\f442"; }
+.bi-journal-richtext::before { content: "\f443"; }
+.bi-journal-text::before { content: "\f444"; }
+.bi-journal-x::before { content: "\f445"; }
+.bi-journal::before { content: "\f446"; }
+.bi-journals::before { content: "\f447"; }
+.bi-joystick::before { content: "\f448"; }
+.bi-justify-left::before { content: "\f449"; }
+.bi-justify-right::before { content: "\f44a"; }
+.bi-justify::before { content: "\f44b"; }
+.bi-kanban-fill::before { content: "\f44c"; }
+.bi-kanban::before { content: "\f44d"; }
+.bi-key-fill::before { content: "\f44e"; }
+.bi-key::before { content: "\f44f"; }
+.bi-keyboard-fill::before { content: "\f450"; }
+.bi-keyboard::before { content: "\f451"; }
+.bi-ladder::before { content: "\f452"; }
+.bi-lamp-fill::before { content: "\f453"; }
+.bi-lamp::before { content: "\f454"; }
+.bi-laptop-fill::before { content: "\f455"; }
+.bi-laptop::before { content: "\f456"; }
+.bi-layer-backward::before { content: "\f457"; }
+.bi-layer-forward::before { content: "\f458"; }
+.bi-layers-fill::before { content: "\f459"; }
+.bi-layers-half::before { content: "\f45a"; }
+.bi-layers::before { content: "\f45b"; }
+.bi-layout-sidebar-inset-reverse::before { content: "\f45c"; }
+.bi-layout-sidebar-inset::before { content: "\f45d"; }
+.bi-layout-sidebar-reverse::before { content: "\f45e"; }
+.bi-layout-sidebar::before { content: "\f45f"; }
+.bi-layout-split::before { content: "\f460"; }
+.bi-layout-text-sidebar-reverse::before { content: "\f461"; }
+.bi-layout-text-sidebar::before { content: "\f462"; }
+.bi-layout-text-window-reverse::before { content: "\f463"; }
+.bi-layout-text-window::before { content: "\f464"; }
+.bi-layout-three-columns::before { content: "\f465"; }
+.bi-layout-wtf::before { content: "\f466"; }
+.bi-life-preserver::before { content: "\f467"; }
+.bi-lightbulb-fill::before { content: "\f468"; }
+.bi-lightbulb-off-fill::before { content: "\f469"; }
+.bi-lightbulb-off::before { content: "\f46a"; }
+.bi-lightbulb::before { content: "\f46b"; }
+.bi-lightning-charge-fill::before { content: "\f46c"; }
+.bi-lightning-charge::before { content: "\f46d"; }
+.bi-lightning-fill::before { content: "\f46e"; }
+.bi-lightning::before { content: "\f46f"; }
+.bi-link-45deg::before { content: "\f470"; }
+.bi-link::before { content: "\f471"; }
+.bi-linkedin::before { content: "\f472"; }
+.bi-list-check::before { content: "\f473"; }
+.bi-list-nested::before { content: "\f474"; }
+.bi-list-ol::before { content: "\f475"; }
+.bi-list-stars::before { content: "\f476"; }
+.bi-list-task::before { content: "\f477"; }
+.bi-list-ul::before { content: "\f478"; }
+.bi-list::before { content: "\f479"; }
+.bi-lock-fill::before { content: "\f47a"; }
+.bi-lock::before { content: "\f47b"; }
+.bi-mailbox::before { content: "\f47c"; }
+.bi-mailbox2::before { content: "\f47d"; }
+.bi-map-fill::before { content: "\f47e"; }
+.bi-map::before { content: "\f47f"; }
+.bi-markdown-fill::before { content: "\f480"; }
+.bi-markdown::before { content: "\f481"; }
+.bi-mask::before { content: "\f482"; }
+.bi-megaphone-fill::before { content: "\f483"; }
+.bi-megaphone::before { content: "\f484"; }
+.bi-menu-app-fill::before { content: "\f485"; }
+.bi-menu-app::before { content: "\f486"; }
+.bi-menu-button-fill::before { content: "\f487"; }
+.bi-menu-button-wide-fill::before { content: "\f488"; }
+.bi-menu-button-wide::before { content: "\f489"; }
+.bi-menu-button::before { content: "\f48a"; }
+.bi-menu-down::before { content: "\f48b"; }
+.bi-menu-up::before { content: "\f48c"; }
+.bi-mic-fill::before { content: "\f48d"; }
+.bi-mic-mute-fill::before { content: "\f48e"; }
+.bi-mic-mute::before { content: "\f48f"; }
+.bi-mic::before { content: "\f490"; }
+.bi-minecart-loaded::before { content: "\f491"; }
+.bi-minecart::before { content: "\f492"; }
+.bi-moisture::before { content: "\f493"; }
+.bi-moon-fill::before { content: "\f494"; }
+.bi-moon-stars-fill::before { content: "\f495"; }
+.bi-moon-stars::before { content: "\f496"; }
+.bi-moon::before { content: "\f497"; }
+.bi-mouse-fill::before { content: "\f498"; }
+.bi-mouse::before { content: "\f499"; }
+.bi-mouse2-fill::before { content: "\f49a"; }
+.bi-mouse2::before { content: "\f49b"; }
+.bi-mouse3-fill::before { content: "\f49c"; }
+.bi-mouse3::before { content: "\f49d"; }
+.bi-music-note-beamed::before { content: "\f49e"; }
+.bi-music-note-list::before { content: "\f49f"; }
+.bi-music-note::before { content: "\f4a0"; }
+.bi-music-player-fill::before { content: "\f4a1"; }
+.bi-music-player::before { content: "\f4a2"; }
+.bi-newspaper::before { content: "\f4a3"; }
+.bi-node-minus-fill::before { content: "\f4a4"; }
+.bi-node-minus::before { content: "\f4a5"; }
+.bi-node-plus-fill::before { content: "\f4a6"; }
+.bi-node-plus::before { content: "\f4a7"; }
+.bi-nut-fill::before { content: "\f4a8"; }
+.bi-nut::before { content: "\f4a9"; }
+.bi-octagon-fill::before { content: "\f4aa"; }
+.bi-octagon-half::before { content: "\f4ab"; }
+.bi-octagon::before { content: "\f4ac"; }
+.bi-option::before { content: "\f4ad"; }
+.bi-outlet::before { content: "\f4ae"; }
+.bi-paint-bucket::before { content: "\f4af"; }
+.bi-palette-fill::before { content: "\f4b0"; }
+.bi-palette::before { content: "\f4b1"; }
+.bi-palette2::before { content: "\f4b2"; }
+.bi-paperclip::before { content: "\f4b3"; }
+.bi-paragraph::before { content: "\f4b4"; }
+.bi-patch-check-fill::before { content: "\f4b5"; }
+.bi-patch-check::before { content: "\f4b6"; }
+.bi-patch-exclamation-fill::before { content: "\f4b7"; }
+.bi-patch-exclamation::before { content: "\f4b8"; }
+.bi-patch-minus-fill::before { content: "\f4b9"; }
+.bi-patch-minus::before { content: "\f4ba"; }
+.bi-patch-plus-fill::before { content: "\f4bb"; }
+.bi-patch-plus::before { content: "\f4bc"; }
+.bi-patch-question-fill::before { content: "\f4bd"; }
+.bi-patch-question::before { content: "\f4be"; }
+.bi-pause-btn-fill::before { content: "\f4bf"; }
+.bi-pause-btn::before { content: "\f4c0"; }
+.bi-pause-circle-fill::before { content: "\f4c1"; }
+.bi-pause-circle::before { content: "\f4c2"; }
+.bi-pause-fill::before { content: "\f4c3"; }
+.bi-pause::before { content: "\f4c4"; }
+.bi-peace-fill::before { content: "\f4c5"; }
+.bi-peace::before { content: "\f4c6"; }
+.bi-pen-fill::before { content: "\f4c7"; }
+.bi-pen::before { content: "\f4c8"; }
+.bi-pencil-fill::before { content: "\f4c9"; }
+.bi-pencil-square::before { content: "\f4ca"; }
+.bi-pencil::before { content: "\f4cb"; }
+.bi-pentagon-fill::before { content: "\f4cc"; }
+.bi-pentagon-half::before { content: "\f4cd"; }
+.bi-pentagon::before { content: "\f4ce"; }
+.bi-people-fill::before { content: "\f4cf"; }
+.bi-people::before { content: "\f4d0"; }
+.bi-percent::before { content: "\f4d1"; }
+.bi-person-badge-fill::before { content: "\f4d2"; }
+.bi-person-badge::before { content: "\f4d3"; }
+.bi-person-bounding-box::before { content: "\f4d4"; }
+.bi-person-check-fill::before { content: "\f4d5"; }
+.bi-person-check::before { content: "\f4d6"; }
+.bi-person-circle::before { content: "\f4d7"; }
+.bi-person-dash-fill::before { content: "\f4d8"; }
+.bi-person-dash::before { content: "\f4d9"; }
+.bi-person-fill::before { content: "\f4da"; }
+.bi-person-lines-fill::before { content: "\f4db"; }
+.bi-person-plus-fill::before { content: "\f4dc"; }
+.bi-person-plus::before { content: "\f4dd"; }
+.bi-person-square::before { content: "\f4de"; }
+.bi-person-x-fill::before { content: "\f4df"; }
+.bi-person-x::before { content: "\f4e0"; }
+.bi-person::before { content: "\f4e1"; }
+.bi-phone-fill::before { content: "\f4e2"; }
+.bi-phone-landscape-fill::before { content: "\f4e3"; }
+.bi-phone-landscape::before { content: "\f4e4"; }
+.bi-phone-vibrate-fill::before { content: "\f4e5"; }
+.bi-phone-vibrate::before { content: "\f4e6"; }
+.bi-phone::before { content: "\f4e7"; }
+.bi-pie-chart-fill::before { content: "\f4e8"; }
+.bi-pie-chart::before { content: "\f4e9"; }
+.bi-pin-angle-fill::before { content: "\f4ea"; }
+.bi-pin-angle::before { content: "\f4eb"; }
+.bi-pin-fill::before { content: "\f4ec"; }
+.bi-pin::before { content: "\f4ed"; }
+.bi-pip-fill::before { content: "\f4ee"; }
+.bi-pip::before { content: "\f4ef"; }
+.bi-play-btn-fill::before { content: "\f4f0"; }
+.bi-play-btn::before { content: "\f4f1"; }
+.bi-play-circle-fill::before { content: "\f4f2"; }
+.bi-play-circle::before { content: "\f4f3"; }
+.bi-play-fill::before { content: "\f4f4"; }
+.bi-play::before { content: "\f4f5"; }
+.bi-plug-fill::before { content: "\f4f6"; }
+.bi-plug::before { content: "\f4f7"; }
+.bi-plus-circle-dotted::before { content: "\f4f8"; }
+.bi-plus-circle-fill::before { content: "\f4f9"; }
+.bi-plus-circle::before { content: "\f4fa"; }
+.bi-plus-square-dotted::before { content: "\f4fb"; }
+.bi-plus-square-fill::before { content: "\f4fc"; }
+.bi-plus-square::before { content: "\f4fd"; }
+.bi-plus::before { content: "\f4fe"; }
+.bi-power::before { content: "\f4ff"; }
+.bi-printer-fill::before { content: "\f500"; }
+.bi-printer::before { content: "\f501"; }
+.bi-puzzle-fill::before { content: "\f502"; }
+.bi-puzzle::before { content: "\f503"; }
+.bi-question-circle-fill::before { content: "\f504"; }
+.bi-question-circle::before { content: "\f505"; }
+.bi-question-diamond-fill::before { content: "\f506"; }
+.bi-question-diamond::before { content: "\f507"; }
+.bi-question-octagon-fill::before { content: "\f508"; }
+.bi-question-octagon::before { content: "\f509"; }
+.bi-question-square-fill::before { content: "\f50a"; }
+.bi-question-square::before { content: "\f50b"; }
+.bi-question::before { content: "\f50c"; }
+.bi-rainbow::before { content: "\f50d"; }
+.bi-receipt-cutoff::before { content: "\f50e"; }
+.bi-receipt::before { content: "\f50f"; }
+.bi-reception-0::before { content: "\f510"; }
+.bi-reception-1::before { content: "\f511"; }
+.bi-reception-2::before { content: "\f512"; }
+.bi-reception-3::before { content: "\f513"; }
+.bi-reception-4::before { content: "\f514"; }
+.bi-record-btn-fill::before { content: "\f515"; }
+.bi-record-btn::before { content: "\f516"; }
+.bi-record-circle-fill::before { content: "\f517"; }
+.bi-record-circle::before { content: "\f518"; }
+.bi-record-fill::before { content: "\f519"; }
+.bi-record::before { content: "\f51a"; }
+.bi-record2-fill::before { content: "\f51b"; }
+.bi-record2::before { content: "\f51c"; }
+.bi-reply-all-fill::before { content: "\f51d"; }
+.bi-reply-all::before { content: "\f51e"; }
+.bi-reply-fill::before { content: "\f51f"; }
+.bi-reply::before { content: "\f520"; }
+.bi-rss-fill::before { content: "\f521"; }
+.bi-rss::before { content: "\f522"; }
+.bi-rulers::before { content: "\f523"; }
+.bi-save-fill::before { content: "\f524"; }
+.bi-save::before { content: "\f525"; }
+.bi-save2-fill::before { content: "\f526"; }
+.bi-save2::before { content: "\f527"; }
+.bi-scissors::before { content: "\f528"; }
+.bi-screwdriver::before { content: "\f529"; }
+.bi-search::before { content: "\f52a"; }
+.bi-segmented-nav::before { content: "\f52b"; }
+.bi-server::before { content: "\f52c"; }
+.bi-share-fill::before { content: "\f52d"; }
+.bi-share::before { content: "\f52e"; }
+.bi-shield-check::before { content: "\f52f"; }
+.bi-shield-exclamation::before { content: "\f530"; }
+.bi-shield-fill-check::before { content: "\f531"; }
+.bi-shield-fill-exclamation::before { content: "\f532"; }
+.bi-shield-fill-minus::before { content: "\f533"; }
+.bi-shield-fill-plus::before { content: "\f534"; }
+.bi-shield-fill-x::before { content: "\f535"; }
+.bi-shield-fill::before { content: "\f536"; }
+.bi-shield-lock-fill::before { content: "\f537"; }
+.bi-shield-lock::before { content: "\f538"; }
+.bi-shield-minus::before { content: "\f539"; }
+.bi-shield-plus::before { content: "\f53a"; }
+.bi-shield-shaded::before { content: "\f53b"; }
+.bi-shield-slash-fill::before { content: "\f53c"; }
+.bi-shield-slash::before { content: "\f53d"; }
+.bi-shield-x::before { content: "\f53e"; }
+.bi-shield::before { content: "\f53f"; }
+.bi-shift-fill::before { content: "\f540"; }
+.bi-shift::before { content: "\f541"; }
+.bi-shop-window::before { content: "\f542"; }
+.bi-shop::before { content: "\f543"; }
+.bi-shuffle::before { content: "\f544"; }
+.bi-signpost-2-fill::before { content: "\f545"; }
+.bi-signpost-2::before { content: "\f546"; }
+.bi-signpost-fill::before { content: "\f547"; }
+.bi-signpost-split-fill::before { content: "\f548"; }
+.bi-signpost-split::before { content: "\f549"; }
+.bi-signpost::before { content: "\f54a"; }
+.bi-sim-fill::before { content: "\f54b"; }
+.bi-sim::before { content: "\f54c"; }
+.bi-skip-backward-btn-fill::before { content: "\f54d"; }
+.bi-skip-backward-btn::before { content: "\f54e"; }
+.bi-skip-backward-circle-fill::before { content: "\f54f"; }
+.bi-skip-backward-circle::before { content: "\f550"; }
+.bi-skip-backward-fill::before { content: "\f551"; }
+.bi-skip-backward::before { content: "\f552"; }
+.bi-skip-end-btn-fill::before { content: "\f553"; }
+.bi-skip-end-btn::before { content: "\f554"; }
+.bi-skip-end-circle-fill::before { content: "\f555"; }
+.bi-skip-end-circle::before { content: "\f556"; }
+.bi-skip-end-fill::before { content: "\f557"; }
+.bi-skip-end::before { content: "\f558"; }
+.bi-skip-forward-btn-fill::before { content: "\f559"; }
+.bi-skip-forward-btn::before { content: "\f55a"; }
+.bi-skip-forward-circle-fill::before { content: "\f55b"; }
+.bi-skip-forward-circle::before { content: "\f55c"; }
+.bi-skip-forward-fill::before { content: "\f55d"; }
+.bi-skip-forward::before { content: "\f55e"; }
+.bi-skip-start-btn-fill::before { content: "\f55f"; }
+.bi-skip-start-btn::before { content: "\f560"; }
+.bi-skip-start-circle-fill::before { content: "\f561"; }
+.bi-skip-start-circle::before { content: "\f562"; }
+.bi-skip-start-fill::before { content: "\f563"; }
+.bi-skip-start::before { content: "\f564"; }
+.bi-slack::before { content: "\f565"; }
+.bi-slash-circle-fill::before { content: "\f566"; }
+.bi-slash-circle::before { content: "\f567"; }
+.bi-slash-square-fill::before { content: "\f568"; }
+.bi-slash-square::before { content: "\f569"; }
+.bi-slash::before { content: "\f56a"; }
+.bi-sliders::before { content: "\f56b"; }
+.bi-smartwatch::before { content: "\f56c"; }
+.bi-snow::before { content: "\f56d"; }
+.bi-snow2::before { content: "\f56e"; }
+.bi-snow3::before { content: "\f56f"; }
+.bi-sort-alpha-down-alt::before { content: "\f570"; }
+.bi-sort-alpha-down::before { content: "\f571"; }
+.bi-sort-alpha-up-alt::before { content: "\f572"; }
+.bi-sort-alpha-up::before { content: "\f573"; }
+.bi-sort-down-alt::before { content: "\f574"; }
+.bi-sort-down::before { content: "\f575"; }
+.bi-sort-numeric-down-alt::before { content: "\f576"; }
+.bi-sort-numeric-down::before { content: "\f577"; }
+.bi-sort-numeric-up-alt::before { content: "\f578"; }
+.bi-sort-numeric-up::before { content: "\f579"; }
+.bi-sort-up-alt::before { content: "\f57a"; }
+.bi-sort-up::before { content: "\f57b"; }
+.bi-soundwave::before { content: "\f57c"; }
+.bi-speaker-fill::before { content: "\f57d"; }
+.bi-speaker::before { content: "\f57e"; }
+.bi-speedometer::before { content: "\f57f"; }
+.bi-speedometer2::before { content: "\f580"; }
+.bi-spellcheck::before { content: "\f581"; }
+.bi-square-fill::before { content: "\f582"; }
+.bi-square-half::before { content: "\f583"; }
+.bi-square::before { content: "\f584"; }
+.bi-stack::before { content: "\f585"; }
+.bi-star-fill::before { content: "\f586"; }
+.bi-star-half::before { content: "\f587"; }
+.bi-star::before { content: "\f588"; }
+.bi-stars::before { content: "\f589"; }
+.bi-stickies-fill::before { content: "\f58a"; }
+.bi-stickies::before { content: "\f58b"; }
+.bi-sticky-fill::before { content: "\f58c"; }
+.bi-sticky::before { content: "\f58d"; }
+.bi-stop-btn-fill::before { content: "\f58e"; }
+.bi-stop-btn::before { content: "\f58f"; }
+.bi-stop-circle-fill::before { content: "\f590"; }
+.bi-stop-circle::before { content: "\f591"; }
+.bi-stop-fill::before { content: "\f592"; }
+.bi-stop::before { content: "\f593"; }
+.bi-stoplights-fill::before { content: "\f594"; }
+.bi-stoplights::before { content: "\f595"; }
+.bi-stopwatch-fill::before { content: "\f596"; }
+.bi-stopwatch::before { content: "\f597"; }
+.bi-subtract::before { content: "\f598"; }
+.bi-suit-club-fill::before { content: "\f599"; }
+.bi-suit-club::before { content: "\f59a"; }
+.bi-suit-diamond-fill::before { content: "\f59b"; }
+.bi-suit-diamond::before { content: "\f59c"; }
+.bi-suit-heart-fill::before { content: "\f59d"; }
+.bi-suit-heart::before { content: "\f59e"; }
+.bi-suit-spade-fill::before { content: "\f59f"; }
+.bi-suit-spade::before { content: "\f5a0"; }
+.bi-sun-fill::before { content: "\f5a1"; }
+.bi-sun::before { content: "\f5a2"; }
+.bi-sunglasses::before { content: "\f5a3"; }
+.bi-sunrise-fill::before { content: "\f5a4"; }
+.bi-sunrise::before { content: "\f5a5"; }
+.bi-sunset-fill::before { content: "\f5a6"; }
+.bi-sunset::before { content: "\f5a7"; }
+.bi-symmetry-horizontal::before { content: "\f5a8"; }
+.bi-symmetry-vertical::before { content: "\f5a9"; }
+.bi-table::before { content: "\f5aa"; }
+.bi-tablet-fill::before { content: "\f5ab"; }
+.bi-tablet-landscape-fill::before { content: "\f5ac"; }
+.bi-tablet-landscape::before { content: "\f5ad"; }
+.bi-tablet::before { content: "\f5ae"; }
+.bi-tag-fill::before { content: "\f5af"; }
+.bi-tag::before { content: "\f5b0"; }
+.bi-tags-fill::before { content: "\f5b1"; }
+.bi-tags::before { content: "\f5b2"; }
+.bi-telegram::before { content: "\f5b3"; }
+.bi-telephone-fill::before { content: "\f5b4"; }
+.bi-telephone-forward-fill::before { content: "\f5b5"; }
+.bi-telephone-forward::before { content: "\f5b6"; }
+.bi-telephone-inbound-fill::before { content: "\f5b7"; }
+.bi-telephone-inbound::before { content: "\f5b8"; }
+.bi-telephone-minus-fill::before { content: "\f5b9"; }
+.bi-telephone-minus::before { content: "\f5ba"; }
+.bi-telephone-outbound-fill::before { content: "\f5bb"; }
+.bi-telephone-outbound::before { content: "\f5bc"; }
+.bi-telephone-plus-fill::before { content: "\f5bd"; }
+.bi-telephone-plus::before { content: "\f5be"; }
+.bi-telephone-x-fill::before { content: "\f5bf"; }
+.bi-telephone-x::before { content: "\f5c0"; }
+.bi-telephone::before { content: "\f5c1"; }
+.bi-terminal-fill::before { content: "\f5c2"; }
+.bi-terminal::before { content: "\f5c3"; }
+.bi-text-center::before { content: "\f5c4"; }
+.bi-text-indent-left::before { content: "\f5c5"; }
+.bi-text-indent-right::before { content: "\f5c6"; }
+.bi-text-left::before { content: "\f5c7"; }
+.bi-text-paragraph::before { content: "\f5c8"; }
+.bi-text-right::before { content: "\f5c9"; }
+.bi-textarea-resize::before { content: "\f5ca"; }
+.bi-textarea-t::before { content: "\f5cb"; }
+.bi-textarea::before { content: "\f5cc"; }
+.bi-thermometer-half::before { content: "\f5cd"; }
+.bi-thermometer-high::before { content: "\f5ce"; }
+.bi-thermometer-low::before { content: "\f5cf"; }
+.bi-thermometer-snow::before { content: "\f5d0"; }
+.bi-thermometer-sun::before { content: "\f5d1"; }
+.bi-thermometer::before { content: "\f5d2"; }
+.bi-three-dots-vertical::before { content: "\f5d3"; }
+.bi-three-dots::before { content: "\f5d4"; }
+.bi-toggle-off::before { content: "\f5d5"; }
+.bi-toggle-on::before { content: "\f5d6"; }
+.bi-toggle2-off::before { content: "\f5d7"; }
+.bi-toggle2-on::before { content: "\f5d8"; }
+.bi-toggles::before { content: "\f5d9"; }
+.bi-toggles2::before { content: "\f5da"; }
+.bi-tools::before { content: "\f5db"; }
+.bi-tornado::before { content: "\f5dc"; }
+.bi-trash-fill::before { content: "\f5dd"; }
+.bi-trash::before { content: "\f5de"; }
+.bi-trash2-fill::before { content: "\f5df"; }
+.bi-trash2::before { content: "\f5e0"; }
+.bi-tree-fill::before { content: "\f5e1"; }
+.bi-tree::before { content: "\f5e2"; }
+.bi-triangle-fill::before { content: "\f5e3"; }
+.bi-triangle-half::before { content: "\f5e4"; }
+.bi-triangle::before { content: "\f5e5"; }
+.bi-trophy-fill::before { content: "\f5e6"; }
+.bi-trophy::before { content: "\f5e7"; }
+.bi-tropical-storm::before { content: "\f5e8"; }
+.bi-truck-flatbed::before { content: "\f5e9"; }
+.bi-truck::before { content: "\f5ea"; }
+.bi-tsunami::before { content: "\f5eb"; }
+.bi-tv-fill::before { content: "\f5ec"; }
+.bi-tv::before { content: "\f5ed"; }
+.bi-twitch::before { content: "\f5ee"; }
+.bi-twitter::before { content: "\f5ef"; }
+.bi-type-bold::before { content: "\f5f0"; }
+.bi-type-h1::before { content: "\f5f1"; }
+.bi-type-h2::before { content: "\f5f2"; }
+.bi-type-h3::before { content: "\f5f3"; }
+.bi-type-italic::before { content: "\f5f4"; }
+.bi-type-strikethrough::before { content: "\f5f5"; }
+.bi-type-underline::before { content: "\f5f6"; }
+.bi-type::before { content: "\f5f7"; }
+.bi-ui-checks-grid::before { content: "\f5f8"; }
+.bi-ui-checks::before { content: "\f5f9"; }
+.bi-ui-radios-grid::before { content: "\f5fa"; }
+.bi-ui-radios::before { content: "\f5fb"; }
+.bi-umbrella-fill::before { content: "\f5fc"; }
+.bi-umbrella::before { content: "\f5fd"; }
+.bi-union::before { content: "\f5fe"; }
+.bi-unlock-fill::before { content: "\f5ff"; }
+.bi-unlock::before { content: "\f600"; }
+.bi-upc-scan::before { content: "\f601"; }
+.bi-upc::before { content: "\f602"; }
+.bi-upload::before { content: "\f603"; }
+.bi-vector-pen::before { content: "\f604"; }
+.bi-view-list::before { content: "\f605"; }
+.bi-view-stacked::before { content: "\f606"; }
+.bi-vinyl-fill::before { content: "\f607"; }
+.bi-vinyl::before { content: "\f608"; }
+.bi-voicemail::before { content: "\f609"; }
+.bi-volume-down-fill::before { content: "\f60a"; }
+.bi-volume-down::before { content: "\f60b"; }
+.bi-volume-mute-fill::before { content: "\f60c"; }
+.bi-volume-mute::before { content: "\f60d"; }
+.bi-volume-off-fill::before { content: "\f60e"; }
+.bi-volume-off::before { content: "\f60f"; }
+.bi-volume-up-fill::before { content: "\f610"; }
+.bi-volume-up::before { content: "\f611"; }
+.bi-vr::before { content: "\f612"; }
+.bi-wallet-fill::before { content: "\f613"; }
+.bi-wallet::before { content: "\f614"; }
+.bi-wallet2::before { content: "\f615"; }
+.bi-watch::before { content: "\f616"; }
+.bi-water::before { content: "\f617"; }
+.bi-whatsapp::before { content: "\f618"; }
+.bi-wifi-1::before { content: "\f619"; }
+.bi-wifi-2::before { content: "\f61a"; }
+.bi-wifi-off::before { content: "\f61b"; }
+.bi-wifi::before { content: "\f61c"; }
+.bi-wind::before { content: "\f61d"; }
+.bi-window-dock::before { content: "\f61e"; }
+.bi-window-sidebar::before { content: "\f61f"; }
+.bi-window::before { content: "\f620"; }
+.bi-wrench::before { content: "\f621"; }
+.bi-x-circle-fill::before { content: "\f622"; }
+.bi-x-circle::before { content: "\f623"; }
+.bi-x-diamond-fill::before { content: "\f624"; }
+.bi-x-diamond::before { content: "\f625"; }
+.bi-x-octagon-fill::before { content: "\f626"; }
+.bi-x-octagon::before { content: "\f627"; }
+.bi-x-square-fill::before { content: "\f628"; }
+.bi-x-square::before { content: "\f629"; }
+.bi-x::before { content: "\f62a"; }
+.bi-youtube::before { content: "\f62b"; }
+.bi-zoom-in::before { content: "\f62c"; }
+.bi-zoom-out::before { content: "\f62d"; }
+.bi-bank::before { content: "\f62e"; }
+.bi-bank2::before { content: "\f62f"; }
+.bi-bell-slash-fill::before { content: "\f630"; }
+.bi-bell-slash::before { content: "\f631"; }
+.bi-cash-coin::before { content: "\f632"; }
+.bi-check-lg::before { content: "\f633"; }
+.bi-coin::before { content: "\f634"; }
+.bi-currency-bitcoin::before { content: "\f635"; }
+.bi-currency-dollar::before { content: "\f636"; }
+.bi-currency-euro::before { content: "\f637"; }
+.bi-currency-exchange::before { content: "\f638"; }
+.bi-currency-pound::before { content: "\f639"; }
+.bi-currency-yen::before { content: "\f63a"; }
+.bi-dash-lg::before { content: "\f63b"; }
+.bi-exclamation-lg::before { content: "\f63c"; }
+.bi-file-earmark-pdf-fill::before { content: "\f63d"; }
+.bi-file-earmark-pdf::before { content: "\f63e"; }
+.bi-file-pdf-fill::before { content: "\f63f"; }
+.bi-file-pdf::before { content: "\f640"; }
+.bi-gender-ambiguous::before { content: "\f641"; }
+.bi-gender-female::before { content: "\f642"; }
+.bi-gender-male::before { content: "\f643"; }
+.bi-gender-trans::before { content: "\f644"; }
+.bi-headset-vr::before { content: "\f645"; }
+.bi-info-lg::before { content: "\f646"; }
+.bi-mastodon::before { content: "\f647"; }
+.bi-messenger::before { content: "\f648"; }
+.bi-piggy-bank-fill::before { content: "\f649"; }
+.bi-piggy-bank::before { content: "\f64a"; }
+.bi-pin-map-fill::before { content: "\f64b"; }
+.bi-pin-map::before { content: "\f64c"; }
+.bi-plus-lg::before { content: "\f64d"; }
+.bi-question-lg::before { content: "\f64e"; }
+.bi-recycle::before { content: "\f64f"; }
+.bi-reddit::before { content: "\f650"; }
+.bi-safe-fill::before { content: "\f651"; }
+.bi-safe2-fill::before { content: "\f652"; }
+.bi-safe2::before { content: "\f653"; }
+.bi-sd-card-fill::before { content: "\f654"; }
+.bi-sd-card::before { content: "\f655"; }
+.bi-skype::before { content: "\f656"; }
+.bi-slash-lg::before { content: "\f657"; }
+.bi-translate::before { content: "\f658"; }
+.bi-x-lg::before { content: "\f659"; }
+.bi-safe::before { content: "\f65a"; }
+.bi-apple::before { content: "\f65b"; }
+.bi-microsoft::before { content: "\f65d"; }
+.bi-windows::before { content: "\f65e"; }
+.bi-behance::before { content: "\f65c"; }
+.bi-dribbble::before { content: "\f65f"; }
+.bi-line::before { content: "\f660"; }
+.bi-medium::before { content: "\f661"; }
+.bi-paypal::before { content: "\f662"; }
+.bi-pinterest::before { content: "\f663"; }
+.bi-signal::before { content: "\f664"; }
+.bi-snapchat::before { content: "\f665"; }
+.bi-spotify::before { content: "\f666"; }
+.bi-stack-overflow::before { content: "\f667"; }
+.bi-strava::before { content: "\f668"; }
+.bi-wordpress::before { content: "\f669"; }
+.bi-vimeo::before { content: "\f66a"; }
+.bi-activity::before { content: "\f66b"; }
+.bi-easel2-fill::before { content: "\f66c"; }
+.bi-easel2::before { content: "\f66d"; }
+.bi-easel3-fill::before { content: "\f66e"; }
+.bi-easel3::before { content: "\f66f"; }
+.bi-fan::before { content: "\f670"; }
+.bi-fingerprint::before { content: "\f671"; }
+.bi-graph-down-arrow::before { content: "\f672"; }
+.bi-graph-up-arrow::before { content: "\f673"; }
+.bi-hypnotize::before { content: "\f674"; }
+.bi-magic::before { content: "\f675"; }
+.bi-person-rolodex::before { content: "\f676"; }
+.bi-person-video::before { content: "\f677"; }
+.bi-person-video2::before { content: "\f678"; }
+.bi-person-video3::before { content: "\f679"; }
+.bi-person-workspace::before { content: "\f67a"; }
+.bi-radioactive::before { content: "\f67b"; }
+.bi-webcam-fill::before { content: "\f67c"; }
+.bi-webcam::before { content: "\f67d"; }
+.bi-yin-yang::before { content: "\f67e"; }
+.bi-bandaid-fill::before { content: "\f680"; }
+.bi-bandaid::before { content: "\f681"; }
+.bi-bluetooth::before { content: "\f682"; }
+.bi-body-text::before { content: "\f683"; }
+.bi-boombox::before { content: "\f684"; }
+.bi-boxes::before { content: "\f685"; }
+.bi-dpad-fill::before { content: "\f686"; }
+.bi-dpad::before { content: "\f687"; }
+.bi-ear-fill::before { content: "\f688"; }
+.bi-ear::before { content: "\f689"; }
+.bi-envelope-check-fill::before { content: "\f68b"; }
+.bi-envelope-check::before { content: "\f68c"; }
+.bi-envelope-dash-fill::before { content: "\f68e"; }
+.bi-envelope-dash::before { content: "\f68f"; }
+.bi-envelope-exclamation-fill::before { content: "\f691"; }
+.bi-envelope-exclamation::before { content: "\f692"; }
+.bi-envelope-plus-fill::before { content: "\f693"; }
+.bi-envelope-plus::before { content: "\f694"; }
+.bi-envelope-slash-fill::before { content: "\f696"; }
+.bi-envelope-slash::before { content: "\f697"; }
+.bi-envelope-x-fill::before { content: "\f699"; }
+.bi-envelope-x::before { content: "\f69a"; }
+.bi-explicit-fill::before { content: "\f69b"; }
+.bi-explicit::before { content: "\f69c"; }
+.bi-git::before { content: "\f69d"; }
+.bi-infinity::before { content: "\f69e"; }
+.bi-list-columns-reverse::before { content: "\f69f"; }
+.bi-list-columns::before { content: "\f6a0"; }
+.bi-meta::before { content: "\f6a1"; }
+.bi-nintendo-switch::before { content: "\f6a4"; }
+.bi-pc-display-horizontal::before { content: "\f6a5"; }
+.bi-pc-display::before { content: "\f6a6"; }
+.bi-pc-horizontal::before { content: "\f6a7"; }
+.bi-pc::before { content: "\f6a8"; }
+.bi-playstation::before { content: "\f6a9"; }
+.bi-plus-slash-minus::before { content: "\f6aa"; }
+.bi-projector-fill::before { content: "\f6ab"; }
+.bi-projector::before { content: "\f6ac"; }
+.bi-qr-code-scan::before { content: "\f6ad"; }
+.bi-qr-code::before { content: "\f6ae"; }
+.bi-quora::before { content: "\f6af"; }
+.bi-quote::before { content: "\f6b0"; }
+.bi-robot::before { content: "\f6b1"; }
+.bi-send-check-fill::before { content: "\f6b2"; }
+.bi-send-check::before { content: "\f6b3"; }
+.bi-send-dash-fill::before { content: "\f6b4"; }
+.bi-send-dash::before { content: "\f6b5"; }
+.bi-send-exclamation-fill::before { content: "\f6b7"; }
+.bi-send-exclamation::before { content: "\f6b8"; }
+.bi-send-fill::before { content: "\f6b9"; }
+.bi-send-plus-fill::before { content: "\f6ba"; }
+.bi-send-plus::before { content: "\f6bb"; }
+.bi-send-slash-fill::before { content: "\f6bc"; }
+.bi-send-slash::before { content: "\f6bd"; }
+.bi-send-x-fill::before { content: "\f6be"; }
+.bi-send-x::before { content: "\f6bf"; }
+.bi-send::before { content: "\f6c0"; }
+.bi-steam::before { content: "\f6c1"; }
+.bi-terminal-dash::before { content: "\f6c3"; }
+.bi-terminal-plus::before { content: "\f6c4"; }
+.bi-terminal-split::before { content: "\f6c5"; }
+.bi-ticket-detailed-fill::before { content: "\f6c6"; }
+.bi-ticket-detailed::before { content: "\f6c7"; }
+.bi-ticket-fill::before { content: "\f6c8"; }
+.bi-ticket-perforated-fill::before { content: "\f6c9"; }
+.bi-ticket-perforated::before { content: "\f6ca"; }
+.bi-ticket::before { content: "\f6cb"; }
+.bi-tiktok::before { content: "\f6cc"; }
+.bi-window-dash::before { content: "\f6cd"; }
+.bi-window-desktop::before { content: "\f6ce"; }
+.bi-window-fullscreen::before { content: "\f6cf"; }
+.bi-window-plus::before { content: "\f6d0"; }
+.bi-window-split::before { content: "\f6d1"; }
+.bi-window-stack::before { content: "\f6d2"; }
+.bi-window-x::before { content: "\f6d3"; }
+.bi-xbox::before { content: "\f6d4"; }
+.bi-ethernet::before { content: "\f6d5"; }
+.bi-hdmi-fill::before { content: "\f6d6"; }
+.bi-hdmi::before { content: "\f6d7"; }
+.bi-usb-c-fill::before { content: "\f6d8"; }
+.bi-usb-c::before { content: "\f6d9"; }
+.bi-usb-fill::before { content: "\f6da"; }
+.bi-usb-plug-fill::before { content: "\f6db"; }
+.bi-usb-plug::before { content: "\f6dc"; }
+.bi-usb-symbol::before { content: "\f6dd"; }
+.bi-usb::before { content: "\f6de"; }
+.bi-boombox-fill::before { content: "\f6df"; }
+.bi-displayport::before { content: "\f6e1"; }
+.bi-gpu-card::before { content: "\f6e2"; }
+.bi-memory::before { content: "\f6e3"; }
+.bi-modem-fill::before { content: "\f6e4"; }
+.bi-modem::before { content: "\f6e5"; }
+.bi-motherboard-fill::before { content: "\f6e6"; }
+.bi-motherboard::before { content: "\f6e7"; }
+.bi-optical-audio-fill::before { content: "\f6e8"; }
+.bi-optical-audio::before { content: "\f6e9"; }
+.bi-pci-card::before { content: "\f6ea"; }
+.bi-router-fill::before { content: "\f6eb"; }
+.bi-router::before { content: "\f6ec"; }
+.bi-thunderbolt-fill::before { content: "\f6ef"; }
+.bi-thunderbolt::before { content: "\f6f0"; }
+.bi-usb-drive-fill::before { content: "\f6f1"; }
+.bi-usb-drive::before { content: "\f6f2"; }
+.bi-usb-micro-fill::before { content: "\f6f3"; }
+.bi-usb-micro::before { content: "\f6f4"; }
+.bi-usb-mini-fill::before { content: "\f6f5"; }
+.bi-usb-mini::before { content: "\f6f6"; }
+.bi-cloud-haze2::before { content: "\f6f7"; }
+.bi-device-hdd-fill::before { content: "\f6f8"; }
+.bi-device-hdd::before { content: "\f6f9"; }
+.bi-device-ssd-fill::before { content: "\f6fa"; }
+.bi-device-ssd::before { content: "\f6fb"; }
+.bi-displayport-fill::before { content: "\f6fc"; }
+.bi-mortarboard-fill::before { content: "\f6fd"; }
+.bi-mortarboard::before { content: "\f6fe"; }
+.bi-terminal-x::before { content: "\f6ff"; }
+.bi-arrow-through-heart-fill::before { content: "\f700"; }
+.bi-arrow-through-heart::before { content: "\f701"; }
+.bi-badge-sd-fill::before { content: "\f702"; }
+.bi-badge-sd::before { content: "\f703"; }
+.bi-bag-heart-fill::before { content: "\f704"; }
+.bi-bag-heart::before { content: "\f705"; }
+.bi-balloon-fill::before { content: "\f706"; }
+.bi-balloon-heart-fill::before { content: "\f707"; }
+.bi-balloon-heart::before { content: "\f708"; }
+.bi-balloon::before { content: "\f709"; }
+.bi-box2-fill::before { content: "\f70a"; }
+.bi-box2-heart-fill::before { content: "\f70b"; }
+.bi-box2-heart::before { content: "\f70c"; }
+.bi-box2::before { content: "\f70d"; }
+.bi-braces-asterisk::before { content: "\f70e"; }
+.bi-calendar-heart-fill::before { content: "\f70f"; }
+.bi-calendar-heart::before { content: "\f710"; }
+.bi-calendar2-heart-fill::before { content: "\f711"; }
+.bi-calendar2-heart::before { content: "\f712"; }
+.bi-chat-heart-fill::before { content: "\f713"; }
+.bi-chat-heart::before { content: "\f714"; }
+.bi-chat-left-heart-fill::before { content: "\f715"; }
+.bi-chat-left-heart::before { content: "\f716"; }
+.bi-chat-right-heart-fill::before { content: "\f717"; }
+.bi-chat-right-heart::before { content: "\f718"; }
+.bi-chat-square-heart-fill::before { content: "\f719"; }
+.bi-chat-square-heart::before { content: "\f71a"; }
+.bi-clipboard-check-fill::before { content: "\f71b"; }
+.bi-clipboard-data-fill::before { content: "\f71c"; }
+.bi-clipboard-fill::before { content: "\f71d"; }
+.bi-clipboard-heart-fill::before { content: "\f71e"; }
+.bi-clipboard-heart::before { content: "\f71f"; }
+.bi-clipboard-minus-fill::before { content: "\f720"; }
+.bi-clipboard-plus-fill::before { content: "\f721"; }
+.bi-clipboard-pulse::before { content: "\f722"; }
+.bi-clipboard-x-fill::before { content: "\f723"; }
+.bi-clipboard2-check-fill::before { content: "\f724"; }
+.bi-clipboard2-check::before { content: "\f725"; }
+.bi-clipboard2-data-fill::before { content: "\f726"; }
+.bi-clipboard2-data::before { content: "\f727"; }
+.bi-clipboard2-fill::before { content: "\f728"; }
+.bi-clipboard2-heart-fill::before { content: "\f729"; }
+.bi-clipboard2-heart::before { content: "\f72a"; }
+.bi-clipboard2-minus-fill::before { content: "\f72b"; }
+.bi-clipboard2-minus::before { content: "\f72c"; }
+.bi-clipboard2-plus-fill::before { content: "\f72d"; }
+.bi-clipboard2-plus::before { content: "\f72e"; }
+.bi-clipboard2-pulse-fill::before { content: "\f72f"; }
+.bi-clipboard2-pulse::before { content: "\f730"; }
+.bi-clipboard2-x-fill::before { content: "\f731"; }
+.bi-clipboard2-x::before { content: "\f732"; }
+.bi-clipboard2::before { content: "\f733"; }
+.bi-emoji-kiss-fill::before { content: "\f734"; }
+.bi-emoji-kiss::before { content: "\f735"; }
+.bi-envelope-heart-fill::before { content: "\f736"; }
+.bi-envelope-heart::before { content: "\f737"; }
+.bi-envelope-open-heart-fill::before { content: "\f738"; }
+.bi-envelope-open-heart::before { content: "\f739"; }
+.bi-envelope-paper-fill::before { content: "\f73a"; }
+.bi-envelope-paper-heart-fill::before { content: "\f73b"; }
+.bi-envelope-paper-heart::before { content: "\f73c"; }
+.bi-envelope-paper::before { content: "\f73d"; }
+.bi-filetype-aac::before { content: "\f73e"; }
+.bi-filetype-ai::before { content: "\f73f"; }
+.bi-filetype-bmp::before { content: "\f740"; }
+.bi-filetype-cs::before { content: "\f741"; }
+.bi-filetype-css::before { content: "\f742"; }
+.bi-filetype-csv::before { content: "\f743"; }
+.bi-filetype-doc::before { content: "\f744"; }
+.bi-filetype-docx::before { content: "\f745"; }
+.bi-filetype-exe::before { content: "\f746"; }
+.bi-filetype-gif::before { content: "\f747"; }
+.bi-filetype-heic::before { content: "\f748"; }
+.bi-filetype-html::before { content: "\f749"; }
+.bi-filetype-java::before { content: "\f74a"; }
+.bi-filetype-jpg::before { content: "\f74b"; }
+.bi-filetype-js::before { content: "\f74c"; }
+.bi-filetype-jsx::before { content: "\f74d"; }
+.bi-filetype-key::before { content: "\f74e"; }
+.bi-filetype-m4p::before { content: "\f74f"; }
+.bi-filetype-md::before { content: "\f750"; }
+.bi-filetype-mdx::before { content: "\f751"; }
+.bi-filetype-mov::before { content: "\f752"; }
+.bi-filetype-mp3::before { content: "\f753"; }
+.bi-filetype-mp4::before { content: "\f754"; }
+.bi-filetype-otf::before { content: "\f755"; }
+.bi-filetype-pdf::before { content: "\f756"; }
+.bi-filetype-php::before { content: "\f757"; }
+.bi-filetype-png::before { content: "\f758"; }
+.bi-filetype-ppt::before { content: "\f75a"; }
+.bi-filetype-psd::before { content: "\f75b"; }
+.bi-filetype-py::before { content: "\f75c"; }
+.bi-filetype-raw::before { content: "\f75d"; }
+.bi-filetype-rb::before { content: "\f75e"; }
+.bi-filetype-sass::before { content: "\f75f"; }
+.bi-filetype-scss::before { content: "\f760"; }
+.bi-filetype-sh::before { content: "\f761"; }
+.bi-filetype-svg::before { content: "\f762"; }
+.bi-filetype-tiff::before { content: "\f763"; }
+.bi-filetype-tsx::before { content: "\f764"; }
+.bi-filetype-ttf::before { content: "\f765"; }
+.bi-filetype-txt::before { content: "\f766"; }
+.bi-filetype-wav::before { content: "\f767"; }
+.bi-filetype-woff::before { content: "\f768"; }
+.bi-filetype-xls::before { content: "\f76a"; }
+.bi-filetype-xml::before { content: "\f76b"; }
+.bi-filetype-yml::before { content: "\f76c"; }
+.bi-heart-arrow::before { content: "\f76d"; }
+.bi-heart-pulse-fill::before { content: "\f76e"; }
+.bi-heart-pulse::before { content: "\f76f"; }
+.bi-heartbreak-fill::before { content: "\f770"; }
+.bi-heartbreak::before { content: "\f771"; }
+.bi-hearts::before { content: "\f772"; }
+.bi-hospital-fill::before { content: "\f773"; }
+.bi-hospital::before { content: "\f774"; }
+.bi-house-heart-fill::before { content: "\f775"; }
+.bi-house-heart::before { content: "\f776"; }
+.bi-incognito::before { content: "\f777"; }
+.bi-magnet-fill::before { content: "\f778"; }
+.bi-magnet::before { content: "\f779"; }
+.bi-person-heart::before { content: "\f77a"; }
+.bi-person-hearts::before { content: "\f77b"; }
+.bi-phone-flip::before { content: "\f77c"; }
+.bi-plugin::before { content: "\f77d"; }
+.bi-postage-fill::before { content: "\f77e"; }
+.bi-postage-heart-fill::before { content: "\f77f"; }
+.bi-postage-heart::before { content: "\f780"; }
+.bi-postage::before { content: "\f781"; }
+.bi-postcard-fill::before { content: "\f782"; }
+.bi-postcard-heart-fill::before { content: "\f783"; }
+.bi-postcard-heart::before { content: "\f784"; }
+.bi-postcard::before { content: "\f785"; }
+.bi-search-heart-fill::before { content: "\f786"; }
+.bi-search-heart::before { content: "\f787"; }
+.bi-sliders2-vertical::before { content: "\f788"; }
+.bi-sliders2::before { content: "\f789"; }
+.bi-trash3-fill::before { content: "\f78a"; }
+.bi-trash3::before { content: "\f78b"; }
+.bi-valentine::before { content: "\f78c"; }
+.bi-valentine2::before { content: "\f78d"; }
+.bi-wrench-adjustable-circle-fill::before { content: "\f78e"; }
+.bi-wrench-adjustable-circle::before { content: "\f78f"; }
+.bi-wrench-adjustable::before { content: "\f790"; }
+.bi-filetype-json::before { content: "\f791"; }
+.bi-filetype-pptx::before { content: "\f792"; }
+.bi-filetype-xlsx::before { content: "\f793"; }
+.bi-1-circle-fill::before { content: "\f796"; }
+.bi-1-circle::before { content: "\f797"; }
+.bi-1-square-fill::before { content: "\f798"; }
+.bi-1-square::before { content: "\f799"; }
+.bi-2-circle-fill::before { content: "\f79c"; }
+.bi-2-circle::before { content: "\f79d"; }
+.bi-2-square-fill::before { content: "\f79e"; }
+.bi-2-square::before { content: "\f79f"; }
+.bi-3-circle-fill::before { content: "\f7a2"; }
+.bi-3-circle::before { content: "\f7a3"; }
+.bi-3-square-fill::before { content: "\f7a4"; }
+.bi-3-square::before { content: "\f7a5"; }
+.bi-4-circle-fill::before { content: "\f7a8"; }
+.bi-4-circle::before { content: "\f7a9"; }
+.bi-4-square-fill::before { content: "\f7aa"; }
+.bi-4-square::before { content: "\f7ab"; }
+.bi-5-circle-fill::before { content: "\f7ae"; }
+.bi-5-circle::before { content: "\f7af"; }
+.bi-5-square-fill::before { content: "\f7b0"; }
+.bi-5-square::before { content: "\f7b1"; }
+.bi-6-circle-fill::before { content: "\f7b4"; }
+.bi-6-circle::before { content: "\f7b5"; }
+.bi-6-square-fill::before { content: "\f7b6"; }
+.bi-6-square::before { content: "\f7b7"; }
+.bi-7-circle-fill::before { content: "\f7ba"; }
+.bi-7-circle::before { content: "\f7bb"; }
+.bi-7-square-fill::before { content: "\f7bc"; }
+.bi-7-square::before { content: "\f7bd"; }
+.bi-8-circle-fill::before { content: "\f7c0"; }
+.bi-8-circle::before { content: "\f7c1"; }
+.bi-8-square-fill::before { content: "\f7c2"; }
+.bi-8-square::before { content: "\f7c3"; }
+.bi-9-circle-fill::before { content: "\f7c6"; }
+.bi-9-circle::before { content: "\f7c7"; }
+.bi-9-square-fill::before { content: "\f7c8"; }
+.bi-9-square::before { content: "\f7c9"; }
+.bi-airplane-engines-fill::before { content: "\f7ca"; }
+.bi-airplane-engines::before { content: "\f7cb"; }
+.bi-airplane-fill::before { content: "\f7cc"; }
+.bi-airplane::before { content: "\f7cd"; }
+.bi-alexa::before { content: "\f7ce"; }
+.bi-alipay::before { content: "\f7cf"; }
+.bi-android::before { content: "\f7d0"; }
+.bi-android2::before { content: "\f7d1"; }
+.bi-box-fill::before { content: "\f7d2"; }
+.bi-box-seam-fill::before { content: "\f7d3"; }
+.bi-browser-chrome::before { content: "\f7d4"; }
+.bi-browser-edge::before { content: "\f7d5"; }
+.bi-browser-firefox::before { content: "\f7d6"; }
+.bi-browser-safari::before { content: "\f7d7"; }
+.bi-c-circle-fill::before { content: "\f7da"; }
+.bi-c-circle::before { content: "\f7db"; }
+.bi-c-square-fill::before { content: "\f7dc"; }
+.bi-c-square::before { content: "\f7dd"; }
+.bi-capsule-pill::before { content: "\f7de"; }
+.bi-capsule::before { content: "\f7df"; }
+.bi-car-front-fill::before { content: "\f7e0"; }
+.bi-car-front::before { content: "\f7e1"; }
+.bi-cassette-fill::before { content: "\f7e2"; }
+.bi-cassette::before { content: "\f7e3"; }
+.bi-cc-circle-fill::before { content: "\f7e6"; }
+.bi-cc-circle::before { content: "\f7e7"; }
+.bi-cc-square-fill::before { content: "\f7e8"; }
+.bi-cc-square::before { content: "\f7e9"; }
+.bi-cup-hot-fill::before { content: "\f7ea"; }
+.bi-cup-hot::before { content: "\f7eb"; }
+.bi-currency-rupee::before { content: "\f7ec"; }
+.bi-dropbox::before { content: "\f7ed"; }
+.bi-escape::before { content: "\f7ee"; }
+.bi-fast-forward-btn-fill::before { content: "\f7ef"; }
+.bi-fast-forward-btn::before { content: "\f7f0"; }
+.bi-fast-forward-circle-fill::before { content: "\f7f1"; }
+.bi-fast-forward-circle::before { content: "\f7f2"; }
+.bi-fast-forward-fill::before { content: "\f7f3"; }
+.bi-fast-forward::before { content: "\f7f4"; }
+.bi-filetype-sql::before { content: "\f7f5"; }
+.bi-fire::before { content: "\f7f6"; }
+.bi-google-play::before { content: "\f7f7"; }
+.bi-h-circle-fill::before { content: "\f7fa"; }
+.bi-h-circle::before { content: "\f7fb"; }
+.bi-h-square-fill::before { content: "\f7fc"; }
+.bi-h-square::before { content: "\f7fd"; }
+.bi-indent::before { content: "\f7fe"; }
+.bi-lungs-fill::before { content: "\f7ff"; }
+.bi-lungs::before { content: "\f800"; }
+.bi-microsoft-teams::before { content: "\f801"; }
+.bi-p-circle-fill::before { content: "\f804"; }
+.bi-p-circle::before { content: "\f805"; }
+.bi-p-square-fill::before { content: "\f806"; }
+.bi-p-square::before { content: "\f807"; }
+.bi-pass-fill::before { content: "\f808"; }
+.bi-pass::before { content: "\f809"; }
+.bi-prescription::before { content: "\f80a"; }
+.bi-prescription2::before { content: "\f80b"; }
+.bi-r-circle-fill::before { content: "\f80e"; }
+.bi-r-circle::before { content: "\f80f"; }
+.bi-r-square-fill::before { content: "\f810"; }
+.bi-r-square::before { content: "\f811"; }
+.bi-repeat-1::before { content: "\f812"; }
+.bi-repeat::before { content: "\f813"; }
+.bi-rewind-btn-fill::before { content: "\f814"; }
+.bi-rewind-btn::before { content: "\f815"; }
+.bi-rewind-circle-fill::before { content: "\f816"; }
+.bi-rewind-circle::before { content: "\f817"; }
+.bi-rewind-fill::before { content: "\f818"; }
+.bi-rewind::before { content: "\f819"; }
+.bi-train-freight-front-fill::before { content: "\f81a"; }
+.bi-train-freight-front::before { content: "\f81b"; }
+.bi-train-front-fill::before { content: "\f81c"; }
+.bi-train-front::before { content: "\f81d"; }
+.bi-train-lightrail-front-fill::before { content: "\f81e"; }
+.bi-train-lightrail-front::before { content: "\f81f"; }
+.bi-truck-front-fill::before { content: "\f820"; }
+.bi-truck-front::before { content: "\f821"; }
+.bi-ubuntu::before { content: "\f822"; }
+.bi-unindent::before { content: "\f823"; }
+.bi-unity::before { content: "\f824"; }
+.bi-universal-access-circle::before { content: "\f825"; }
+.bi-universal-access::before { content: "\f826"; }
+.bi-virus::before { content: "\f827"; }
+.bi-virus2::before { content: "\f828"; }
+.bi-wechat::before { content: "\f829"; }
+.bi-yelp::before { content: "\f82a"; }
+.bi-sign-stop-fill::before { content: "\f82b"; }
+.bi-sign-stop-lights-fill::before { content: "\f82c"; }
+.bi-sign-stop-lights::before { content: "\f82d"; }
+.bi-sign-stop::before { content: "\f82e"; }
+.bi-sign-turn-left-fill::before { content: "\f82f"; }
+.bi-sign-turn-left::before { content: "\f830"; }
+.bi-sign-turn-right-fill::before { content: "\f831"; }
+.bi-sign-turn-right::before { content: "\f832"; }
+.bi-sign-turn-slight-left-fill::before { content: "\f833"; }
+.bi-sign-turn-slight-left::before { content: "\f834"; }
+.bi-sign-turn-slight-right-fill::before { content: "\f835"; }
+.bi-sign-turn-slight-right::before { content: "\f836"; }
+.bi-sign-yield-fill::before { content: "\f837"; }
+.bi-sign-yield::before { content: "\f838"; }
+.bi-ev-station-fill::before { content: "\f839"; }
+.bi-ev-station::before { content: "\f83a"; }
+.bi-fuel-pump-diesel-fill::before { content: "\f83b"; }
+.bi-fuel-pump-diesel::before { content: "\f83c"; }
+.bi-fuel-pump-fill::before { content: "\f83d"; }
+.bi-fuel-pump::before { content: "\f83e"; }
+.bi-0-circle-fill::before { content: "\f83f"; }
+.bi-0-circle::before { content: "\f840"; }
+.bi-0-square-fill::before { content: "\f841"; }
+.bi-0-square::before { content: "\f842"; }
+.bi-rocket-fill::before { content: "\f843"; }
+.bi-rocket-takeoff-fill::before { content: "\f844"; }
+.bi-rocket-takeoff::before { content: "\f845"; }
+.bi-rocket::before { content: "\f846"; }
+.bi-stripe::before { content: "\f847"; }
+.bi-subscript::before { content: "\f848"; }
+.bi-superscript::before { content: "\f849"; }
+.bi-trello::before { content: "\f84a"; }
+.bi-envelope-at-fill::before { content: "\f84b"; }
+.bi-envelope-at::before { content: "\f84c"; }
+.bi-regex::before { content: "\f84d"; }
+.bi-text-wrap::before { content: "\f84e"; }
+.bi-sign-dead-end-fill::before { content: "\f84f"; }
+.bi-sign-dead-end::before { content: "\f850"; }
+.bi-sign-do-not-enter-fill::before { content: "\f851"; }
+.bi-sign-do-not-enter::before { content: "\f852"; }
+.bi-sign-intersection-fill::before { content: "\f853"; }
+.bi-sign-intersection-side-fill::before { content: "\f854"; }
+.bi-sign-intersection-side::before { content: "\f855"; }
+.bi-sign-intersection-t-fill::before { content: "\f856"; }
+.bi-sign-intersection-t::before { content: "\f857"; }
+.bi-sign-intersection-y-fill::before { content: "\f858"; }
+.bi-sign-intersection-y::before { content: "\f859"; }
+.bi-sign-intersection::before { content: "\f85a"; }
+.bi-sign-merge-left-fill::before { content: "\f85b"; }
+.bi-sign-merge-left::before { content: "\f85c"; }
+.bi-sign-merge-right-fill::before { content: "\f85d"; }
+.bi-sign-merge-right::before { content: "\f85e"; }
+.bi-sign-no-left-turn-fill::before { content: "\f85f"; }
+.bi-sign-no-left-turn::before { content: "\f860"; }
+.bi-sign-no-parking-fill::before { content: "\f861"; }
+.bi-sign-no-parking::before { content: "\f862"; }
+.bi-sign-no-right-turn-fill::before { content: "\f863"; }
+.bi-sign-no-right-turn::before { content: "\f864"; }
+.bi-sign-railroad-fill::before { content: "\f865"; }
+.bi-sign-railroad::before { content: "\f866"; }
+.bi-building-add::before { content: "\f867"; }
+.bi-building-check::before { content: "\f868"; }
+.bi-building-dash::before { content: "\f869"; }
+.bi-building-down::before { content: "\f86a"; }
+.bi-building-exclamation::before { content: "\f86b"; }
+.bi-building-fill-add::before { content: "\f86c"; }
+.bi-building-fill-check::before { content: "\f86d"; }
+.bi-building-fill-dash::before { content: "\f86e"; }
+.bi-building-fill-down::before { content: "\f86f"; }
+.bi-building-fill-exclamation::before { content: "\f870"; }
+.bi-building-fill-gear::before { content: "\f871"; }
+.bi-building-fill-lock::before { content: "\f872"; }
+.bi-building-fill-slash::before { content: "\f873"; }
+.bi-building-fill-up::before { content: "\f874"; }
+.bi-building-fill-x::before { content: "\f875"; }
+.bi-building-fill::before { content: "\f876"; }
+.bi-building-gear::before { content: "\f877"; }
+.bi-building-lock::before { content: "\f878"; }
+.bi-building-slash::before { content: "\f879"; }
+.bi-building-up::before { content: "\f87a"; }
+.bi-building-x::before { content: "\f87b"; }
+.bi-buildings-fill::before { content: "\f87c"; }
+.bi-buildings::before { content: "\f87d"; }
+.bi-bus-front-fill::before { content: "\f87e"; }
+.bi-bus-front::before { content: "\f87f"; }
+.bi-ev-front-fill::before { content: "\f880"; }
+.bi-ev-front::before { content: "\f881"; }
+.bi-globe-americas::before { content: "\f882"; }
+.bi-globe-asia-australia::before { content: "\f883"; }
+.bi-globe-central-south-asia::before { content: "\f884"; }
+.bi-globe-europe-africa::before { content: "\f885"; }
+.bi-house-add-fill::before { content: "\f886"; }
+.bi-house-add::before { content: "\f887"; }
+.bi-house-check-fill::before { content: "\f888"; }
+.bi-house-check::before { content: "\f889"; }
+.bi-house-dash-fill::before { content: "\f88a"; }
+.bi-house-dash::before { content: "\f88b"; }
+.bi-house-down-fill::before { content: "\f88c"; }
+.bi-house-down::before { content: "\f88d"; }
+.bi-house-exclamation-fill::before { content: "\f88e"; }
+.bi-house-exclamation::before { content: "\f88f"; }
+.bi-house-gear-fill::before { content: "\f890"; }
+.bi-house-gear::before { content: "\f891"; }
+.bi-house-lock-fill::before { content: "\f892"; }
+.bi-house-lock::before { content: "\f893"; }
+.bi-house-slash-fill::before { content: "\f894"; }
+.bi-house-slash::before { content: "\f895"; }
+.bi-house-up-fill::before { content: "\f896"; }
+.bi-house-up::before { content: "\f897"; }
+.bi-house-x-fill::before { content: "\f898"; }
+.bi-house-x::before { content: "\f899"; }
+.bi-person-add::before { content: "\f89a"; }
+.bi-person-down::before { content: "\f89b"; }
+.bi-person-exclamation::before { content: "\f89c"; }
+.bi-person-fill-add::before { content: "\f89d"; }
+.bi-person-fill-check::before { content: "\f89e"; }
+.bi-person-fill-dash::before { content: "\f89f"; }
+.bi-person-fill-down::before { content: "\f8a0"; }
+.bi-person-fill-exclamation::before { content: "\f8a1"; }
+.bi-person-fill-gear::before { content: "\f8a2"; }
+.bi-person-fill-lock::before { content: "\f8a3"; }
+.bi-person-fill-slash::before { content: "\f8a4"; }
+.bi-person-fill-up::before { content: "\f8a5"; }
+.bi-person-fill-x::before { content: "\f8a6"; }
+.bi-person-gear::before { content: "\f8a7"; }
+.bi-person-lock::before { content: "\f8a8"; }
+.bi-person-slash::before { content: "\f8a9"; }
+.bi-person-up::before { content: "\f8aa"; }
+.bi-scooter::before { content: "\f8ab"; }
+.bi-taxi-front-fill::before { content: "\f8ac"; }
+.bi-taxi-front::before { content: "\f8ad"; }
+.bi-amd::before { content: "\f8ae"; }
+.bi-database-add::before { content: "\f8af"; }
+.bi-database-check::before { content: "\f8b0"; }
+.bi-database-dash::before { content: "\f8b1"; }
+.bi-database-down::before { content: "\f8b2"; }
+.bi-database-exclamation::before { content: "\f8b3"; }
+.bi-database-fill-add::before { content: "\f8b4"; }
+.bi-database-fill-check::before { content: "\f8b5"; }
+.bi-database-fill-dash::before { content: "\f8b6"; }
+.bi-database-fill-down::before { content: "\f8b7"; }
+.bi-database-fill-exclamation::before { content: "\f8b8"; }
+.bi-database-fill-gear::before { content: "\f8b9"; }
+.bi-database-fill-lock::before { content: "\f8ba"; }
+.bi-database-fill-slash::before { content: "\f8bb"; }
+.bi-database-fill-up::before { content: "\f8bc"; }
+.bi-database-fill-x::before { content: "\f8bd"; }
+.bi-database-fill::before { content: "\f8be"; }
+.bi-database-gear::before { content: "\f8bf"; }
+.bi-database-lock::before { content: "\f8c0"; }
+.bi-database-slash::before { content: "\f8c1"; }
+.bi-database-up::before { content: "\f8c2"; }
+.bi-database-x::before { content: "\f8c3"; }
+.bi-database::before { content: "\f8c4"; }
+.bi-houses-fill::before { content: "\f8c5"; }
+.bi-houses::before { content: "\f8c6"; }
+.bi-nvidia::before { content: "\f8c7"; }
+.bi-person-vcard-fill::before { content: "\f8c8"; }
+.bi-person-vcard::before { content: "\f8c9"; }
+.bi-sina-weibo::before { content: "\f8ca"; }
+.bi-tencent-qq::before { content: "\f8cb"; }
+.bi-wikipedia::before { content: "\f8cc"; }
+.bi-alphabet-uppercase::before { content: "\f2a5"; }
+.bi-alphabet::before { content: "\f68a"; }
+.bi-amazon::before { content: "\f68d"; }
+.bi-arrows-collapse-vertical::before { content: "\f690"; }
+.bi-arrows-expand-vertical::before { content: "\f695"; }
+.bi-arrows-vertical::before { content: "\f698"; }
+.bi-arrows::before { content: "\f6a2"; }
+.bi-ban-fill::before { content: "\f6a3"; }
+.bi-ban::before { content: "\f6b6"; }
+.bi-bing::before { content: "\f6c2"; }
+.bi-cake::before { content: "\f6e0"; }
+.bi-cake2::before { content: "\f6ed"; }
+.bi-cookie::before { content: "\f6ee"; }
+.bi-copy::before { content: "\f759"; }
+.bi-crosshair::before { content: "\f769"; }
+.bi-crosshair2::before { content: "\f794"; }
+.bi-emoji-astonished-fill::before { content: "\f795"; }
+.bi-emoji-astonished::before { content: "\f79a"; }
+.bi-emoji-grimace-fill::before { content: "\f79b"; }
+.bi-emoji-grimace::before { content: "\f7a0"; }
+.bi-emoji-grin-fill::before { content: "\f7a1"; }
+.bi-emoji-grin::before { content: "\f7a6"; }
+.bi-emoji-surprise-fill::before { content: "\f7a7"; }
+.bi-emoji-surprise::before { content: "\f7ac"; }
+.bi-emoji-tear-fill::before { content: "\f7ad"; }
+.bi-emoji-tear::before { content: "\f7b2"; }
+.bi-envelope-arrow-down-fill::before { content: "\f7b3"; }
+.bi-envelope-arrow-down::before { content: "\f7b8"; }
+.bi-envelope-arrow-up-fill::before { content: "\f7b9"; }
+.bi-envelope-arrow-up::before { content: "\f7be"; }
+.bi-feather::before { content: "\f7bf"; }
+.bi-feather2::before { content: "\f7c4"; }
+.bi-floppy-fill::before { content: "\f7c5"; }
+.bi-floppy::before { content: "\f7d8"; }
+.bi-floppy2-fill::before { content: "\f7d9"; }
+.bi-floppy2::before { content: "\f7e4"; }
+.bi-gitlab::before { content: "\f7e5"; }
+.bi-highlighter::before { content: "\f7f8"; }
+.bi-marker-tip::before { content: "\f802"; }
+.bi-nvme-fill::before { content: "\f803"; }
+.bi-nvme::before { content: "\f80c"; }
+.bi-opencollective::before { content: "\f80d"; }
+.bi-pci-card-network::before { content: "\f8cd"; }
+.bi-pci-card-sound::before { content: "\f8ce"; }
+.bi-radar::before { content: "\f8cf"; }
+.bi-send-arrow-down-fill::before { content: "\f8d0"; }
+.bi-send-arrow-down::before { content: "\f8d1"; }
+.bi-send-arrow-up-fill::before { content: "\f8d2"; }
+.bi-send-arrow-up::before { content: "\f8d3"; }
+.bi-sim-slash-fill::before { content: "\f8d4"; }
+.bi-sim-slash::before { content: "\f8d5"; }
+.bi-sourceforge::before { content: "\f8d6"; }
+.bi-substack::before { content: "\f8d7"; }
+.bi-threads-fill::before { content: "\f8d8"; }
+.bi-threads::before { content: "\f8d9"; }
+.bi-transparency::before { content: "\f8da"; }
+.bi-twitter-x::before { content: "\f8db"; }
+.bi-type-h4::before { content: "\f8dc"; }
+.bi-type-h5::before { content: "\f8dd"; }
+.bi-type-h6::before { content: "\f8de"; }
+.bi-backpack-fill::before { content: "\f8df"; }
+.bi-backpack::before { content: "\f8e0"; }
+.bi-backpack2-fill::before { content: "\f8e1"; }
+.bi-backpack2::before { content: "\f8e2"; }
+.bi-backpack3-fill::before { content: "\f8e3"; }
+.bi-backpack3::before { content: "\f8e4"; }
+.bi-backpack4-fill::before { content: "\f8e5"; }
+.bi-backpack4::before { content: "\f8e6"; }
+.bi-brilliance::before { content: "\f8e7"; }
+.bi-cake-fill::before { content: "\f8e8"; }
+.bi-cake2-fill::before { content: "\f8e9"; }
+.bi-duffle-fill::before { content: "\f8ea"; }
+.bi-duffle::before { content: "\f8eb"; }
+.bi-exposure::before { content: "\f8ec"; }
+.bi-gender-neuter::before { content: "\f8ed"; }
+.bi-highlights::before { content: "\f8ee"; }
+.bi-luggage-fill::before { content: "\f8ef"; }
+.bi-luggage::before { content: "\f8f0"; }
+.bi-mailbox-flag::before { content: "\f8f1"; }
+.bi-mailbox2-flag::before { content: "\f8f2"; }
+.bi-noise-reduction::before { content: "\f8f3"; }
+.bi-passport-fill::before { content: "\f8f4"; }
+.bi-passport::before { content: "\f8f5"; }
+.bi-person-arms-up::before { content: "\f8f6"; }
+.bi-person-raised-hand::before { content: "\f8f7"; }
+.bi-person-standing-dress::before { content: "\f8f8"; }
+.bi-person-standing::before { content: "\f8f9"; }
+.bi-person-walking::before { content: "\f8fa"; }
+.bi-person-wheelchair::before { content: "\f8fb"; }
+.bi-shadows::before { content: "\f8fc"; }
+.bi-suitcase-fill::before { content: "\f8fd"; }
+.bi-suitcase-lg-fill::before { content: "\f8fe"; }
+.bi-suitcase-lg::before { content: "\f8ff"; }
+.bi-suitcase::before { content: "\f900"; }
+.bi-suitcase2-fill::before { content: "\f901"; }
+.bi-suitcase2::before { content: "\f902"; }
+.bi-vignette::before { content: "\f903"; }
diff --git a/1 PA Decline/article ready_files/libs/bootstrap/bootstrap-icons.woff b/1 PA Decline/article ready_files/libs/bootstrap/bootstrap-icons.woff
new file mode 100644
index 0000000..dbeeb05
Binary files /dev/null and b/1 PA Decline/article ready_files/libs/bootstrap/bootstrap-icons.woff differ
diff --git a/1 PA Decline/article ready_files/libs/bootstrap/bootstrap.min.css b/1 PA Decline/article ready_files/libs/bootstrap/bootstrap.min.css
new file mode 100644
index 0000000..0946f19
--- /dev/null
+++ b/1 PA Decline/article ready_files/libs/bootstrap/bootstrap.min.css
@@ -0,0 +1,12 @@
+/*!
+ * Bootstrap v5.3.1 (https://getbootstrap.com/)
+ * Copyright 2011-2023 The Bootstrap Authors
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ */:root,[data-bs-theme=light]{--bs-blue: #0d6efd;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #d63384;--bs-red: #dc3545;--bs-orange: #fd7e14;--bs-yellow: #ffc107;--bs-green: #198754;--bs-teal: #20c997;--bs-cyan: #0dcaf0;--bs-black: #000;--bs-white: #ffffff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-default: #dee2e6;--bs-primary: #0d6efd;--bs-secondary: #6c757d;--bs-success: #198754;--bs-info: #0dcaf0;--bs-warning: #ffc107;--bs-danger: #dc3545;--bs-light: #f8f9fa;--bs-dark: #212529;--bs-default-rgb: 222, 226, 230;--bs-primary-rgb: 13, 110, 253;--bs-secondary-rgb: 108, 117, 125;--bs-success-rgb: 25, 135, 84;--bs-info-rgb: 13, 202, 240;--bs-warning-rgb: 255, 193, 7;--bs-danger-rgb: 220, 53, 69;--bs-light-rgb: 248, 249, 250;--bs-dark-rgb: 33, 37, 41;--bs-primary-text-emphasis: #052c65;--bs-secondary-text-emphasis: #2b2f32;--bs-success-text-emphasis: #0a3622;--bs-info-text-emphasis: #055160;--bs-warning-text-emphasis: #664d03;--bs-danger-text-emphasis: #58151c;--bs-light-text-emphasis: #495057;--bs-dark-text-emphasis: #495057;--bs-primary-bg-subtle: #cfe2ff;--bs-secondary-bg-subtle: #e2e3e5;--bs-success-bg-subtle: #d1e7dd;--bs-info-bg-subtle: #cff4fc;--bs-warning-bg-subtle: #fff3cd;--bs-danger-bg-subtle: #f8d7da;--bs-light-bg-subtle: #fcfcfd;--bs-dark-bg-subtle: #ced4da;--bs-primary-border-subtle: #9ec5fe;--bs-secondary-border-subtle: #c4c8cb;--bs-success-border-subtle: #a3cfbb;--bs-info-border-subtle: #9eeaf9;--bs-warning-border-subtle: #ffe69c;--bs-danger-border-subtle: #f1aeb5;--bs-light-border-subtle: #e9ecef;--bs-dark-border-subtle: #adb5bd;--bs-white-rgb: 255, 255, 255;--bs-black-rgb: 0, 0, 0;--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-root-font-size: 17px;--bs-body-font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-body-font-size:1rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-color-rgb: 33, 37, 41;--bs-body-bg: #ffffff;--bs-body-bg-rgb: 255, 255, 255;--bs-emphasis-color: #000;--bs-emphasis-color-rgb: 0, 0, 0;--bs-secondary-color: rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb: 33, 37, 41;--bs-secondary-bg: #e9ecef;--bs-secondary-bg-rgb: 233, 236, 239;--bs-tertiary-color: rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb: 33, 37, 41;--bs-tertiary-bg: #f8f9fa;--bs-tertiary-bg-rgb: 248, 249, 250;--bs-heading-color: inherit;--bs-link-color: #0d6efd;--bs-link-color-rgb: 13, 110, 253;--bs-link-decoration: underline;--bs-link-hover-color: #0a58ca;--bs-link-hover-color-rgb: 10, 88, 202;--bs-code-color: #7d12ba;--bs-highlight-bg: #fff3cd;--bs-border-width: 1px;--bs-border-style: solid;--bs-border-color: #dee2e6;--bs-border-color-translucent: rgba(0, 0, 0, 0.175);--bs-border-radius: 0.375rem;--bs-border-radius-sm: 0.25rem;--bs-border-radius-lg: 0.5rem;--bs-border-radius-xl: 1rem;--bs-border-radius-xxl: 2rem;--bs-border-radius-2xl: var(--bs-border-radius-xxl);--bs-border-radius-pill: 50rem;--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width: 0.25rem;--bs-focus-ring-opacity: 0.25;--bs-focus-ring-color: rgba(13, 110, 253, 0.25);--bs-form-valid-color: #198754;--bs-form-valid-border-color: #198754;--bs-form-invalid-color: #dc3545;--bs-form-invalid-border-color: #dc3545}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color: #dee2e6;--bs-body-color-rgb: 222, 226, 230;--bs-body-bg: #212529;--bs-body-bg-rgb: 33, 37, 41;--bs-emphasis-color: #ffffff;--bs-emphasis-color-rgb: 255, 255, 255;--bs-secondary-color: rgba(222, 226, 230, 0.75);--bs-secondary-color-rgb: 222, 226, 230;--bs-secondary-bg: #343a40;--bs-secondary-bg-rgb: 52, 58, 64;--bs-tertiary-color: rgba(222, 226, 230, 0.5);--bs-tertiary-color-rgb: 222, 226, 230;--bs-tertiary-bg: #2b3035;--bs-tertiary-bg-rgb: 43, 48, 53;--bs-primary-text-emphasis: #6ea8fe;--bs-secondary-text-emphasis: #a7acb1;--bs-success-text-emphasis: #75b798;--bs-info-text-emphasis: #6edff6;--bs-warning-text-emphasis: #ffda6a;--bs-danger-text-emphasis: #ea868f;--bs-light-text-emphasis: #f8f9fa;--bs-dark-text-emphasis: #dee2e6;--bs-primary-bg-subtle: #031633;--bs-secondary-bg-subtle: #161719;--bs-success-bg-subtle: #051b11;--bs-info-bg-subtle: #032830;--bs-warning-bg-subtle: #332701;--bs-danger-bg-subtle: #2c0b0e;--bs-light-bg-subtle: #343a40;--bs-dark-bg-subtle: #1a1d20;--bs-primary-border-subtle: #084298;--bs-secondary-border-subtle: #41464b;--bs-success-border-subtle: #0f5132;--bs-info-border-subtle: #087990;--bs-warning-border-subtle: #997404;--bs-danger-border-subtle: #842029;--bs-light-border-subtle: #495057;--bs-dark-border-subtle: #343a40;--bs-heading-color: inherit;--bs-link-color: #6ea8fe;--bs-link-hover-color: #8bb9fe;--bs-link-color-rgb: 110, 168, 254;--bs-link-hover-color-rgb: 139, 185, 254;--bs-code-color: white;--bs-border-color: #495057;--bs-border-color-translucent: rgba(255, 255, 255, 0.15);--bs-form-valid-color: #75b798;--bs-form-valid-border-color: #75b798;--bs-form-invalid-color: #ea868f;--bs-form-invalid-border-color: #ea868f}*,*::before,*::after{box-sizing:border-box}:root{font-size:var(--bs-root-font-size)}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}hr{margin:1rem 0;color:inherit;border:0;border-top:1px solid;opacity:.25}h6,.h6,h5,.h5,h4,.h4,h3,.h3,h2,.h2,h1,.h1{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color)}h1,.h1{font-size:calc(1.325rem + 0.9vw)}@media(min-width: 1200px){h1,.h1{font-size:2rem}}h2,.h2{font-size:calc(1.29rem + 0.48vw)}@media(min-width: 1200px){h2,.h2{font-size:1.65rem}}h3,.h3{font-size:calc(1.27rem + 0.24vw)}@media(min-width: 1200px){h3,.h3{font-size:1.45rem}}h4,.h4{font-size:1.25rem}h5,.h5{font-size:1.1rem}h6,.h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{text-decoration:underline dotted;-webkit-text-decoration:underline dotted;-moz-text-decoration:underline dotted;-ms-text-decoration:underline dotted;-o-text-decoration:underline dotted;cursor:help;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem;padding:.625rem 1.25rem;border-left:.25rem solid #e9ecef}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}b,strong{font-weight:bolder}small,.small{font-size:0.875em}mark,.mark{padding:.1875em;background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:0.75em;line-height:0;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}a{color:rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));text-decoration:underline;-webkit-text-decoration:underline;-moz-text-decoration:underline;-ms-text-decoration:underline;-o-text-decoration:underline}a:hover{--bs-link-color-rgb: var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:0.875em;color:#000;background-color:#f8f9fa;padding:.5rem;border:1px solid var(--bs-border-color, #dee2e6);border-radius:.375rem}pre code{background-color:rgba(0,0,0,0);font-size:inherit;color:inherit;word-break:normal}code{font-size:0.875em;color:var(--bs-code-color);background-color:#f8f9fa;border-radius:.375rem;padding:.125rem .25rem;word-wrap:break-word}a>code{color:inherit}kbd{padding:.4rem .4rem;font-size:0.875em;color:#fff;background-color:#212529;border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:rgba(33,37,41,.75);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}thead,tbody,tfoot,tr,td,th{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none !important}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button:not(:disabled),[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + 0.3vw);line-height:inherit}@media(min-width: 1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none !important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:0.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:0.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.375rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:0.875em;color:rgba(33,37,41,.75)}.container,.container-fluid,.container-xxl,.container-xl,.container-lg,.container-md,.container-sm{--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;width:100%;padding-right:calc(var(--bs-gutter-x)*.5);padding-left:calc(var(--bs-gutter-x)*.5);margin-right:auto;margin-left:auto}@media(min-width: 576px){.container-sm,.container{max-width:540px}}@media(min-width: 768px){.container-md,.container-sm,.container{max-width:720px}}@media(min-width: 992px){.container-lg,.container-md,.container-sm,.container{max-width:960px}}@media(min-width: 1200px){.container-xl,.container-lg,.container-md,.container-sm,.container{max-width:1140px}}@media(min-width: 1400px){.container-xxl,.container-xl,.container-lg,.container-md,.container-sm,.container{max-width:1320px}}:root{--bs-breakpoint-xs: 0;--bs-breakpoint-sm: 576px;--bs-breakpoint-md: 768px;--bs-breakpoint-lg: 992px;--bs-breakpoint-xl: 1200px;--bs-breakpoint-xxl: 1400px}.grid{display:grid;grid-template-rows:repeat(var(--bs-rows, 1), 1fr);grid-template-columns:repeat(var(--bs-columns, 12), 1fr);gap:var(--bs-gap, 1.5rem)}.grid .g-col-1{grid-column:auto/span 1}.grid .g-col-2{grid-column:auto/span 2}.grid .g-col-3{grid-column:auto/span 3}.grid .g-col-4{grid-column:auto/span 4}.grid .g-col-5{grid-column:auto/span 5}.grid .g-col-6{grid-column:auto/span 6}.grid .g-col-7{grid-column:auto/span 7}.grid .g-col-8{grid-column:auto/span 8}.grid .g-col-9{grid-column:auto/span 9}.grid .g-col-10{grid-column:auto/span 10}.grid .g-col-11{grid-column:auto/span 11}.grid .g-col-12{grid-column:auto/span 12}.grid .g-start-1{grid-column-start:1}.grid .g-start-2{grid-column-start:2}.grid .g-start-3{grid-column-start:3}.grid .g-start-4{grid-column-start:4}.grid .g-start-5{grid-column-start:5}.grid .g-start-6{grid-column-start:6}.grid .g-start-7{grid-column-start:7}.grid .g-start-8{grid-column-start:8}.grid .g-start-9{grid-column-start:9}.grid .g-start-10{grid-column-start:10}.grid .g-start-11{grid-column-start:11}@media(min-width: 576px){.grid .g-col-sm-1{grid-column:auto/span 1}.grid .g-col-sm-2{grid-column:auto/span 2}.grid .g-col-sm-3{grid-column:auto/span 3}.grid .g-col-sm-4{grid-column:auto/span 4}.grid .g-col-sm-5{grid-column:auto/span 5}.grid .g-col-sm-6{grid-column:auto/span 6}.grid .g-col-sm-7{grid-column:auto/span 7}.grid .g-col-sm-8{grid-column:auto/span 8}.grid .g-col-sm-9{grid-column:auto/span 9}.grid .g-col-sm-10{grid-column:auto/span 10}.grid .g-col-sm-11{grid-column:auto/span 11}.grid .g-col-sm-12{grid-column:auto/span 12}.grid .g-start-sm-1{grid-column-start:1}.grid .g-start-sm-2{grid-column-start:2}.grid .g-start-sm-3{grid-column-start:3}.grid .g-start-sm-4{grid-column-start:4}.grid .g-start-sm-5{grid-column-start:5}.grid .g-start-sm-6{grid-column-start:6}.grid .g-start-sm-7{grid-column-start:7}.grid .g-start-sm-8{grid-column-start:8}.grid .g-start-sm-9{grid-column-start:9}.grid .g-start-sm-10{grid-column-start:10}.grid .g-start-sm-11{grid-column-start:11}}@media(min-width: 768px){.grid .g-col-md-1{grid-column:auto/span 1}.grid .g-col-md-2{grid-column:auto/span 2}.grid .g-col-md-3{grid-column:auto/span 3}.grid .g-col-md-4{grid-column:auto/span 4}.grid .g-col-md-5{grid-column:auto/span 5}.grid .g-col-md-6{grid-column:auto/span 6}.grid .g-col-md-7{grid-column:auto/span 7}.grid .g-col-md-8{grid-column:auto/span 8}.grid .g-col-md-9{grid-column:auto/span 9}.grid .g-col-md-10{grid-column:auto/span 10}.grid .g-col-md-11{grid-column:auto/span 11}.grid .g-col-md-12{grid-column:auto/span 12}.grid .g-start-md-1{grid-column-start:1}.grid .g-start-md-2{grid-column-start:2}.grid .g-start-md-3{grid-column-start:3}.grid .g-start-md-4{grid-column-start:4}.grid .g-start-md-5{grid-column-start:5}.grid .g-start-md-6{grid-column-start:6}.grid .g-start-md-7{grid-column-start:7}.grid .g-start-md-8{grid-column-start:8}.grid .g-start-md-9{grid-column-start:9}.grid .g-start-md-10{grid-column-start:10}.grid .g-start-md-11{grid-column-start:11}}@media(min-width: 992px){.grid .g-col-lg-1{grid-column:auto/span 1}.grid .g-col-lg-2{grid-column:auto/span 2}.grid .g-col-lg-3{grid-column:auto/span 3}.grid .g-col-lg-4{grid-column:auto/span 4}.grid .g-col-lg-5{grid-column:auto/span 5}.grid .g-col-lg-6{grid-column:auto/span 6}.grid .g-col-lg-7{grid-column:auto/span 7}.grid .g-col-lg-8{grid-column:auto/span 8}.grid .g-col-lg-9{grid-column:auto/span 9}.grid .g-col-lg-10{grid-column:auto/span 10}.grid .g-col-lg-11{grid-column:auto/span 11}.grid .g-col-lg-12{grid-column:auto/span 12}.grid .g-start-lg-1{grid-column-start:1}.grid .g-start-lg-2{grid-column-start:2}.grid .g-start-lg-3{grid-column-start:3}.grid .g-start-lg-4{grid-column-start:4}.grid .g-start-lg-5{grid-column-start:5}.grid .g-start-lg-6{grid-column-start:6}.grid .g-start-lg-7{grid-column-start:7}.grid .g-start-lg-8{grid-column-start:8}.grid .g-start-lg-9{grid-column-start:9}.grid .g-start-lg-10{grid-column-start:10}.grid .g-start-lg-11{grid-column-start:11}}@media(min-width: 1200px){.grid .g-col-xl-1{grid-column:auto/span 1}.grid .g-col-xl-2{grid-column:auto/span 2}.grid .g-col-xl-3{grid-column:auto/span 3}.grid .g-col-xl-4{grid-column:auto/span 4}.grid .g-col-xl-5{grid-column:auto/span 5}.grid .g-col-xl-6{grid-column:auto/span 6}.grid .g-col-xl-7{grid-column:auto/span 7}.grid .g-col-xl-8{grid-column:auto/span 8}.grid .g-col-xl-9{grid-column:auto/span 9}.grid .g-col-xl-10{grid-column:auto/span 10}.grid .g-col-xl-11{grid-column:auto/span 11}.grid .g-col-xl-12{grid-column:auto/span 12}.grid .g-start-xl-1{grid-column-start:1}.grid .g-start-xl-2{grid-column-start:2}.grid .g-start-xl-3{grid-column-start:3}.grid .g-start-xl-4{grid-column-start:4}.grid .g-start-xl-5{grid-column-start:5}.grid .g-start-xl-6{grid-column-start:6}.grid .g-start-xl-7{grid-column-start:7}.grid .g-start-xl-8{grid-column-start:8}.grid .g-start-xl-9{grid-column-start:9}.grid .g-start-xl-10{grid-column-start:10}.grid .g-start-xl-11{grid-column-start:11}}@media(min-width: 1400px){.grid .g-col-xxl-1{grid-column:auto/span 1}.grid .g-col-xxl-2{grid-column:auto/span 2}.grid .g-col-xxl-3{grid-column:auto/span 3}.grid .g-col-xxl-4{grid-column:auto/span 4}.grid .g-col-xxl-5{grid-column:auto/span 5}.grid .g-col-xxl-6{grid-column:auto/span 6}.grid .g-col-xxl-7{grid-column:auto/span 7}.grid .g-col-xxl-8{grid-column:auto/span 8}.grid .g-col-xxl-9{grid-column:auto/span 9}.grid .g-col-xxl-10{grid-column:auto/span 10}.grid .g-col-xxl-11{grid-column:auto/span 11}.grid .g-col-xxl-12{grid-column:auto/span 12}.grid .g-start-xxl-1{grid-column-start:1}.grid .g-start-xxl-2{grid-column-start:2}.grid .g-start-xxl-3{grid-column-start:3}.grid .g-start-xxl-4{grid-column-start:4}.grid .g-start-xxl-5{grid-column-start:5}.grid .g-start-xxl-6{grid-column-start:6}.grid .g-start-xxl-7{grid-column-start:7}.grid .g-start-xxl-8{grid-column-start:8}.grid .g-start-xxl-9{grid-column-start:9}.grid .g-start-xxl-10{grid-column-start:10}.grid .g-start-xxl-11{grid-column-start:11}}.table{--bs-table-color-type: initial;--bs-table-bg-type: initial;--bs-table-color-state: initial;--bs-table-bg-state: initial;--bs-table-color: #212529;--bs-table-bg: #ffffff;--bs-table-border-color: #dee2e6;--bs-table-accent-bg: transparent;--bs-table-striped-color: #212529;--bs-table-striped-bg: rgba(0, 0, 0, 0.05);--bs-table-active-color: #212529;--bs-table-active-bg: rgba(0, 0, 0, 0.1);--bs-table-hover-color: #212529;--bs-table-hover-bg: rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;color:var(--bs-table-color-state, var(--bs-table-color-type, var(--bs-table-color)));background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-bg-state, var(--bs-table-bg-type, var(--bs-table-accent-bg)))}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:calc(1px*2) solid #9ba5ae}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-color-type: var(--bs-table-striped-color);--bs-table-bg-type: var(--bs-table-striped-bg)}.table-striped-columns>:not(caption)>tr>:nth-child(even){--bs-table-color-type: var(--bs-table-striped-color);--bs-table-bg-type: var(--bs-table-striped-bg)}.table-active{--bs-table-color-state: var(--bs-table-active-color);--bs-table-bg-state: var(--bs-table-active-bg)}.table-hover>tbody>tr:hover>*{--bs-table-color-state: var(--bs-table-hover-color);--bs-table-bg-state: var(--bs-table-hover-bg)}.table-primary{--bs-table-color: #000;--bs-table-bg: #cfe2ff;--bs-table-border-color: #bacbe6;--bs-table-striped-bg: #c5d7f2;--bs-table-striped-color: #000;--bs-table-active-bg: #bacbe6;--bs-table-active-color: #000;--bs-table-hover-bg: #bfd1ec;--bs-table-hover-color: #000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color: #000;--bs-table-bg: #e2e3e5;--bs-table-border-color: #cbccce;--bs-table-striped-bg: #d7d8da;--bs-table-striped-color: #000;--bs-table-active-bg: #cbccce;--bs-table-active-color: #000;--bs-table-hover-bg: #d1d2d4;--bs-table-hover-color: #000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color: #000;--bs-table-bg: #d1e7dd;--bs-table-border-color: #bcd0c7;--bs-table-striped-bg: #c7dbd2;--bs-table-striped-color: #000;--bs-table-active-bg: #bcd0c7;--bs-table-active-color: #000;--bs-table-hover-bg: #c1d6cc;--bs-table-hover-color: #000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color: #000;--bs-table-bg: #cff4fc;--bs-table-border-color: #badce3;--bs-table-striped-bg: #c5e8ef;--bs-table-striped-color: #000;--bs-table-active-bg: #badce3;--bs-table-active-color: #000;--bs-table-hover-bg: #bfe2e9;--bs-table-hover-color: #000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color: #000;--bs-table-bg: #fff3cd;--bs-table-border-color: #e6dbb9;--bs-table-striped-bg: #f2e7c3;--bs-table-striped-color: #000;--bs-table-active-bg: #e6dbb9;--bs-table-active-color: #000;--bs-table-hover-bg: #ece1be;--bs-table-hover-color: #000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color: #000;--bs-table-bg: #f8d7da;--bs-table-border-color: #dfc2c4;--bs-table-striped-bg: #eccccf;--bs-table-striped-color: #000;--bs-table-active-bg: #dfc2c4;--bs-table-active-color: #000;--bs-table-hover-bg: #e5c7ca;--bs-table-hover-color: #000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color: #000;--bs-table-bg: #f8f9fa;--bs-table-border-color: #dfe0e1;--bs-table-striped-bg: #ecedee;--bs-table-striped-color: #000;--bs-table-active-bg: #dfe0e1;--bs-table-active-color: #000;--bs-table-hover-bg: #e5e6e7;--bs-table-hover-color: #000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color: #ffffff;--bs-table-bg: #212529;--bs-table-border-color: #373b3e;--bs-table-striped-bg: #2c3034;--bs-table-striped-color: #ffffff;--bs-table-active-bg: #373b3e;--bs-table-active-color: #ffffff;--bs-table-hover-bg: #323539;--bs-table-hover-color: #ffffff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width: 575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label,.shiny-input-container .control-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(0.375rem + 1px);padding-bottom:calc(0.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(0.5rem + 1px);padding-bottom:calc(0.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(0.25rem + 1px);padding-bottom:calc(0.25rem + 1px);font-size:0.875rem}.form-text{margin-top:.25rem;font-size:0.875em;color:rgba(33,37,41,.75)}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;background-color:#fff;background-clip:padding-box;border:1px solid #dee2e6;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:#212529;background-color:#fff;border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{min-width:85px;height:1.5em;margin:0}.form-control::-webkit-datetime-edit{display:block;padding:0}.form-control::placeholder{color:rgba(33,37,41,.75);opacity:1}.form-control:disabled{background-color:#e9ecef;opacity:1}.form-control::file-selector-button{padding:.375rem .75rem;margin:-0.375rem -0.75rem;margin-inline-end:.75rem;color:#212529;background-color:#f8f9fa;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#e9ecef}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#212529;background-color:rgba(0,0,0,0);border:solid rgba(0,0,0,0);border-width:1px 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + 0.5rem + calc(1px * 2));padding:.25rem .5rem;font-size:0.875rem;border-radius:.25rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-0.25rem -0.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + calc(1px * 2));padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-0.5rem -1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + 0.75rem + calc(1px * 2))}textarea.form-control-sm{min-height:calc(1.5em + 0.5rem + calc(1px * 2))}textarea.form-control-lg{min-height:calc(1.5em + 1rem + calc(1px * 2))}.form-control-color{width:3rem;height:calc(1.5em + 0.75rem + calc(1px * 2));padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0 !important;border-radius:.375rem}.form-control-color::-webkit-color-swatch{border:0 !important;border-radius:.375rem}.form-control-color.form-control-sm{height:calc(1.5em + 0.5rem + calc(1px * 2))}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + calc(1px * 2))}.form-select{--bs-form-select-bg-img: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;background-color:#fff;background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon, none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #dee2e6;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-select{transition:none}}.form-select:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:rgba(0,0,0,0);text-shadow:0 0 0 #212529}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:0.875rem;border-radius:.25rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:.5rem}[data-bs-theme=dark] .form-select{--bs-form-select-bg-img: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23dee2e6' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e")}.form-check,.shiny-input-container .checkbox,.shiny-input-container .radio{display:block;min-height:1.5rem;padding-left:0;margin-bottom:.125rem}.form-check .form-check-input,.form-check .shiny-input-container .checkbox input,.form-check .shiny-input-container .radio input,.shiny-input-container .checkbox .form-check-input,.shiny-input-container .checkbox .shiny-input-container .checkbox input,.shiny-input-container .checkbox .shiny-input-container .radio input,.shiny-input-container .radio .form-check-input,.shiny-input-container .radio .shiny-input-container .checkbox input,.shiny-input-container .radio .shiny-input-container .radio input{float:left;margin-left:0}.form-check-reverse{padding-right:0;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:0;margin-left:0}.form-check-input,.shiny-input-container .checkbox input,.shiny-input-container .checkbox-inline input,.shiny-input-container .radio input,.shiny-input-container .radio-inline input{--bs-form-check-bg: #ffffff;width:1em;height:1em;margin-top:.25em;vertical-align:top;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid #dee2e6;print-color-adjust:exact}.form-check-input[type=checkbox],.shiny-input-container .checkbox input[type=checkbox],.shiny-input-container .checkbox-inline input[type=checkbox],.shiny-input-container .radio input[type=checkbox],.shiny-input-container .radio-inline input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio],.shiny-input-container .checkbox input[type=radio],.shiny-input-container .checkbox-inline input[type=radio],.shiny-input-container .radio input[type=radio],.shiny-input-container .radio-inline input[type=radio]{border-radius:50%}.form-check-input:active,.shiny-input-container .checkbox input:active,.shiny-input-container .checkbox-inline input:active,.shiny-input-container .radio input:active,.shiny-input-container .radio-inline input:active{filter:brightness(90%)}.form-check-input:focus,.shiny-input-container .checkbox input:focus,.shiny-input-container .checkbox-inline input:focus,.shiny-input-container .radio input:focus,.shiny-input-container .radio-inline input:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-check-input:checked,.shiny-input-container .checkbox input:checked,.shiny-input-container .checkbox-inline input:checked,.shiny-input-container .radio input:checked,.shiny-input-container .radio-inline input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox],.shiny-input-container .checkbox input:checked[type=checkbox],.shiny-input-container .checkbox-inline input:checked[type=checkbox],.shiny-input-container .radio input:checked[type=checkbox],.shiny-input-container .radio-inline input:checked[type=checkbox]{--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23ffffff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio],.shiny-input-container .checkbox input:checked[type=radio],.shiny-input-container .checkbox-inline input:checked[type=radio],.shiny-input-container .radio input:checked[type=radio],.shiny-input-container .radio-inline input:checked[type=radio]{--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23ffffff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate,.shiny-input-container .checkbox input[type=checkbox]:indeterminate,.shiny-input-container .checkbox-inline input[type=checkbox]:indeterminate,.shiny-input-container .radio input[type=checkbox]:indeterminate,.shiny-input-container .radio-inline input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23ffffff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled,.shiny-input-container .checkbox input:disabled,.shiny-input-container .checkbox-inline input:disabled,.shiny-input-container .radio input:disabled,.shiny-input-container .radio-inline input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input[disabled]~.form-check-label,.form-check-input[disabled]~span,.form-check-input:disabled~.form-check-label,.form-check-input:disabled~span,.shiny-input-container .checkbox input[disabled]~.form-check-label,.shiny-input-container .checkbox input[disabled]~span,.shiny-input-container .checkbox input:disabled~.form-check-label,.shiny-input-container .checkbox input:disabled~span,.shiny-input-container .checkbox-inline input[disabled]~.form-check-label,.shiny-input-container .checkbox-inline input[disabled]~span,.shiny-input-container .checkbox-inline input:disabled~.form-check-label,.shiny-input-container .checkbox-inline input:disabled~span,.shiny-input-container .radio input[disabled]~.form-check-label,.shiny-input-container .radio input[disabled]~span,.shiny-input-container .radio input:disabled~.form-check-label,.shiny-input-container .radio input:disabled~span,.shiny-input-container .radio-inline input[disabled]~.form-check-label,.shiny-input-container .radio-inline input[disabled]~span,.shiny-input-container .radio-inline input:disabled~.form-check-label,.shiny-input-container .radio-inline input:disabled~span{cursor:default;opacity:.5}.form-check-label,.shiny-input-container .checkbox label,.shiny-input-container .checkbox-inline label,.shiny-input-container .radio label,.shiny-input-container .radio-inline label{cursor:pointer}.form-switch{padding-left:2.5em}.form-switch .form-check-input{--bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");width:2em;margin-left:-2.5em;background-image:var(--bs-form-switch-bg);background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{--bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;--bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23ffffff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.btn-check[disabled]+.btn,.btn-check:disabled+.btn{pointer-events:none;filter:none;opacity:.65}[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus){--bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e")}.form-range{width:100%;height:1.5rem;padding:0;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;background-color:rgba(0,0,0,0)}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-0.25rem;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-range::-webkit-slider-thumb{transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:rgba(0,0,0,0);cursor:pointer;background-color:#f8f9fa;border-color:rgba(0,0,0,0);border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-range::-moz-range-thumb{transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:rgba(0,0,0,0);cursor:pointer;background-color:#f8f9fa;border-color:rgba(0,0,0,0);border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:rgba(33,37,41,.75)}.form-range:disabled::-moz-range-thumb{background-color:rgba(33,37,41,.75)}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + calc(1px * 2));min-height:calc(3.5rem + calc(1px * 2));line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;z-index:2;height:100%;padding:1rem .75rem;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:1px solid rgba(0,0,0,0);transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media(prefers-reduced-motion: reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control::placeholder,.form-floating>.form-control-plaintext::placeholder{color:rgba(0,0,0,0)}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown),.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill,.form-floating>.form-control-plaintext:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-control-plaintext~label,.form-floating>.form-select~label{color:rgba(var(--bs-body-color-rgb), 0.65);transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.form-floating>.form-control:focus~label::after,.form-floating>.form-control:not(:placeholder-shown)~label::after,.form-floating>.form-control-plaintext~label::after,.form-floating>.form-select~label::after{position:absolute;inset:1rem .375rem;z-index:-1;height:1.5em;content:"";background-color:#fff;border-radius:.375rem}.form-floating>.form-control:-webkit-autofill~label{color:rgba(var(--bs-body-color-rgb), 0.65);transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.form-floating>.form-control-plaintext~label{border-width:1px 0}.form-floating>:disabled~label,.form-floating>.form-control:disabled~label{color:#6c757d}.form-floating>:disabled~label::after,.form-floating>.form-control:disabled~label::after{background-color:#e9ecef}.input-group{position:relative;display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;align-items:stretch;-webkit-align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select,.input-group>.form-floating{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus,.input-group>.form-floating:focus-within{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:center;white-space:nowrap;background-color:#f8f9fa;border:1px solid #dee2e6;border-radius:.375rem}.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text,.input-group-lg>.btn{padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text,.input-group-sm>.btn{padding:.25rem .5rem;font-size:0.875rem;border-radius:.25rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select{border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:calc(1px*-1);border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:0.875em;color:#198754}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:0.875rem;color:#fff;background-color:#198754;border-radius:.375rem}.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip,.is-valid~.valid-feedback,.is-valid~.valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:#198754;padding-right:calc(1.5em + 0.75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:#198754;box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .form-select:valid,.form-select.is-valid{border-color:#198754}.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"],.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"]{--bs-form-select-bg-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-select:valid:focus,.form-select.is-valid:focus{border-color:#198754;box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.was-validated .form-control-color:valid,.form-control-color.is-valid{width:calc(3rem + calc(1.5em + 0.75rem))}.was-validated .form-check-input:valid,.form-check-input.is-valid{border-color:#198754}.was-validated .form-check-input:valid:checked,.form-check-input.is-valid:checked{background-color:#198754}.was-validated .form-check-input:valid:focus,.form-check-input.is-valid:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.was-validated .form-check-input:valid~.form-check-label,.form-check-input.is-valid~.form-check-label{color:#198754}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.was-validated .input-group>.form-control:not(:focus):valid,.input-group>.form-control:not(:focus).is-valid,.was-validated .input-group>.form-select:not(:focus):valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.input-group>.form-floating:not(:focus-within).is-valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:0.875em;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:0.875rem;color:#fff;background-color:#dc3545;border-radius:.375rem}.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip,.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:#dc3545;padding-right:calc(1.5em + 0.75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .form-select:invalid,.form-select.is-invalid{border-color:#dc3545}.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"],.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"]{--bs-form-select-bg-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-select:invalid:focus,.form-select.is-invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.was-validated .form-control-color:invalid,.form-control-color.is-invalid{width:calc(3rem + calc(1.5em + 0.75rem))}.was-validated .form-check-input:invalid,.form-check-input.is-invalid{border-color:#dc3545}.was-validated .form-check-input:invalid:checked,.form-check-input.is-invalid:checked{background-color:#dc3545}.was-validated .form-check-input:invalid:focus,.form-check-input.is-invalid:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.was-validated .form-check-input:invalid~.form-check-label,.form-check-input.is-invalid~.form-check-label{color:#dc3545}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.was-validated .input-group>.form-control:not(:focus):invalid,.input-group>.form-control:not(:focus).is-invalid,.was-validated .input-group>.form-select:not(:focus):invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.input-group>.form-floating:not(:focus-within).is-invalid{z-index:4}.btn{--bs-btn-padding-x: 0.75rem;--bs-btn-padding-y: 0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight: 400;--bs-btn-line-height: 1.5;--bs-btn-color: #212529;--bs-btn-bg: transparent;--bs-btn-border-width: 1px;--bs-btn-border-color: transparent;--bs-btn-border-radius: 0.375rem;--bs-btn-hover-border-color: transparent;--bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity: 0.65;--bs-btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;vertical-align:middle;cursor:pointer;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,:not(.btn-check)+.btn:active,.btn:first-child:active,.btn.active,.btn.show{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,:not(.btn-check)+.btn:active:focus-visible,.btn:first-child:active:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn:disabled,.btn.disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-default{--bs-btn-color: #000;--bs-btn-bg: #dee2e6;--bs-btn-border-color: #dee2e6;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #e3e6ea;--bs-btn-hover-border-color: #e1e5e9;--bs-btn-focus-shadow-rgb: 189, 192, 196;--bs-btn-active-color: #000;--bs-btn-active-bg: #e5e8eb;--bs-btn-active-border-color: #e1e5e9;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #000;--bs-btn-disabled-bg: #dee2e6;--bs-btn-disabled-border-color: #dee2e6}.btn-primary{--bs-btn-color: #ffffff;--bs-btn-bg: #0d6efd;--bs-btn-border-color: #0d6efd;--bs-btn-hover-color: #ffffff;--bs-btn-hover-bg: #0b5ed7;--bs-btn-hover-border-color: #0a58ca;--bs-btn-focus-shadow-rgb: 49, 132, 253;--bs-btn-active-color: #ffffff;--bs-btn-active-bg: #0a58ca;--bs-btn-active-border-color: #0a53be;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #ffffff;--bs-btn-disabled-bg: #0d6efd;--bs-btn-disabled-border-color: #0d6efd}.btn-secondary{--bs-btn-color: #ffffff;--bs-btn-bg: #6c757d;--bs-btn-border-color: #6c757d;--bs-btn-hover-color: #ffffff;--bs-btn-hover-bg: #5c636a;--bs-btn-hover-border-color: #565e64;--bs-btn-focus-shadow-rgb: 130, 138, 145;--bs-btn-active-color: #ffffff;--bs-btn-active-bg: #565e64;--bs-btn-active-border-color: #51585e;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #ffffff;--bs-btn-disabled-bg: #6c757d;--bs-btn-disabled-border-color: #6c757d}.btn-success{--bs-btn-color: #ffffff;--bs-btn-bg: #198754;--bs-btn-border-color: #198754;--bs-btn-hover-color: #ffffff;--bs-btn-hover-bg: #157347;--bs-btn-hover-border-color: #146c43;--bs-btn-focus-shadow-rgb: 60, 153, 110;--bs-btn-active-color: #ffffff;--bs-btn-active-bg: #146c43;--bs-btn-active-border-color: #13653f;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #ffffff;--bs-btn-disabled-bg: #198754;--bs-btn-disabled-border-color: #198754}.btn-info{--bs-btn-color: #000;--bs-btn-bg: #0dcaf0;--bs-btn-border-color: #0dcaf0;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #31d2f2;--bs-btn-hover-border-color: #25cff2;--bs-btn-focus-shadow-rgb: 11, 172, 204;--bs-btn-active-color: #000;--bs-btn-active-bg: #3dd5f3;--bs-btn-active-border-color: #25cff2;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #000;--bs-btn-disabled-bg: #0dcaf0;--bs-btn-disabled-border-color: #0dcaf0}.btn-warning{--bs-btn-color: #000;--bs-btn-bg: #ffc107;--bs-btn-border-color: #ffc107;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #ffca2c;--bs-btn-hover-border-color: #ffc720;--bs-btn-focus-shadow-rgb: 217, 164, 6;--bs-btn-active-color: #000;--bs-btn-active-bg: #ffcd39;--bs-btn-active-border-color: #ffc720;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #000;--bs-btn-disabled-bg: #ffc107;--bs-btn-disabled-border-color: #ffc107}.btn-danger{--bs-btn-color: #ffffff;--bs-btn-bg: #dc3545;--bs-btn-border-color: #dc3545;--bs-btn-hover-color: #ffffff;--bs-btn-hover-bg: #bb2d3b;--bs-btn-hover-border-color: #b02a37;--bs-btn-focus-shadow-rgb: 225, 83, 97;--bs-btn-active-color: #ffffff;--bs-btn-active-bg: #b02a37;--bs-btn-active-border-color: #a52834;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #ffffff;--bs-btn-disabled-bg: #dc3545;--bs-btn-disabled-border-color: #dc3545}.btn-light{--bs-btn-color: #000;--bs-btn-bg: #f8f9fa;--bs-btn-border-color: #f8f9fa;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #d3d4d5;--bs-btn-hover-border-color: #c6c7c8;--bs-btn-focus-shadow-rgb: 211, 212, 213;--bs-btn-active-color: #000;--bs-btn-active-bg: #c6c7c8;--bs-btn-active-border-color: #babbbc;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #000;--bs-btn-disabled-bg: #f8f9fa;--bs-btn-disabled-border-color: #f8f9fa}.btn-dark{--bs-btn-color: #ffffff;--bs-btn-bg: #212529;--bs-btn-border-color: #212529;--bs-btn-hover-color: #ffffff;--bs-btn-hover-bg: #424649;--bs-btn-hover-border-color: #373b3e;--bs-btn-focus-shadow-rgb: 66, 70, 73;--bs-btn-active-color: #ffffff;--bs-btn-active-bg: #4d5154;--bs-btn-active-border-color: #373b3e;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #ffffff;--bs-btn-disabled-bg: #212529;--bs-btn-disabled-border-color: #212529}.btn-outline-default{--bs-btn-color: #dee2e6;--bs-btn-border-color: #dee2e6;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #dee2e6;--bs-btn-hover-border-color: #dee2e6;--bs-btn-focus-shadow-rgb: 222, 226, 230;--bs-btn-active-color: #000;--bs-btn-active-bg: #dee2e6;--bs-btn-active-border-color: #dee2e6;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #dee2e6;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #dee2e6;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-primary{--bs-btn-color: #0d6efd;--bs-btn-border-color: #0d6efd;--bs-btn-hover-color: #ffffff;--bs-btn-hover-bg: #0d6efd;--bs-btn-hover-border-color: #0d6efd;--bs-btn-focus-shadow-rgb: 13, 110, 253;--bs-btn-active-color: #ffffff;--bs-btn-active-bg: #0d6efd;--bs-btn-active-border-color: #0d6efd;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #0d6efd;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #0d6efd;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-secondary{--bs-btn-color: #6c757d;--bs-btn-border-color: #6c757d;--bs-btn-hover-color: #ffffff;--bs-btn-hover-bg: #6c757d;--bs-btn-hover-border-color: #6c757d;--bs-btn-focus-shadow-rgb: 108, 117, 125;--bs-btn-active-color: #ffffff;--bs-btn-active-bg: #6c757d;--bs-btn-active-border-color: #6c757d;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #6c757d;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #6c757d;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-success{--bs-btn-color: #198754;--bs-btn-border-color: #198754;--bs-btn-hover-color: #ffffff;--bs-btn-hover-bg: #198754;--bs-btn-hover-border-color: #198754;--bs-btn-focus-shadow-rgb: 25, 135, 84;--bs-btn-active-color: #ffffff;--bs-btn-active-bg: #198754;--bs-btn-active-border-color: #198754;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #198754;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #198754;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-info{--bs-btn-color: #0dcaf0;--bs-btn-border-color: #0dcaf0;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #0dcaf0;--bs-btn-hover-border-color: #0dcaf0;--bs-btn-focus-shadow-rgb: 13, 202, 240;--bs-btn-active-color: #000;--bs-btn-active-bg: #0dcaf0;--bs-btn-active-border-color: #0dcaf0;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #0dcaf0;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #0dcaf0;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-warning{--bs-btn-color: #ffc107;--bs-btn-border-color: #ffc107;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #ffc107;--bs-btn-hover-border-color: #ffc107;--bs-btn-focus-shadow-rgb: 255, 193, 7;--bs-btn-active-color: #000;--bs-btn-active-bg: #ffc107;--bs-btn-active-border-color: #ffc107;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #ffc107;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #ffc107;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-danger{--bs-btn-color: #dc3545;--bs-btn-border-color: #dc3545;--bs-btn-hover-color: #ffffff;--bs-btn-hover-bg: #dc3545;--bs-btn-hover-border-color: #dc3545;--bs-btn-focus-shadow-rgb: 220, 53, 69;--bs-btn-active-color: #ffffff;--bs-btn-active-bg: #dc3545;--bs-btn-active-border-color: #dc3545;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #dc3545;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #dc3545;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-light{--bs-btn-color: #f8f9fa;--bs-btn-border-color: #f8f9fa;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #f8f9fa;--bs-btn-hover-border-color: #f8f9fa;--bs-btn-focus-shadow-rgb: 248, 249, 250;--bs-btn-active-color: #000;--bs-btn-active-bg: #f8f9fa;--bs-btn-active-border-color: #f8f9fa;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #f8f9fa;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #f8f9fa;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-dark{--bs-btn-color: #212529;--bs-btn-border-color: #212529;--bs-btn-hover-color: #ffffff;--bs-btn-hover-bg: #212529;--bs-btn-hover-border-color: #212529;--bs-btn-focus-shadow-rgb: 33, 37, 41;--bs-btn-active-color: #ffffff;--bs-btn-active-bg: #212529;--bs-btn-active-border-color: #212529;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #212529;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #212529;--bs-btn-bg: transparent;--bs-gradient: none}.btn-link{--bs-btn-font-weight: 400;--bs-btn-color: #0d6efd;--bs-btn-bg: transparent;--bs-btn-border-color: transparent;--bs-btn-hover-color: #0a58ca;--bs-btn-hover-border-color: transparent;--bs-btn-active-color: #0a58ca;--bs-btn-active-border-color: transparent;--bs-btn-disabled-color: #6c757d;--bs-btn-disabled-border-color: transparent;--bs-btn-box-shadow: 0 0 0 #000;--bs-btn-focus-shadow-rgb: 49, 132, 253;text-decoration:underline;-webkit-text-decoration:underline;-moz-text-decoration:underline;-ms-text-decoration:underline;-o-text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-lg,.btn-group-lg>.btn{--bs-btn-padding-y: 0.5rem;--bs-btn-padding-x: 1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius: 0.5rem}.btn-sm,.btn-group-sm>.btn{--bs-btn-padding-y: 0.25rem;--bs-btn-padding-x: 0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius: 0.25rem}.fade{transition:opacity .15s linear}@media(prefers-reduced-motion: reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .2s ease}@media(prefers-reduced-motion: reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media(prefers-reduced-motion: reduce){.collapsing.collapse-horizontal{transition:none}}.dropup,.dropend,.dropdown,.dropstart,.dropup-center,.dropdown-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid rgba(0,0,0,0);border-bottom:0;border-left:.3em solid rgba(0,0,0,0)}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex: 1000;--bs-dropdown-min-width: 10rem;--bs-dropdown-padding-x: 0;--bs-dropdown-padding-y: 0.5rem;--bs-dropdown-spacer: 0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color: #212529;--bs-dropdown-bg: #ffffff;--bs-dropdown-border-color: rgba(0, 0, 0, 0.175);--bs-dropdown-border-radius: 0.375rem;--bs-dropdown-border-width: 1px;--bs-dropdown-inner-border-radius: calc(0.375rem - 1px);--bs-dropdown-divider-bg: rgba(0, 0, 0, 0.175);--bs-dropdown-divider-margin-y: 0.5rem;--bs-dropdown-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-dropdown-link-color: #212529;--bs-dropdown-link-hover-color: #212529;--bs-dropdown-link-hover-bg: #f8f9fa;--bs-dropdown-link-active-color: #ffffff;--bs-dropdown-link-active-bg: #0d6efd;--bs-dropdown-link-disabled-color: rgba(33, 37, 41, 0.5);--bs-dropdown-item-padding-x: 1rem;--bs-dropdown-item-padding-y: 0.25rem;--bs-dropdown-header-color: #6c757d;--bs-dropdown-header-padding-x: 1rem;--bs-dropdown-header-padding-y: 0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position: start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position: end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media(min-width: 576px){.dropdown-menu-sm-start{--bs-position: start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position: end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 768px){.dropdown-menu-md-start{--bs-position: start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position: end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 992px){.dropdown-menu-lg-start{--bs-position: start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position: end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 1200px){.dropdown-menu-xl-start{--bs-position: start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position: end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 1400px){.dropdown-menu-xxl-start{--bs-position: start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position: end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid rgba(0,0,0,0);border-bottom:.3em solid;border-left:.3em solid rgba(0,0,0,0)}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid rgba(0,0,0,0);border-right:0;border-bottom:.3em solid rgba(0,0,0,0);border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid rgba(0,0,0,0);border-right:.3em solid;border-bottom:.3em solid rgba(0,0,0,0)}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;white-space:nowrap;background-color:rgba(0,0,0,0);border:0;border-radius:var(--bs-dropdown-item-border-radius, 0)}.dropdown-item:hover,.dropdown-item:focus{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:rgba(0,0,0,0)}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:0.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color: #dee2e6;--bs-dropdown-bg: #343a40;--bs-dropdown-border-color: rgba(0, 0, 0, 0.175);--bs-dropdown-box-shadow: ;--bs-dropdown-link-color: #dee2e6;--bs-dropdown-link-hover-color: #ffffff;--bs-dropdown-divider-bg: rgba(0, 0, 0, 0.175);--bs-dropdown-link-hover-bg: rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color: #ffffff;--bs-dropdown-link-active-bg: #0d6efd;--bs-dropdown-link-disabled-color: #adb5bd;--bs-dropdown-header-color: #adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto}.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn:hover,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:1}.btn-toolbar{display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;justify-content:flex-start;-webkit-justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:.375rem}.btn-group>:not(.btn-check:first-child)+.btn,.btn-group>.btn-group:not(:first-child){margin-left:calc(1px*-1)}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn,.btn-group>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;-webkit-flex-direction:column;align-items:flex-start;-webkit-align-items:flex-start;justify-content:center;-webkit-justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:calc(1px*-1)}.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),.btn-group-vertical>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn~.btn,.btn-group-vertical>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x: 1rem;--bs-nav-link-padding-y: 0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color: #0d6efd;--bs-nav-link-hover-color: #0a58ca;--bs-nav-link-disabled-color: rgba(33, 37, 41, 0.75);display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;background:none;border:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media(prefers-reduced-motion: reduce){.nav-link{transition:none}}.nav-link:hover,.nav-link:focus{color:var(--bs-nav-link-hover-color)}.nav-link:focus-visible{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.nav-link.disabled,.nav-link:disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width: 1px;--bs-nav-tabs-border-color: #dee2e6;--bs-nav-tabs-border-radius: 0.375rem;--bs-nav-tabs-link-hover-border-color: #e9ecef #e9ecef #dee2e6;--bs-nav-tabs-link-active-color: #000;--bs-nav-tabs-link-active-bg: #ffffff;--bs-nav-tabs-link-active-border-color: #dee2e6 #dee2e6 #ffffff;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1*var(--bs-nav-tabs-border-width));border:var(--bs-nav-tabs-border-width) solid rgba(0,0,0,0);border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1*var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius: 0.375rem;--bs-nav-pills-link-active-color: #ffffff;--bs-nav-pills-link-active-bg: #0d6efd}.nav-pills .nav-link{border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-underline{--bs-nav-underline-gap: 1rem;--bs-nav-underline-border-width: 0.125rem;--bs-nav-underline-link-active-color: #000;gap:var(--bs-nav-underline-gap)}.nav-underline .nav-link{padding-right:0;padding-left:0;border-bottom:var(--bs-nav-underline-border-width) solid rgba(0,0,0,0)}.nav-underline .nav-link:hover,.nav-underline .nav-link:focus{border-bottom-color:currentcolor}.nav-underline .nav-link.active,.nav-underline .show>.nav-link{font-weight:700;color:var(--bs-nav-underline-link-active-color);border-bottom-color:currentcolor}.nav-fill>.nav-link,.nav-fill .nav-item{flex:1 1 auto;-webkit-flex:1 1 auto;text-align:center}.nav-justified>.nav-link,.nav-justified .nav-item{flex-basis:0;-webkit-flex-basis:0;flex-grow:1;-webkit-flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x: 0;--bs-navbar-padding-y: 0.5rem;--bs-navbar-color: #fdfefe;--bs-navbar-hover-color: rgba(253, 254, 255, 0.8);--bs-navbar-disabled-color: rgba(253, 254, 254, 0.75);--bs-navbar-active-color: #fdfeff;--bs-navbar-brand-padding-y: 0.3125rem;--bs-navbar-brand-margin-end: 1rem;--bs-navbar-brand-font-size: 1.25rem;--bs-navbar-brand-color: #fdfefe;--bs-navbar-brand-hover-color: #fdfeff;--bs-navbar-nav-link-padding-x: 0.5rem;--bs-navbar-toggler-padding-y: 0.25;--bs-navbar-toggler-padding-x: 0;--bs-navbar-toggler-font-size: 1.25rem;--bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23fdfefe' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color: rgba(253, 254, 254, 0);--bs-navbar-toggler-border-radius: 0.375rem;--bs-navbar-toggler-focus-width: 0.25rem;--bs-navbar-toggler-transition: box-shadow 0.15s ease-in-out;position:relative;display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-sm,.navbar>.container-md,.navbar>.container-lg,.navbar>.container-xl,.navbar>.container-xxl{display:flex;display:-webkit-flex;flex-wrap:inherit;-webkit-flex-wrap:inherit;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;white-space:nowrap}.navbar-brand:hover,.navbar-brand:focus{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x: 0;--bs-nav-link-padding-y: 0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color: var(--bs-navbar-color);--bs-nav-link-hover-color: var(--bs-navbar-hover-color);--bs-nav-link-disabled-color: var(--bs-navbar-disabled-color);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .nav-link.show{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:hover,.navbar-text a:focus{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-basis:100%;-webkit-flex-basis:100%;flex-grow:1;-webkit-flex-grow:1;align-items:center;-webkit-align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:rgba(0,0,0,0);border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media(prefers-reduced-motion: reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height, 75vh);overflow-y:auto}@media(min-width: 576px){.navbar-expand-sm{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;-webkit-flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:rgba(0,0,0,0) !important;border:0 !important;transform:none !important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 768px){.navbar-expand-md{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;-webkit-flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:rgba(0,0,0,0) !important;border:0 !important;transform:none !important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 992px){.navbar-expand-lg{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;-webkit-flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:rgba(0,0,0,0) !important;border:0 !important;transform:none !important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 1200px){.navbar-expand-xl{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;-webkit-flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:rgba(0,0,0,0) !important;border:0 !important;transform:none !important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 1400px){.navbar-expand-xxl{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;-webkit-flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:rgba(0,0,0,0) !important;border:0 !important;transform:none !important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;-webkit-flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:rgba(0,0,0,0) !important;border:0 !important;transform:none !important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}.navbar-dark,.navbar[data-bs-theme=dark]{--bs-navbar-color: #fdfefe;--bs-navbar-hover-color: rgba(253, 254, 255, 0.8);--bs-navbar-disabled-color: rgba(253, 254, 254, 0.75);--bs-navbar-active-color: #fdfeff;--bs-navbar-brand-color: #fdfefe;--bs-navbar-brand-hover-color: #fdfeff;--bs-navbar-toggler-border-color: rgba(253, 254, 254, 0);--bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23fdfefe' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}[data-bs-theme=dark] .navbar-toggler-icon{--bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23fdfefe' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y: 1rem;--bs-card-spacer-x: 1rem;--bs-card-title-spacer-y: 0.5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width: 1px;--bs-card-border-color: rgba(0, 0, 0, 0.175);--bs-card-border-radius: 0.375rem;--bs-card-box-shadow: ;--bs-card-inner-border-radius: calc(0.375rem - 1px);--bs-card-cap-padding-y: 0.5rem;--bs-card-cap-padding-x: 1rem;--bs-card-cap-bg: rgba(33, 37, 41, 0.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg: #ffffff;--bs-card-img-overlay-padding: 1rem;--bs-card-group-margin: 0.75rem;position:relative;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;min-width:0;height:var(--bs-card-height);color:var(--bs-body-color);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;-webkit-flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y);color:var(--bs-card-title-color)}.card-subtitle{margin-top:calc(-0.5*var(--bs-card-title-spacer-y));margin-bottom:0;color:var(--bs-card-subtitle-color)}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-0.5*var(--bs-card-cap-padding-x));margin-bottom:calc(-1*var(--bs-card-cap-padding-y));margin-left:calc(-0.5*var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-0.5*var(--bs-card-cap-padding-x));margin-left:calc(-0.5*var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-top,.card-img-bottom{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media(min-width: 576px){.card-group{display:flex;display:-webkit-flex;flex-flow:row wrap;-webkit-flex-flow:row wrap}.card-group>.card{flex:1 0 0%;-webkit-flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-img-top,.card-group>.card:not(:last-child) .card-header{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-img-bottom,.card-group>.card:not(:last-child) .card-footer{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-img-top,.card-group>.card:not(:first-child) .card-header{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-img-bottom,.card-group>.card:not(:first-child) .card-footer{border-bottom-left-radius:0}}.accordion{--bs-accordion-color: #212529;--bs-accordion-bg: #ffffff;--bs-accordion-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease;--bs-accordion-border-color: #dee2e6;--bs-accordion-border-width: 1px;--bs-accordion-border-radius: 0.375rem;--bs-accordion-inner-border-radius: calc(0.375rem - 1px);--bs-accordion-btn-padding-x: 1.25rem;--bs-accordion-btn-padding-y: 1rem;--bs-accordion-btn-color: #212529;--bs-accordion-btn-bg: #ffffff;--bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width: 1.25rem;--bs-accordion-btn-icon-transform: rotate(-180deg);--bs-accordion-btn-icon-transition: transform 0.2s ease-in-out;--bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23052c65'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-focus-border-color: #86b7fe;--bs-accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-accordion-body-padding-x: 1.25rem;--bs-accordion-body-padding-y: 1rem;--bs-accordion-active-color: #052c65;--bs-accordion-active-bg: #cfe2ff}.accordion-button{position:relative;display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media(prefers-reduced-motion: reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1*var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;-webkit-flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media(prefers-reduced-motion: reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:var(--bs-accordion-btn-focus-border-color);outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button,.accordion-flush .accordion-item .accordion-button.collapsed{border-radius:0}[data-bs-theme=dark] .accordion-button::after{--bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.breadcrumb{--bs-breadcrumb-padding-x: 0;--bs-breadcrumb-padding-y: 0;--bs-breadcrumb-margin-bottom: 1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color: rgba(33, 37, 41, 0.75);--bs-breadcrumb-item-padding-x: 0.5rem;--bs-breadcrumb-item-active-color: rgba(33, 37, 41, 0.75);display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, ">") /* rtl: var(--bs-breadcrumb-divider, ">") */}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x: 0.75rem;--bs-pagination-padding-y: 0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color: #0d6efd;--bs-pagination-bg: #ffffff;--bs-pagination-border-width: 1px;--bs-pagination-border-color: #dee2e6;--bs-pagination-border-radius: 0.375rem;--bs-pagination-hover-color: #0a58ca;--bs-pagination-hover-bg: #f8f9fa;--bs-pagination-hover-border-color: #dee2e6;--bs-pagination-focus-color: #0a58ca;--bs-pagination-focus-bg: #e9ecef;--bs-pagination-focus-box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-pagination-active-color: #ffffff;--bs-pagination-active-bg: #0d6efd;--bs-pagination-active-border-color: #0d6efd;--bs-pagination-disabled-color: rgba(33, 37, 41, 0.75);--bs-pagination-disabled-bg: #e9ecef;--bs-pagination-disabled-border-color: #dee2e6;display:flex;display:-webkit-flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.page-link.active,.active>.page-link{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.page-link.disabled,.disabled>.page-link{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:calc(1px*-1)}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x: 1.5rem;--bs-pagination-padding-y: 0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius: 0.5rem}.pagination-sm{--bs-pagination-padding-x: 0.5rem;--bs-pagination-padding-y: 0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius: 0.25rem}.badge{--bs-badge-padding-x: 0.65em;--bs-badge-padding-y: 0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight: 700;--bs-badge-color: #ffffff;--bs-badge-border-radius: 0.375rem;display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg: transparent;--bs-alert-padding-x: 1rem;--bs-alert-padding-y: 1rem;--bs-alert-margin-bottom: 1rem;--bs-alert-color: inherit;--bs-alert-border-color: transparent;--bs-alert-border: 1px solid var(--bs-alert-border-color);--bs-alert-border-radius: 0.375rem;--bs-alert-link-color: inherit;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700;color:var(--bs-alert-link-color)}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-default{--bs-alert-color: var(--bs-default-text-emphasis);--bs-alert-bg: var(--bs-default-bg-subtle);--bs-alert-border-color: var(--bs-default-border-subtle);--bs-alert-link-color: var(--bs-default-text-emphasis)}.alert-primary{--bs-alert-color: var(--bs-primary-text-emphasis);--bs-alert-bg: var(--bs-primary-bg-subtle);--bs-alert-border-color: var(--bs-primary-border-subtle);--bs-alert-link-color: var(--bs-primary-text-emphasis)}.alert-secondary{--bs-alert-color: var(--bs-secondary-text-emphasis);--bs-alert-bg: var(--bs-secondary-bg-subtle);--bs-alert-border-color: var(--bs-secondary-border-subtle);--bs-alert-link-color: var(--bs-secondary-text-emphasis)}.alert-success{--bs-alert-color: var(--bs-success-text-emphasis);--bs-alert-bg: var(--bs-success-bg-subtle);--bs-alert-border-color: var(--bs-success-border-subtle);--bs-alert-link-color: var(--bs-success-text-emphasis)}.alert-info{--bs-alert-color: var(--bs-info-text-emphasis);--bs-alert-bg: var(--bs-info-bg-subtle);--bs-alert-border-color: var(--bs-info-border-subtle);--bs-alert-link-color: var(--bs-info-text-emphasis)}.alert-warning{--bs-alert-color: var(--bs-warning-text-emphasis);--bs-alert-bg: var(--bs-warning-bg-subtle);--bs-alert-border-color: var(--bs-warning-border-subtle);--bs-alert-link-color: var(--bs-warning-text-emphasis)}.alert-danger{--bs-alert-color: var(--bs-danger-text-emphasis);--bs-alert-bg: var(--bs-danger-bg-subtle);--bs-alert-border-color: var(--bs-danger-border-subtle);--bs-alert-link-color: var(--bs-danger-text-emphasis)}.alert-light{--bs-alert-color: var(--bs-light-text-emphasis);--bs-alert-bg: var(--bs-light-bg-subtle);--bs-alert-border-color: var(--bs-light-border-subtle);--bs-alert-link-color: var(--bs-light-text-emphasis)}.alert-dark{--bs-alert-color: var(--bs-dark-text-emphasis);--bs-alert-bg: var(--bs-dark-bg-subtle);--bs-alert-border-color: var(--bs-dark-border-subtle);--bs-alert-link-color: var(--bs-dark-text-emphasis)}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress,.progress-stacked{--bs-progress-height: 1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg: #e9ecef;--bs-progress-border-radius: 0.375rem;--bs-progress-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-progress-bar-color: #ffffff;--bs-progress-bar-bg: #0d6efd;--bs-progress-bar-transition: width 0.6s ease;display:flex;display:-webkit-flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;justify-content:center;-webkit-justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media(prefers-reduced-motion: reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-stacked>.progress{overflow:visible}.progress-stacked>.progress>.progress-bar{width:100%}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media(prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color: #212529;--bs-list-group-bg: #ffffff;--bs-list-group-border-color: #dee2e6;--bs-list-group-border-width: 1px;--bs-list-group-border-radius: 0.375rem;--bs-list-group-item-padding-x: 1rem;--bs-list-group-item-padding-y: 0.5rem;--bs-list-group-action-color: rgba(33, 37, 41, 0.75);--bs-list-group-action-hover-color: #000;--bs-list-group-action-hover-bg: #f8f9fa;--bs-list-group-action-active-color: #212529;--bs-list-group-action-active-bg: #e9ecef;--bs-list-group-disabled-color: rgba(33, 37, 41, 0.75);--bs-list-group-disabled-bg: #ffffff;--bs-list-group-active-color: #ffffff;--bs-list-group-active-bg: #0d6efd;--bs-list-group-active-border-color: #0d6efd;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1*var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1*var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media(min-width: 576px){.list-group-horizontal-sm{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1*var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media(min-width: 768px){.list-group-horizontal-md{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1*var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media(min-width: 992px){.list-group-horizontal-lg{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1*var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media(min-width: 1200px){.list-group-horizontal-xl{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1*var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media(min-width: 1400px){.list-group-horizontal-xxl{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1*var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-default{--bs-list-group-color: var(--bs-default-text-emphasis);--bs-list-group-bg: var(--bs-default-bg-subtle);--bs-list-group-border-color: var(--bs-default-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-default-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-default-border-subtle);--bs-list-group-active-color: var(--bs-default-bg-subtle);--bs-list-group-active-bg: var(--bs-default-text-emphasis);--bs-list-group-active-border-color: var(--bs-default-text-emphasis)}.list-group-item-primary{--bs-list-group-color: var(--bs-primary-text-emphasis);--bs-list-group-bg: var(--bs-primary-bg-subtle);--bs-list-group-border-color: var(--bs-primary-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-primary-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-primary-border-subtle);--bs-list-group-active-color: var(--bs-primary-bg-subtle);--bs-list-group-active-bg: var(--bs-primary-text-emphasis);--bs-list-group-active-border-color: var(--bs-primary-text-emphasis)}.list-group-item-secondary{--bs-list-group-color: var(--bs-secondary-text-emphasis);--bs-list-group-bg: var(--bs-secondary-bg-subtle);--bs-list-group-border-color: var(--bs-secondary-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-secondary-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-secondary-border-subtle);--bs-list-group-active-color: var(--bs-secondary-bg-subtle);--bs-list-group-active-bg: var(--bs-secondary-text-emphasis);--bs-list-group-active-border-color: var(--bs-secondary-text-emphasis)}.list-group-item-success{--bs-list-group-color: var(--bs-success-text-emphasis);--bs-list-group-bg: var(--bs-success-bg-subtle);--bs-list-group-border-color: var(--bs-success-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-success-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-success-border-subtle);--bs-list-group-active-color: var(--bs-success-bg-subtle);--bs-list-group-active-bg: var(--bs-success-text-emphasis);--bs-list-group-active-border-color: var(--bs-success-text-emphasis)}.list-group-item-info{--bs-list-group-color: var(--bs-info-text-emphasis);--bs-list-group-bg: var(--bs-info-bg-subtle);--bs-list-group-border-color: var(--bs-info-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-info-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-info-border-subtle);--bs-list-group-active-color: var(--bs-info-bg-subtle);--bs-list-group-active-bg: var(--bs-info-text-emphasis);--bs-list-group-active-border-color: var(--bs-info-text-emphasis)}.list-group-item-warning{--bs-list-group-color: var(--bs-warning-text-emphasis);--bs-list-group-bg: var(--bs-warning-bg-subtle);--bs-list-group-border-color: var(--bs-warning-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-warning-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-warning-border-subtle);--bs-list-group-active-color: var(--bs-warning-bg-subtle);--bs-list-group-active-bg: var(--bs-warning-text-emphasis);--bs-list-group-active-border-color: var(--bs-warning-text-emphasis)}.list-group-item-danger{--bs-list-group-color: var(--bs-danger-text-emphasis);--bs-list-group-bg: var(--bs-danger-bg-subtle);--bs-list-group-border-color: var(--bs-danger-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-danger-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-danger-border-subtle);--bs-list-group-active-color: var(--bs-danger-bg-subtle);--bs-list-group-active-bg: var(--bs-danger-text-emphasis);--bs-list-group-active-border-color: var(--bs-danger-text-emphasis)}.list-group-item-light{--bs-list-group-color: var(--bs-light-text-emphasis);--bs-list-group-bg: var(--bs-light-bg-subtle);--bs-list-group-border-color: var(--bs-light-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-light-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-light-border-subtle);--bs-list-group-active-color: var(--bs-light-bg-subtle);--bs-list-group-active-bg: var(--bs-light-text-emphasis);--bs-list-group-active-border-color: var(--bs-light-text-emphasis)}.list-group-item-dark{--bs-list-group-color: var(--bs-dark-text-emphasis);--bs-list-group-bg: var(--bs-dark-bg-subtle);--bs-list-group-border-color: var(--bs-dark-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-dark-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-dark-border-subtle);--bs-list-group-active-color: var(--bs-dark-bg-subtle);--bs-list-group-active-bg: var(--bs-dark-text-emphasis);--bs-list-group-active-border-color: var(--bs-dark-text-emphasis)}.btn-close{--bs-btn-close-color: #000;--bs-btn-close-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e");--bs-btn-close-opacity: 0.5;--bs-btn-close-hover-opacity: 0.75;--bs-btn-close-focus-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-btn-close-focus-opacity: 1;--bs-btn-close-disabled-opacity: 0.25;--bs-btn-close-white-filter: invert(1) grayscale(100%) brightness(200%);box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:var(--bs-btn-close-color);background:rgba(0,0,0,0) var(--bs-btn-close-bg) center/1em auto no-repeat;border:0;border-radius:.375rem;opacity:var(--bs-btn-close-opacity)}.btn-close:hover{color:var(--bs-btn-close-color);text-decoration:none;opacity:var(--bs-btn-close-hover-opacity)}.btn-close:focus{outline:0;box-shadow:var(--bs-btn-close-focus-shadow);opacity:var(--bs-btn-close-focus-opacity)}.btn-close:disabled,.btn-close.disabled{pointer-events:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;opacity:var(--bs-btn-close-disabled-opacity)}.btn-close-white{filter:var(--bs-btn-close-white-filter)}[data-bs-theme=dark] .btn-close{filter:var(--bs-btn-close-white-filter)}.toast{--bs-toast-zindex: 1090;--bs-toast-padding-x: 0.75rem;--bs-toast-padding-y: 0.5rem;--bs-toast-spacing: 1.5rem;--bs-toast-max-width: 350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg: rgba(255, 255, 255, 0.85);--bs-toast-border-width: 1px;--bs-toast-border-color: rgba(0, 0, 0, 0.175);--bs-toast-border-radius: 0.375rem;--bs-toast-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-toast-header-color: rgba(33, 37, 41, 0.75);--bs-toast-header-bg: rgba(255, 255, 255, 0.85);--bs-toast-header-border-color: rgba(0, 0, 0, 0.175);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex: 1090;position:absolute;z-index:var(--bs-toast-zindex);width:max-content;width:-webkit-max-content;width:-moz-max-content;width:-ms-max-content;width:-o-max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-0.5*var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex: 1055;--bs-modal-width: 500px;--bs-modal-padding: 1rem;--bs-modal-margin: 0.5rem;--bs-modal-color: ;--bs-modal-bg: #ffffff;--bs-modal-border-color: rgba(0, 0, 0, 0.175);--bs-modal-border-width: 1px;--bs-modal-border-radius: 0.5rem;--bs-modal-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-modal-inner-border-radius: calc(0.5rem - 1px);--bs-modal-header-padding-x: 1rem;--bs-modal-header-padding-y: 1rem;--bs-modal-header-padding: 1rem 1rem;--bs-modal-header-border-color: #dee2e6;--bs-modal-header-border-width: 1px;--bs-modal-title-line-height: 1.5;--bs-modal-footer-gap: 0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color: #dee2e6;--bs-modal-footer-border-width: 1px;position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0, -50px)}@media(prefers-reduced-motion: reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin)*2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;min-height:calc(100% - var(--bs-modal-margin)*2)}.modal-content{position:relative;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex: 1050;--bs-backdrop-bg: #000;--bs-backdrop-opacity: 0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;display:-webkit-flex;flex-shrink:0;-webkit-flex-shrink:0;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y)*.5) calc(var(--bs-modal-header-padding-x)*.5);margin:calc(-0.5*var(--bs-modal-header-padding-y)) calc(-0.5*var(--bs-modal-header-padding-x)) calc(-0.5*var(--bs-modal-header-padding-y)) auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;display:-webkit-flex;flex-shrink:0;-webkit-flex-shrink:0;flex-wrap:wrap;-webkit-flex-wrap:wrap;align-items:center;-webkit-align-items:center;justify-content:flex-end;-webkit-justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap)*.5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap)*.5)}@media(min-width: 576px){.modal{--bs-modal-margin: 1.75rem;--bs-modal-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width: 300px}}@media(min-width: 992px){.modal-lg,.modal-xl{--bs-modal-width: 800px}}@media(min-width: 1200px){.modal-xl{--bs-modal-width: 1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header,.modal-fullscreen .modal-footer{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media(max-width: 575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header,.modal-fullscreen-sm-down .modal-footer{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media(max-width: 767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header,.modal-fullscreen-md-down .modal-footer{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media(max-width: 991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header,.modal-fullscreen-lg-down .modal-footer{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media(max-width: 1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header,.modal-fullscreen-xl-down .modal-footer{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media(max-width: 1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header,.modal-fullscreen-xxl-down .modal-footer{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex: 1080;--bs-tooltip-max-width: 200px;--bs-tooltip-padding-x: 0.5rem;--bs-tooltip-padding-y: 0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color: #ffffff;--bs-tooltip-bg: #000;--bs-tooltip-border-radius: 0.375rem;--bs-tooltip-opacity: 0.9;--bs-tooltip-arrow-width: 0.8rem;--bs-tooltip-arrow-height: 0.4rem;z-index:var(--bs-tooltip-zindex);display:block;margin:var(--bs-tooltip-margin);font-family:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:rgba(0,0,0,0);border-style:solid}.bs-tooltip-top .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow{bottom:calc(-1*var(--bs-tooltip-arrow-height))}.bs-tooltip-top .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width)*.5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-end .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow{left:calc(-1*var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-end .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width)*.5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width)*.5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-bottom .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow{top:calc(-1*var(--bs-tooltip-arrow-height))}.bs-tooltip-bottom .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width)*.5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-start .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow{right:calc(-1*var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-start .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width)*.5) 0 calc(var(--bs-tooltip-arrow-width)*.5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex: 1070;--bs-popover-max-width: 276px;--bs-popover-font-size:0.875rem;--bs-popover-bg: #ffffff;--bs-popover-border-width: 1px;--bs-popover-border-color: rgba(0, 0, 0, 0.175);--bs-popover-border-radius: 0.5rem;--bs-popover-inner-border-radius: calc(0.5rem - 1px);--bs-popover-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-popover-header-padding-x: 1rem;--bs-popover-header-padding-y: 0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color: inherit;--bs-popover-header-bg: #e9ecef;--bs-popover-body-padding-x: 1rem;--bs-popover-body-padding-y: 1rem;--bs-popover-body-color: #212529;--bs-popover-arrow-width: 1rem;--bs-popover-arrow-height: 0.5rem;--bs-popover-arrow-border: var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::before,.popover .popover-arrow::after{position:absolute;display:block;content:"";border-color:rgba(0,0,0,0);border-style:solid;border-width:0}.bs-popover-top>.popover-arrow,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow{bottom:calc(-1*(var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width)*.5) 0}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-end>.popover-arrow,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow{left:calc(-1*(var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after{border-width:calc(var(--bs-popover-arrow-width)*.5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width)*.5) 0}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-bottom>.popover-arrow,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow{top:calc(-1*(var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after{border-width:0 calc(var(--bs-popover-arrow-width)*.5) var(--bs-popover-arrow-height)}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-bottom .popover-header::before,.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-0.5*var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-start>.popover-arrow,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow{right:calc(-1*(var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after{border-width:calc(var(--bs-popover-arrow-width)*.5) 0 calc(var(--bs-popover-arrow-width)*.5) var(--bs-popover-arrow-height)}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y;-webkit-touch-action:pan-y;-moz-touch-action:pan-y;-ms-touch-action:pan-y;-o-touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;backface-visibility:hidden;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;transition:transform .6s ease-in-out}@media(prefers-reduced-motion: reduce){.carousel-item{transition:none}}.carousel-item.active,.carousel-item-next,.carousel-item-prev{display:block}.carousel-item-next:not(.carousel-item-start),.active.carousel-item-end{transform:translateX(100%)}.carousel-item-prev:not(.carousel-item-end),.active.carousel-item-start{transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item.active,.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end{z-index:1;opacity:1}.carousel-fade .active.carousel-item-start,.carousel-fade .active.carousel-item-end{z-index:0;opacity:0;transition:opacity 0s .6s}@media(prefers-reduced-motion: reduce){.carousel-fade .active.carousel-item-start,.carousel-fade .active.carousel-item-end{transition:none}}.carousel-control-prev,.carousel-control-next{position:absolute;top:0;bottom:0;z-index:1;display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;justify-content:center;-webkit-justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:none;border:0;opacity:.5;transition:opacity .15s ease}@media(prefers-reduced-motion: reduce){.carousel-control-prev,.carousel-control-next{transition:none}}.carousel-control-prev:hover,.carousel-control-prev:focus,.carousel-control-next:hover,.carousel-control-next:focus{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-prev-icon,.carousel-control-next-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23ffffff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23ffffff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;display:-webkit-flex;justify-content:center;-webkit-justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;-webkit-flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid rgba(0,0,0,0);border-bottom:10px solid rgba(0,0,0,0);opacity:.5;transition:opacity .6s ease}@media(prefers-reduced-motion: reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-prev-icon,.carousel-dark .carousel-control-next-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}[data-bs-theme=dark] .carousel .carousel-control-prev-icon,[data-bs-theme=dark] .carousel .carousel-control-next-icon,[data-bs-theme=dark].carousel .carousel-control-prev-icon,[data-bs-theme=dark].carousel .carousel-control-next-icon{filter:invert(1) grayscale(100)}[data-bs-theme=dark] .carousel .carousel-indicators [data-bs-target],[data-bs-theme=dark].carousel .carousel-indicators [data-bs-target]{background-color:#000}[data-bs-theme=dark] .carousel .carousel-caption,[data-bs-theme=dark].carousel .carousel-caption{color:#000}.spinner-grow,.spinner-border{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@keyframes spinner-border{to{transform:rotate(360deg) /* rtl:ignore */}}.spinner-border{--bs-spinner-width: 2rem;--bs-spinner-height: 2rem;--bs-spinner-vertical-align: -0.125em;--bs-spinner-border-width: 0.25em;--bs-spinner-animation-speed: 0.75s;--bs-spinner-animation-name: spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:rgba(0,0,0,0)}.spinner-border-sm{--bs-spinner-width: 1rem;--bs-spinner-height: 1rem;--bs-spinner-border-width: 0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width: 2rem;--bs-spinner-height: 2rem;--bs-spinner-vertical-align: -0.125em;--bs-spinner-animation-speed: 0.75s;--bs-spinner-animation-name: spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width: 1rem;--bs-spinner-height: 1rem}@media(prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed: 1.5s}}.offcanvas,.offcanvas-xxl,.offcanvas-xl,.offcanvas-lg,.offcanvas-md,.offcanvas-sm{--bs-offcanvas-zindex: 1045;--bs-offcanvas-width: 400px;--bs-offcanvas-height: 30vh;--bs-offcanvas-padding-x: 1rem;--bs-offcanvas-padding-y: 1rem;--bs-offcanvas-color: #212529;--bs-offcanvas-bg: #ffffff;--bs-offcanvas-border-width: 1px;--bs-offcanvas-border-color: rgba(0, 0, 0, 0.175);--bs-offcanvas-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-offcanvas-transition: transform 0.3s ease-in-out;--bs-offcanvas-title-line-height: 1.5}@media(max-width: 575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media(max-width: 575.98px)and (prefers-reduced-motion: reduce){.offcanvas-sm{transition:none}}@media(max-width: 575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-sm.showing,.offcanvas-sm.show:not(.hiding){transform:none}.offcanvas-sm.showing,.offcanvas-sm.hiding,.offcanvas-sm.show{visibility:visible}}@media(min-width: 576px){.offcanvas-sm{--bs-offcanvas-height: auto;--bs-offcanvas-border-width: 0;background-color:rgba(0,0,0,0) !important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible;background-color:rgba(0,0,0,0) !important}}@media(max-width: 767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media(max-width: 767.98px)and (prefers-reduced-motion: reduce){.offcanvas-md{transition:none}}@media(max-width: 767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-md.showing,.offcanvas-md.show:not(.hiding){transform:none}.offcanvas-md.showing,.offcanvas-md.hiding,.offcanvas-md.show{visibility:visible}}@media(min-width: 768px){.offcanvas-md{--bs-offcanvas-height: auto;--bs-offcanvas-border-width: 0;background-color:rgba(0,0,0,0) !important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible;background-color:rgba(0,0,0,0) !important}}@media(max-width: 991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media(max-width: 991.98px)and (prefers-reduced-motion: reduce){.offcanvas-lg{transition:none}}@media(max-width: 991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-lg.showing,.offcanvas-lg.show:not(.hiding){transform:none}.offcanvas-lg.showing,.offcanvas-lg.hiding,.offcanvas-lg.show{visibility:visible}}@media(min-width: 992px){.offcanvas-lg{--bs-offcanvas-height: auto;--bs-offcanvas-border-width: 0;background-color:rgba(0,0,0,0) !important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible;background-color:rgba(0,0,0,0) !important}}@media(max-width: 1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media(max-width: 1199.98px)and (prefers-reduced-motion: reduce){.offcanvas-xl{transition:none}}@media(max-width: 1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xl.showing,.offcanvas-xl.show:not(.hiding){transform:none}.offcanvas-xl.showing,.offcanvas-xl.hiding,.offcanvas-xl.show{visibility:visible}}@media(min-width: 1200px){.offcanvas-xl{--bs-offcanvas-height: auto;--bs-offcanvas-border-width: 0;background-color:rgba(0,0,0,0) !important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible;background-color:rgba(0,0,0,0) !important}}@media(max-width: 1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media(max-width: 1399.98px)and (prefers-reduced-motion: reduce){.offcanvas-xxl{transition:none}}@media(max-width: 1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xxl.showing,.offcanvas-xxl.show:not(.hiding){transform:none}.offcanvas-xxl.showing,.offcanvas-xxl.hiding,.offcanvas-xxl.show{visibility:visible}}@media(min-width: 1400px){.offcanvas-xxl{--bs-offcanvas-height: auto;--bs-offcanvas-border-width: 0;background-color:rgba(0,0,0,0) !important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible;background-color:rgba(0,0,0,0) !important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}@media(prefers-reduced-motion: reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.showing,.offcanvas.show:not(.hiding){transform:none}.offcanvas.showing,.offcanvas.hiding,.offcanvas.show{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y)*.5) calc(var(--bs-offcanvas-padding-x)*.5);margin-top:calc(-0.5*var(--bs-offcanvas-padding-y));margin-right:calc(-0.5*var(--bs-offcanvas-padding-x));margin-bottom:calc(-0.5*var(--bs-offcanvas-padding-y))}.offcanvas-title{margin-bottom:0;line-height:var(--bs-offcanvas-title-line-height)}.offcanvas-body{flex-grow:1;-webkit-flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{mask-image:linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);-webkit-mask-image:linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);mask-size:200% 100%;-webkit-mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{mask-position:-200% 0%;-webkit-mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-default{color:#000 !important;background-color:RGBA(var(--bs-default-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-primary{color:#fff !important;background-color:RGBA(var(--bs-primary-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-secondary{color:#fff !important;background-color:RGBA(var(--bs-secondary-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-success{color:#fff !important;background-color:RGBA(var(--bs-success-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-info{color:#000 !important;background-color:RGBA(var(--bs-info-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-warning{color:#000 !important;background-color:RGBA(var(--bs-warning-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-danger{color:#fff !important;background-color:RGBA(var(--bs-danger-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-light{color:#000 !important;background-color:RGBA(var(--bs-light-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-dark{color:#fff !important;background-color:RGBA(var(--bs-dark-rgb), var(--bs-bg-opacity, 1)) !important}.link-default{color:RGBA(var(--bs-default-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-default-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-default:hover,.link-default:focus{color:RGBA(229, 232, 235, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(229, 232, 235, var(--bs-link-underline-opacity, 1)) !important}.link-primary{color:RGBA(var(--bs-primary-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-primary-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-primary:hover,.link-primary:focus{color:RGBA(10, 88, 202, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(10, 88, 202, var(--bs-link-underline-opacity, 1)) !important}.link-secondary{color:RGBA(var(--bs-secondary-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-secondary-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-secondary:hover,.link-secondary:focus{color:RGBA(86, 94, 100, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(86, 94, 100, var(--bs-link-underline-opacity, 1)) !important}.link-success{color:RGBA(var(--bs-success-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-success-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-success:hover,.link-success:focus{color:RGBA(20, 108, 67, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(20, 108, 67, var(--bs-link-underline-opacity, 1)) !important}.link-info{color:RGBA(var(--bs-info-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-info-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-info:hover,.link-info:focus{color:RGBA(61, 213, 243, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(61, 213, 243, var(--bs-link-underline-opacity, 1)) !important}.link-warning{color:RGBA(var(--bs-warning-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-warning-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-warning:hover,.link-warning:focus{color:RGBA(255, 205, 57, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(255, 205, 57, var(--bs-link-underline-opacity, 1)) !important}.link-danger{color:RGBA(var(--bs-danger-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-danger-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-danger:hover,.link-danger:focus{color:RGBA(176, 42, 55, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(176, 42, 55, var(--bs-link-underline-opacity, 1)) !important}.link-light{color:RGBA(var(--bs-light-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-light-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-light:hover,.link-light:focus{color:RGBA(249, 250, 251, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(249, 250, 251, var(--bs-link-underline-opacity, 1)) !important}.link-dark{color:RGBA(var(--bs-dark-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-dark-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-dark:hover,.link-dark:focus{color:RGBA(26, 30, 33, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(26, 30, 33, var(--bs-link-underline-opacity, 1)) !important}.link-body-emphasis{color:RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-body-emphasis:hover,.link-body-emphasis:focus{color:RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-opacity, 0.75)) !important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-underline-opacity, 0.75)) !important}.focus-ring:focus{outline:0;box-shadow:var(--bs-focus-ring-x, 0) var(--bs-focus-ring-y, 0) var(--bs-focus-ring-blur, 0) var(--bs-focus-ring-width) var(--bs-focus-ring-color)}.icon-link{display:inline-flex;gap:.375rem;align-items:center;-webkit-align-items:center;text-decoration-color:rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 0.5));text-underline-offset:.25em;backface-visibility:hidden;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden}.icon-link>.bi{flex-shrink:0;-webkit-flex-shrink:0;width:1em;height:1em;fill:currentcolor;transition:.2s ease-in-out transform}@media(prefers-reduced-motion: reduce){.icon-link>.bi{transition:none}}.icon-link-hover:hover>.bi,.icon-link-hover:focus-visible>.bi{transform:var(--bs-icon-link-transform, translate3d(0.25em, 0, 0))}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio: 100%}.ratio-4x3{--bs-aspect-ratio: 75%}.ratio-16x9{--bs-aspect-ratio: 56.25%}.ratio-21x9{--bs-aspect-ratio: 42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:sticky;top:0;z-index:1020}.sticky-bottom{position:sticky;bottom:0;z-index:1020}@media(min-width: 576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:sticky;bottom:0;z-index:1020}}@media(min-width: 768px){.sticky-md-top{position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:sticky;bottom:0;z-index:1020}}@media(min-width: 992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:sticky;bottom:0;z-index:1020}}@media(min-width: 1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:sticky;bottom:0;z-index:1020}}@media(min-width: 1400px){.sticky-xxl-top{position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;display:-webkit-flex;flex-direction:row;-webkit-flex-direction:row;align-items:center;-webkit-align-items:center;align-self:stretch;-webkit-align-self:stretch}.vstack{display:flex;display:-webkit-flex;flex:1 1 auto;-webkit-flex:1 1 auto;flex-direction:column;-webkit-flex-direction:column;align-self:stretch;-webkit-align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.visually-hidden:not(caption),.visually-hidden-focusable:not(:focus):not(:focus-within):not(caption){position:absolute !important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;-webkit-align-self:stretch;width:1px;min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.float-start{float:left !important}.float-end{float:right !important}.float-none{float:none !important}.object-fit-contain{object-fit:contain !important}.object-fit-cover{object-fit:cover !important}.object-fit-fill{object-fit:fill !important}.object-fit-scale{object-fit:scale-down !important}.object-fit-none{object-fit:none !important}.opacity-0{opacity:0 !important}.opacity-25{opacity:.25 !important}.opacity-50{opacity:.5 !important}.opacity-75{opacity:.75 !important}.opacity-100{opacity:1 !important}.overflow-auto{overflow:auto !important}.overflow-hidden{overflow:hidden !important}.overflow-visible{overflow:visible !important}.overflow-scroll{overflow:scroll !important}.overflow-x-auto{overflow-x:auto !important}.overflow-x-hidden{overflow-x:hidden !important}.overflow-x-visible{overflow-x:visible !important}.overflow-x-scroll{overflow-x:scroll !important}.overflow-y-auto{overflow-y:auto !important}.overflow-y-hidden{overflow-y:hidden !important}.overflow-y-visible{overflow-y:visible !important}.overflow-y-scroll{overflow-y:scroll !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-inline-grid{display:inline-grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15) !important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075) !important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175) !important}.shadow-none{box-shadow:none !important}.focus-ring-default{--bs-focus-ring-color: rgba(var(--bs-default-rgb), var(--bs-focus-ring-opacity))}.focus-ring-primary{--bs-focus-ring-color: rgba(var(--bs-primary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-secondary{--bs-focus-ring-color: rgba(var(--bs-secondary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-success{--bs-focus-ring-color: rgba(var(--bs-success-rgb), var(--bs-focus-ring-opacity))}.focus-ring-info{--bs-focus-ring-color: rgba(var(--bs-info-rgb), var(--bs-focus-ring-opacity))}.focus-ring-warning{--bs-focus-ring-color: rgba(var(--bs-warning-rgb), var(--bs-focus-ring-opacity))}.focus-ring-danger{--bs-focus-ring-color: rgba(var(--bs-danger-rgb), var(--bs-focus-ring-opacity))}.focus-ring-light{--bs-focus-ring-color: rgba(var(--bs-light-rgb), var(--bs-focus-ring-opacity))}.focus-ring-dark{--bs-focus-ring-color: rgba(var(--bs-dark-rgb), var(--bs-focus-ring-opacity))}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.top-0{top:0 !important}.top-50{top:50% !important}.top-100{top:100% !important}.bottom-0{bottom:0 !important}.bottom-50{bottom:50% !important}.bottom-100{bottom:100% !important}.start-0{left:0 !important}.start-50{left:50% !important}.start-100{left:100% !important}.end-0{right:0 !important}.end-50{right:50% !important}.end-100{right:100% !important}.translate-middle{transform:translate(-50%, -50%) !important}.translate-middle-x{transform:translateX(-50%) !important}.translate-middle-y{transform:translateY(-50%) !important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important}.border-0{border:0 !important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important}.border-top-0{border-top:0 !important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important}.border-end-0{border-right:0 !important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important}.border-bottom-0{border-bottom:0 !important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important}.border-start-0{border-left:0 !important}.border-default{--bs-border-opacity: 1;border-color:rgba(var(--bs-default-rgb), var(--bs-border-opacity)) !important}.border-primary{--bs-border-opacity: 1;border-color:rgba(var(--bs-primary-rgb), var(--bs-border-opacity)) !important}.border-secondary{--bs-border-opacity: 1;border-color:rgba(var(--bs-secondary-rgb), var(--bs-border-opacity)) !important}.border-success{--bs-border-opacity: 1;border-color:rgba(var(--bs-success-rgb), var(--bs-border-opacity)) !important}.border-info{--bs-border-opacity: 1;border-color:rgba(var(--bs-info-rgb), var(--bs-border-opacity)) !important}.border-warning{--bs-border-opacity: 1;border-color:rgba(var(--bs-warning-rgb), var(--bs-border-opacity)) !important}.border-danger{--bs-border-opacity: 1;border-color:rgba(var(--bs-danger-rgb), var(--bs-border-opacity)) !important}.border-light{--bs-border-opacity: 1;border-color:rgba(var(--bs-light-rgb), var(--bs-border-opacity)) !important}.border-dark{--bs-border-opacity: 1;border-color:rgba(var(--bs-dark-rgb), var(--bs-border-opacity)) !important}.border-black{--bs-border-opacity: 1;border-color:rgba(var(--bs-black-rgb), var(--bs-border-opacity)) !important}.border-white{--bs-border-opacity: 1;border-color:rgba(var(--bs-white-rgb), var(--bs-border-opacity)) !important}.border-primary-subtle{border-color:var(--bs-primary-border-subtle) !important}.border-secondary-subtle{border-color:var(--bs-secondary-border-subtle) !important}.border-success-subtle{border-color:var(--bs-success-border-subtle) !important}.border-info-subtle{border-color:var(--bs-info-border-subtle) !important}.border-warning-subtle{border-color:var(--bs-warning-border-subtle) !important}.border-danger-subtle{border-color:var(--bs-danger-border-subtle) !important}.border-light-subtle{border-color:var(--bs-light-border-subtle) !important}.border-dark-subtle{border-color:var(--bs-dark-border-subtle) !important}.border-1{border-width:1px !important}.border-2{border-width:2px !important}.border-3{border-width:3px !important}.border-4{border-width:4px !important}.border-5{border-width:5px !important}.border-opacity-10{--bs-border-opacity: 0.1}.border-opacity-25{--bs-border-opacity: 0.25}.border-opacity-50{--bs-border-opacity: 0.5}.border-opacity-75{--bs-border-opacity: 0.75}.border-opacity-100{--bs-border-opacity: 1}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.mw-100{max-width:100% !important}.vw-100{width:100vw !important}.min-vw-100{min-width:100vw !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mh-100{max-height:100% !important}.vh-100{height:100vh !important}.min-vh-100{min-height:100vh !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}.gap-0{gap:0 !important}.gap-1{gap:.25rem !important}.gap-2{gap:.5rem !important}.gap-3{gap:1rem !important}.gap-4{gap:1.5rem !important}.gap-5{gap:3rem !important}.row-gap-0{row-gap:0 !important}.row-gap-1{row-gap:.25rem !important}.row-gap-2{row-gap:.5rem !important}.row-gap-3{row-gap:1rem !important}.row-gap-4{row-gap:1.5rem !important}.row-gap-5{row-gap:3rem !important}.column-gap-0{column-gap:0 !important}.column-gap-1{column-gap:.25rem !important}.column-gap-2{column-gap:.5rem !important}.column-gap-3{column-gap:1rem !important}.column-gap-4{column-gap:1.5rem !important}.column-gap-5{column-gap:3rem !important}.font-monospace{font-family:var(--bs-font-monospace) !important}.fs-1{font-size:calc(1.325rem + 0.9vw) !important}.fs-2{font-size:calc(1.29rem + 0.48vw) !important}.fs-3{font-size:calc(1.27rem + 0.24vw) !important}.fs-4{font-size:1.25rem !important}.fs-5{font-size:1.1rem !important}.fs-6{font-size:1rem !important}.fst-italic{font-style:italic !important}.fst-normal{font-style:normal !important}.fw-lighter{font-weight:lighter !important}.fw-light{font-weight:300 !important}.fw-normal{font-weight:400 !important}.fw-medium{font-weight:500 !important}.fw-semibold{font-weight:600 !important}.fw-bold{font-weight:700 !important}.fw-bolder{font-weight:bolder !important}.lh-1{line-height:1 !important}.lh-sm{line-height:1.25 !important}.lh-base{line-height:1.5 !important}.lh-lg{line-height:2 !important}.text-start{text-align:left !important}.text-end{text-align:right !important}.text-center{text-align:center !important}.text-decoration-none{text-decoration:none !important}.text-decoration-underline{text-decoration:underline !important}.text-decoration-line-through{text-decoration:line-through !important}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.text-wrap{white-space:normal !important}.text-nowrap{white-space:nowrap !important}.text-break{word-wrap:break-word !important;word-break:break-word !important}.text-default{--bs-text-opacity: 1;color:rgba(var(--bs-default-rgb), var(--bs-text-opacity)) !important}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important}.text-secondary{--bs-text-opacity: 1;color:rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important}.text-success{--bs-text-opacity: 1;color:rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important}.text-info{--bs-text-opacity: 1;color:rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important}.text-warning{--bs-text-opacity: 1;color:rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important}.text-danger{--bs-text-opacity: 1;color:rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important}.text-light{--bs-text-opacity: 1;color:rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important}.text-dark{--bs-text-opacity: 1;color:rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important}.text-black{--bs-text-opacity: 1;color:rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important}.text-white{--bs-text-opacity: 1;color:rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important}.text-body{--bs-text-opacity: 1;color:rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important}.text-muted{--bs-text-opacity: 1;color:var(--bs-secondary-color) !important}.text-black-50{--bs-text-opacity: 1;color:rgba(0,0,0,.5) !important}.text-white-50{--bs-text-opacity: 1;color:rgba(255,255,255,.5) !important}.text-body-secondary{--bs-text-opacity: 1;color:var(--bs-secondary-color) !important}.text-body-tertiary{--bs-text-opacity: 1;color:var(--bs-tertiary-color) !important}.text-body-emphasis{--bs-text-opacity: 1;color:var(--bs-emphasis-color) !important}.text-reset{--bs-text-opacity: 1;color:inherit !important}.text-opacity-25{--bs-text-opacity: 0.25}.text-opacity-50{--bs-text-opacity: 0.5}.text-opacity-75{--bs-text-opacity: 0.75}.text-opacity-100{--bs-text-opacity: 1}.text-primary-emphasis{color:var(--bs-primary-text-emphasis) !important}.text-secondary-emphasis{color:var(--bs-secondary-text-emphasis) !important}.text-success-emphasis{color:var(--bs-success-text-emphasis) !important}.text-info-emphasis{color:var(--bs-info-text-emphasis) !important}.text-warning-emphasis{color:var(--bs-warning-text-emphasis) !important}.text-danger-emphasis{color:var(--bs-danger-text-emphasis) !important}.text-light-emphasis{color:var(--bs-light-text-emphasis) !important}.text-dark-emphasis{color:var(--bs-dark-text-emphasis) !important}.link-opacity-10{--bs-link-opacity: 0.1}.link-opacity-10-hover:hover{--bs-link-opacity: 0.1}.link-opacity-25{--bs-link-opacity: 0.25}.link-opacity-25-hover:hover{--bs-link-opacity: 0.25}.link-opacity-50{--bs-link-opacity: 0.5}.link-opacity-50-hover:hover{--bs-link-opacity: 0.5}.link-opacity-75{--bs-link-opacity: 0.75}.link-opacity-75-hover:hover{--bs-link-opacity: 0.75}.link-opacity-100{--bs-link-opacity: 1}.link-opacity-100-hover:hover{--bs-link-opacity: 1}.link-offset-1{text-underline-offset:.125em !important}.link-offset-1-hover:hover{text-underline-offset:.125em !important}.link-offset-2{text-underline-offset:.25em !important}.link-offset-2-hover:hover{text-underline-offset:.25em !important}.link-offset-3{text-underline-offset:.375em !important}.link-offset-3-hover:hover{text-underline-offset:.375em !important}.link-underline-default{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-default-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-primary{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-primary-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-secondary{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-secondary-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-success{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-success-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-info{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-info-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-warning{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-warning-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-danger{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-danger-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-light{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-light-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-dark{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-dark-rgb), var(--bs-link-underline-opacity)) !important}.link-underline{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-link-color-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-underline-opacity-0{--bs-link-underline-opacity: 0}.link-underline-opacity-0-hover:hover{--bs-link-underline-opacity: 0}.link-underline-opacity-10{--bs-link-underline-opacity: 0.1}.link-underline-opacity-10-hover:hover{--bs-link-underline-opacity: 0.1}.link-underline-opacity-25{--bs-link-underline-opacity: 0.25}.link-underline-opacity-25-hover:hover{--bs-link-underline-opacity: 0.25}.link-underline-opacity-50{--bs-link-underline-opacity: 0.5}.link-underline-opacity-50-hover:hover{--bs-link-underline-opacity: 0.5}.link-underline-opacity-75{--bs-link-underline-opacity: 0.75}.link-underline-opacity-75-hover:hover{--bs-link-underline-opacity: 0.75}.link-underline-opacity-100{--bs-link-underline-opacity: 1}.link-underline-opacity-100-hover:hover{--bs-link-underline-opacity: 1}.bg-default{--bs-bg-opacity: 1;background-color:rgba(var(--bs-default-rgb), var(--bs-bg-opacity)) !important}.bg-primary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important}.bg-secondary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important}.bg-success{--bs-bg-opacity: 1;background-color:rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important}.bg-info{--bs-bg-opacity: 1;background-color:rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important}.bg-warning{--bs-bg-opacity: 1;background-color:rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important}.bg-danger{--bs-bg-opacity: 1;background-color:rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important}.bg-light{--bs-bg-opacity: 1;background-color:rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important}.bg-dark{--bs-bg-opacity: 1;background-color:rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important}.bg-black{--bs-bg-opacity: 1;background-color:rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important}.bg-white{--bs-bg-opacity: 1;background-color:rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important}.bg-body{--bs-bg-opacity: 1;background-color:rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important}.bg-transparent{--bs-bg-opacity: 1;background-color:rgba(0,0,0,0) !important}.bg-body-secondary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-secondary-bg-rgb), var(--bs-bg-opacity)) !important}.bg-body-tertiary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-tertiary-bg-rgb), var(--bs-bg-opacity)) !important}.bg-opacity-10{--bs-bg-opacity: 0.1}.bg-opacity-25{--bs-bg-opacity: 0.25}.bg-opacity-50{--bs-bg-opacity: 0.5}.bg-opacity-75{--bs-bg-opacity: 0.75}.bg-opacity-100{--bs-bg-opacity: 1}.bg-primary-subtle{background-color:var(--bs-primary-bg-subtle) !important}.bg-secondary-subtle{background-color:var(--bs-secondary-bg-subtle) !important}.bg-success-subtle{background-color:var(--bs-success-bg-subtle) !important}.bg-info-subtle{background-color:var(--bs-info-bg-subtle) !important}.bg-warning-subtle{background-color:var(--bs-warning-bg-subtle) !important}.bg-danger-subtle{background-color:var(--bs-danger-bg-subtle) !important}.bg-light-subtle{background-color:var(--bs-light-bg-subtle) !important}.bg-dark-subtle{background-color:var(--bs-dark-bg-subtle) !important}.bg-gradient{background-image:var(--bs-gradient) !important}.user-select-all{user-select:all !important}.user-select-auto{user-select:auto !important}.user-select-none{user-select:none !important}.pe-none{pointer-events:none !important}.pe-auto{pointer-events:auto !important}.rounded{border-radius:var(--bs-border-radius) !important}.rounded-0{border-radius:0 !important}.rounded-1{border-radius:var(--bs-border-radius-sm) !important}.rounded-2{border-radius:var(--bs-border-radius) !important}.rounded-3{border-radius:var(--bs-border-radius-lg) !important}.rounded-4{border-radius:var(--bs-border-radius-xl) !important}.rounded-5{border-radius:var(--bs-border-radius-xxl) !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:var(--bs-border-radius-pill) !important}.rounded-top{border-top-left-radius:var(--bs-border-radius) !important;border-top-right-radius:var(--bs-border-radius) !important}.rounded-top-0{border-top-left-radius:0 !important;border-top-right-radius:0 !important}.rounded-top-1{border-top-left-radius:var(--bs-border-radius-sm) !important;border-top-right-radius:var(--bs-border-radius-sm) !important}.rounded-top-2{border-top-left-radius:var(--bs-border-radius) !important;border-top-right-radius:var(--bs-border-radius) !important}.rounded-top-3{border-top-left-radius:var(--bs-border-radius-lg) !important;border-top-right-radius:var(--bs-border-radius-lg) !important}.rounded-top-4{border-top-left-radius:var(--bs-border-radius-xl) !important;border-top-right-radius:var(--bs-border-radius-xl) !important}.rounded-top-5{border-top-left-radius:var(--bs-border-radius-xxl) !important;border-top-right-radius:var(--bs-border-radius-xxl) !important}.rounded-top-circle{border-top-left-radius:50% !important;border-top-right-radius:50% !important}.rounded-top-pill{border-top-left-radius:var(--bs-border-radius-pill) !important;border-top-right-radius:var(--bs-border-radius-pill) !important}.rounded-end{border-top-right-radius:var(--bs-border-radius) !important;border-bottom-right-radius:var(--bs-border-radius) !important}.rounded-end-0{border-top-right-radius:0 !important;border-bottom-right-radius:0 !important}.rounded-end-1{border-top-right-radius:var(--bs-border-radius-sm) !important;border-bottom-right-radius:var(--bs-border-radius-sm) !important}.rounded-end-2{border-top-right-radius:var(--bs-border-radius) !important;border-bottom-right-radius:var(--bs-border-radius) !important}.rounded-end-3{border-top-right-radius:var(--bs-border-radius-lg) !important;border-bottom-right-radius:var(--bs-border-radius-lg) !important}.rounded-end-4{border-top-right-radius:var(--bs-border-radius-xl) !important;border-bottom-right-radius:var(--bs-border-radius-xl) !important}.rounded-end-5{border-top-right-radius:var(--bs-border-radius-xxl) !important;border-bottom-right-radius:var(--bs-border-radius-xxl) !important}.rounded-end-circle{border-top-right-radius:50% !important;border-bottom-right-radius:50% !important}.rounded-end-pill{border-top-right-radius:var(--bs-border-radius-pill) !important;border-bottom-right-radius:var(--bs-border-radius-pill) !important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius) !important;border-bottom-left-radius:var(--bs-border-radius) !important}.rounded-bottom-0{border-bottom-right-radius:0 !important;border-bottom-left-radius:0 !important}.rounded-bottom-1{border-bottom-right-radius:var(--bs-border-radius-sm) !important;border-bottom-left-radius:var(--bs-border-radius-sm) !important}.rounded-bottom-2{border-bottom-right-radius:var(--bs-border-radius) !important;border-bottom-left-radius:var(--bs-border-radius) !important}.rounded-bottom-3{border-bottom-right-radius:var(--bs-border-radius-lg) !important;border-bottom-left-radius:var(--bs-border-radius-lg) !important}.rounded-bottom-4{border-bottom-right-radius:var(--bs-border-radius-xl) !important;border-bottom-left-radius:var(--bs-border-radius-xl) !important}.rounded-bottom-5{border-bottom-right-radius:var(--bs-border-radius-xxl) !important;border-bottom-left-radius:var(--bs-border-radius-xxl) !important}.rounded-bottom-circle{border-bottom-right-radius:50% !important;border-bottom-left-radius:50% !important}.rounded-bottom-pill{border-bottom-right-radius:var(--bs-border-radius-pill) !important;border-bottom-left-radius:var(--bs-border-radius-pill) !important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius) !important;border-top-left-radius:var(--bs-border-radius) !important}.rounded-start-0{border-bottom-left-radius:0 !important;border-top-left-radius:0 !important}.rounded-start-1{border-bottom-left-radius:var(--bs-border-radius-sm) !important;border-top-left-radius:var(--bs-border-radius-sm) !important}.rounded-start-2{border-bottom-left-radius:var(--bs-border-radius) !important;border-top-left-radius:var(--bs-border-radius) !important}.rounded-start-3{border-bottom-left-radius:var(--bs-border-radius-lg) !important;border-top-left-radius:var(--bs-border-radius-lg) !important}.rounded-start-4{border-bottom-left-radius:var(--bs-border-radius-xl) !important;border-top-left-radius:var(--bs-border-radius-xl) !important}.rounded-start-5{border-bottom-left-radius:var(--bs-border-radius-xxl) !important;border-top-left-radius:var(--bs-border-radius-xxl) !important}.rounded-start-circle{border-bottom-left-radius:50% !important;border-top-left-radius:50% !important}.rounded-start-pill{border-bottom-left-radius:var(--bs-border-radius-pill) !important;border-top-left-radius:var(--bs-border-radius-pill) !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}.z-n1{z-index:-1 !important}.z-0{z-index:0 !important}.z-1{z-index:1 !important}.z-2{z-index:2 !important}.z-3{z-index:3 !important}@media(min-width: 576px){.float-sm-start{float:left !important}.float-sm-end{float:right !important}.float-sm-none{float:none !important}.object-fit-sm-contain{object-fit:contain !important}.object-fit-sm-cover{object-fit:cover !important}.object-fit-sm-fill{object-fit:fill !important}.object-fit-sm-scale{object-fit:scale-down !important}.object-fit-sm-none{object-fit:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-inline-grid{display:inline-grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}.gap-sm-0{gap:0 !important}.gap-sm-1{gap:.25rem !important}.gap-sm-2{gap:.5rem !important}.gap-sm-3{gap:1rem !important}.gap-sm-4{gap:1.5rem !important}.gap-sm-5{gap:3rem !important}.row-gap-sm-0{row-gap:0 !important}.row-gap-sm-1{row-gap:.25rem !important}.row-gap-sm-2{row-gap:.5rem !important}.row-gap-sm-3{row-gap:1rem !important}.row-gap-sm-4{row-gap:1.5rem !important}.row-gap-sm-5{row-gap:3rem !important}.column-gap-sm-0{column-gap:0 !important}.column-gap-sm-1{column-gap:.25rem !important}.column-gap-sm-2{column-gap:.5rem !important}.column-gap-sm-3{column-gap:1rem !important}.column-gap-sm-4{column-gap:1.5rem !important}.column-gap-sm-5{column-gap:3rem !important}.text-sm-start{text-align:left !important}.text-sm-end{text-align:right !important}.text-sm-center{text-align:center !important}}@media(min-width: 768px){.float-md-start{float:left !important}.float-md-end{float:right !important}.float-md-none{float:none !important}.object-fit-md-contain{object-fit:contain !important}.object-fit-md-cover{object-fit:cover !important}.object-fit-md-fill{object-fit:fill !important}.object-fit-md-scale{object-fit:scale-down !important}.object-fit-md-none{object-fit:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-inline-grid{display:inline-grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}.gap-md-0{gap:0 !important}.gap-md-1{gap:.25rem !important}.gap-md-2{gap:.5rem !important}.gap-md-3{gap:1rem !important}.gap-md-4{gap:1.5rem !important}.gap-md-5{gap:3rem !important}.row-gap-md-0{row-gap:0 !important}.row-gap-md-1{row-gap:.25rem !important}.row-gap-md-2{row-gap:.5rem !important}.row-gap-md-3{row-gap:1rem !important}.row-gap-md-4{row-gap:1.5rem !important}.row-gap-md-5{row-gap:3rem !important}.column-gap-md-0{column-gap:0 !important}.column-gap-md-1{column-gap:.25rem !important}.column-gap-md-2{column-gap:.5rem !important}.column-gap-md-3{column-gap:1rem !important}.column-gap-md-4{column-gap:1.5rem !important}.column-gap-md-5{column-gap:3rem !important}.text-md-start{text-align:left !important}.text-md-end{text-align:right !important}.text-md-center{text-align:center !important}}@media(min-width: 992px){.float-lg-start{float:left !important}.float-lg-end{float:right !important}.float-lg-none{float:none !important}.object-fit-lg-contain{object-fit:contain !important}.object-fit-lg-cover{object-fit:cover !important}.object-fit-lg-fill{object-fit:fill !important}.object-fit-lg-scale{object-fit:scale-down !important}.object-fit-lg-none{object-fit:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-inline-grid{display:inline-grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}.gap-lg-0{gap:0 !important}.gap-lg-1{gap:.25rem !important}.gap-lg-2{gap:.5rem !important}.gap-lg-3{gap:1rem !important}.gap-lg-4{gap:1.5rem !important}.gap-lg-5{gap:3rem !important}.row-gap-lg-0{row-gap:0 !important}.row-gap-lg-1{row-gap:.25rem !important}.row-gap-lg-2{row-gap:.5rem !important}.row-gap-lg-3{row-gap:1rem !important}.row-gap-lg-4{row-gap:1.5rem !important}.row-gap-lg-5{row-gap:3rem !important}.column-gap-lg-0{column-gap:0 !important}.column-gap-lg-1{column-gap:.25rem !important}.column-gap-lg-2{column-gap:.5rem !important}.column-gap-lg-3{column-gap:1rem !important}.column-gap-lg-4{column-gap:1.5rem !important}.column-gap-lg-5{column-gap:3rem !important}.text-lg-start{text-align:left !important}.text-lg-end{text-align:right !important}.text-lg-center{text-align:center !important}}@media(min-width: 1200px){.float-xl-start{float:left !important}.float-xl-end{float:right !important}.float-xl-none{float:none !important}.object-fit-xl-contain{object-fit:contain !important}.object-fit-xl-cover{object-fit:cover !important}.object-fit-xl-fill{object-fit:fill !important}.object-fit-xl-scale{object-fit:scale-down !important}.object-fit-xl-none{object-fit:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-inline-grid{display:inline-grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}.gap-xl-0{gap:0 !important}.gap-xl-1{gap:.25rem !important}.gap-xl-2{gap:.5rem !important}.gap-xl-3{gap:1rem !important}.gap-xl-4{gap:1.5rem !important}.gap-xl-5{gap:3rem !important}.row-gap-xl-0{row-gap:0 !important}.row-gap-xl-1{row-gap:.25rem !important}.row-gap-xl-2{row-gap:.5rem !important}.row-gap-xl-3{row-gap:1rem !important}.row-gap-xl-4{row-gap:1.5rem !important}.row-gap-xl-5{row-gap:3rem !important}.column-gap-xl-0{column-gap:0 !important}.column-gap-xl-1{column-gap:.25rem !important}.column-gap-xl-2{column-gap:.5rem !important}.column-gap-xl-3{column-gap:1rem !important}.column-gap-xl-4{column-gap:1.5rem !important}.column-gap-xl-5{column-gap:3rem !important}.text-xl-start{text-align:left !important}.text-xl-end{text-align:right !important}.text-xl-center{text-align:center !important}}@media(min-width: 1400px){.float-xxl-start{float:left !important}.float-xxl-end{float:right !important}.float-xxl-none{float:none !important}.object-fit-xxl-contain{object-fit:contain !important}.object-fit-xxl-cover{object-fit:cover !important}.object-fit-xxl-fill{object-fit:fill !important}.object-fit-xxl-scale{object-fit:scale-down !important}.object-fit-xxl-none{object-fit:none !important}.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-inline-grid{display:inline-grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}.gap-xxl-0{gap:0 !important}.gap-xxl-1{gap:.25rem !important}.gap-xxl-2{gap:.5rem !important}.gap-xxl-3{gap:1rem !important}.gap-xxl-4{gap:1.5rem !important}.gap-xxl-5{gap:3rem !important}.row-gap-xxl-0{row-gap:0 !important}.row-gap-xxl-1{row-gap:.25rem !important}.row-gap-xxl-2{row-gap:.5rem !important}.row-gap-xxl-3{row-gap:1rem !important}.row-gap-xxl-4{row-gap:1.5rem !important}.row-gap-xxl-5{row-gap:3rem !important}.column-gap-xxl-0{column-gap:0 !important}.column-gap-xxl-1{column-gap:.25rem !important}.column-gap-xxl-2{column-gap:.5rem !important}.column-gap-xxl-3{column-gap:1rem !important}.column-gap-xxl-4{column-gap:1.5rem !important}.column-gap-xxl-5{column-gap:3rem !important}.text-xxl-start{text-align:left !important}.text-xxl-end{text-align:right !important}.text-xxl-center{text-align:center !important}}.bg-default{color:#000}.bg-primary{color:#fff}.bg-secondary{color:#fff}.bg-success{color:#fff}.bg-info{color:#000}.bg-warning{color:#000}.bg-danger{color:#fff}.bg-light{color:#000}.bg-dark{color:#fff}@media(min-width: 1200px){.fs-1{font-size:2rem !important}.fs-2{font-size:1.65rem !important}.fs-3{font-size:1.45rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-inline-grid{display:inline-grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}:root{--bslib-spacer: 1rem;--bslib-mb-spacer: var(--bslib-spacer, 1rem)}.bslib-mb-spacing{margin-bottom:var(--bslib-mb-spacer)}.bslib-gap-spacing{gap:var(--bslib-mb-spacer)}.bslib-gap-spacing>.bslib-mb-spacing,.bslib-gap-spacing>.form-group,.bslib-gap-spacing>p,.bslib-gap-spacing>pre{margin-bottom:0}.html-fill-container>.html-fill-item.bslib-mb-spacing{margin-bottom:0}.tab-content>.tab-pane.html-fill-container{display:none}.tab-content>.active.html-fill-container{display:flex}.tab-content.html-fill-container{padding:0}.bg-blue{--bslib-color-bg: #0d6efd;--bslib-color-fg: #ffffff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-blue{--bslib-color-fg: #0d6efd;color:var(--bslib-color-fg)}.bg-indigo{--bslib-color-bg: #6610f2;--bslib-color-fg: #ffffff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-indigo{--bslib-color-fg: #6610f2;color:var(--bslib-color-fg)}.bg-purple{--bslib-color-bg: #6f42c1;--bslib-color-fg: #ffffff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-purple{--bslib-color-fg: #6f42c1;color:var(--bslib-color-fg)}.bg-pink{--bslib-color-bg: #d63384;--bslib-color-fg: #ffffff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-pink{--bslib-color-fg: #d63384;color:var(--bslib-color-fg)}.bg-red{--bslib-color-bg: #dc3545;--bslib-color-fg: #ffffff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-red{--bslib-color-fg: #dc3545;color:var(--bslib-color-fg)}.bg-orange{--bslib-color-bg: #fd7e14;--bslib-color-fg: #000;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-orange{--bslib-color-fg: #fd7e14;color:var(--bslib-color-fg)}.bg-yellow{--bslib-color-bg: #ffc107;--bslib-color-fg: #000;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-yellow{--bslib-color-fg: #ffc107;color:var(--bslib-color-fg)}.bg-green{--bslib-color-bg: #198754;--bslib-color-fg: #ffffff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-green{--bslib-color-fg: #198754;color:var(--bslib-color-fg)}.bg-teal{--bslib-color-bg: #20c997;--bslib-color-fg: #000;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-teal{--bslib-color-fg: #20c997;color:var(--bslib-color-fg)}.bg-cyan{--bslib-color-bg: #0dcaf0;--bslib-color-fg: #000;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-cyan{--bslib-color-fg: #0dcaf0;color:var(--bslib-color-fg)}.text-default{--bslib-color-fg: #dee2e6}.bg-default{--bslib-color-bg: #dee2e6;--bslib-color-fg: #000}.text-primary{--bslib-color-fg: #0d6efd}.bg-primary{--bslib-color-bg: #0d6efd;--bslib-color-fg: #ffffff}.text-secondary{--bslib-color-fg: #6c757d}.bg-secondary{--bslib-color-bg: #6c757d;--bslib-color-fg: #ffffff}.text-success{--bslib-color-fg: #198754}.bg-success{--bslib-color-bg: #198754;--bslib-color-fg: #ffffff}.text-info{--bslib-color-fg: #0dcaf0}.bg-info{--bslib-color-bg: #0dcaf0;--bslib-color-fg: #000}.text-warning{--bslib-color-fg: #ffc107}.bg-warning{--bslib-color-bg: #ffc107;--bslib-color-fg: #000}.text-danger{--bslib-color-fg: #dc3545}.bg-danger{--bslib-color-bg: #dc3545;--bslib-color-fg: #ffffff}.text-light{--bslib-color-fg: #f8f9fa}.bg-light{--bslib-color-bg: #f8f9fa;--bslib-color-fg: #000}.text-dark{--bslib-color-fg: #212529}.bg-dark{--bslib-color-bg: #212529;--bslib-color-fg: #ffffff}.bg-gradient-blue-indigo{--bslib-color-fg: #ffffff;--bslib-color-bg: #3148f9;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0d6efd var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #3148f9;color:#fff}.bg-gradient-blue-purple{--bslib-color-fg: #ffffff;--bslib-color-bg: #345ce5;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0d6efd var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) #345ce5;color:#fff}.bg-gradient-blue-pink{--bslib-color-fg: #ffffff;--bslib-color-bg: #5d56cd;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0d6efd var(--bg-gradient-start, 36%), #d63384 var(--bg-gradient-end, 180%)) #5d56cd;color:#fff}.bg-gradient-blue-red{--bslib-color-fg: #ffffff;--bslib-color-bg: #6057b3;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0d6efd var(--bg-gradient-start, 36%), #dc3545 var(--bg-gradient-end, 180%)) #6057b3;color:#fff}.bg-gradient-blue-orange{--bslib-color-fg: #ffffff;--bslib-color-bg: #6d74a0;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0d6efd var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) #6d74a0;color:#fff}.bg-gradient-blue-yellow{--bslib-color-fg: #000;--bslib-color-bg: #6e8f9b;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0d6efd var(--bg-gradient-start, 36%), #ffc107 var(--bg-gradient-end, 180%)) #6e8f9b;color:#000}.bg-gradient-blue-green{--bslib-color-fg: #ffffff;--bslib-color-bg: #1278b9;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0d6efd var(--bg-gradient-start, 36%), #198754 var(--bg-gradient-end, 180%)) #1278b9;color:#fff}.bg-gradient-blue-teal{--bslib-color-fg: #000;--bslib-color-bg: #1592d4;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0d6efd var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #1592d4;color:#000}.bg-gradient-blue-cyan{--bslib-color-fg: #000;--bslib-color-bg: #0d93f8;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0d6efd var(--bg-gradient-start, 36%), #0dcaf0 var(--bg-gradient-end, 180%)) #0d93f8;color:#000}.bg-gradient-indigo-blue{--bslib-color-fg: #ffffff;--bslib-color-bg: #4236f6;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #0d6efd var(--bg-gradient-end, 180%)) #4236f6;color:#fff}.bg-gradient-indigo-purple{--bslib-color-fg: #ffffff;--bslib-color-bg: #6a24de;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) #6a24de;color:#fff}.bg-gradient-indigo-pink{--bslib-color-fg: #ffffff;--bslib-color-bg: #931ec6;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #d63384 var(--bg-gradient-end, 180%)) #931ec6;color:#fff}.bg-gradient-indigo-red{--bslib-color-fg: #ffffff;--bslib-color-bg: #951fad;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #dc3545 var(--bg-gradient-end, 180%)) #951fad;color:#fff}.bg-gradient-indigo-orange{--bslib-color-fg: #ffffff;--bslib-color-bg: #a23c99;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) #a23c99;color:#fff}.bg-gradient-indigo-yellow{--bslib-color-fg: #ffffff;--bslib-color-bg: #a35794;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #ffc107 var(--bg-gradient-end, 180%)) #a35794;color:#fff}.bg-gradient-indigo-green{--bslib-color-fg: #ffffff;--bslib-color-bg: #4740b3;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #198754 var(--bg-gradient-end, 180%)) #4740b3;color:#fff}.bg-gradient-indigo-teal{--bslib-color-fg: #ffffff;--bslib-color-bg: #4a5ace;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #4a5ace;color:#fff}.bg-gradient-indigo-cyan{--bslib-color-fg: #ffffff;--bslib-color-bg: #425af1;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #0dcaf0 var(--bg-gradient-end, 180%)) #425af1;color:#fff}.bg-gradient-purple-blue{--bslib-color-fg: #ffffff;--bslib-color-bg: #4854d9;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #0d6efd var(--bg-gradient-end, 180%)) #4854d9;color:#fff}.bg-gradient-purple-indigo{--bslib-color-fg: #ffffff;--bslib-color-bg: #6b2ed5;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #6b2ed5;color:#fff}.bg-gradient-purple-pink{--bslib-color-fg: #ffffff;--bslib-color-bg: #983ca9;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #d63384 var(--bg-gradient-end, 180%)) #983ca9;color:#fff}.bg-gradient-purple-red{--bslib-color-fg: #ffffff;--bslib-color-bg: #9b3d8f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #dc3545 var(--bg-gradient-end, 180%)) #9b3d8f;color:#fff}.bg-gradient-purple-orange{--bslib-color-fg: #ffffff;--bslib-color-bg: #a85a7c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) #a85a7c;color:#fff}.bg-gradient-purple-yellow{--bslib-color-fg: #000;--bslib-color-bg: #a97577;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #ffc107 var(--bg-gradient-end, 180%)) #a97577;color:#000}.bg-gradient-purple-green{--bslib-color-fg: #ffffff;--bslib-color-bg: #4d5e95;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #198754 var(--bg-gradient-end, 180%)) #4d5e95;color:#fff}.bg-gradient-purple-teal{--bslib-color-fg: #ffffff;--bslib-color-bg: #4f78b0;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #4f78b0;color:#fff}.bg-gradient-purple-cyan{--bslib-color-fg: #000;--bslib-color-bg: #4878d4;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #0dcaf0 var(--bg-gradient-end, 180%)) #4878d4;color:#000}.bg-gradient-pink-blue{--bslib-color-fg: #ffffff;--bslib-color-bg: #864bb4;background:linear-gradient(var(--bg-gradient-deg, 140deg), #d63384 var(--bg-gradient-start, 36%), #0d6efd var(--bg-gradient-end, 180%)) #864bb4;color:#fff}.bg-gradient-pink-indigo{--bslib-color-fg: #ffffff;--bslib-color-bg: #a925b0;background:linear-gradient(var(--bg-gradient-deg, 140deg), #d63384 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #a925b0;color:#fff}.bg-gradient-pink-purple{--bslib-color-fg: #ffffff;--bslib-color-bg: #ad399c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #d63384 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) #ad399c;color:#fff}.bg-gradient-pink-red{--bslib-color-fg: #ffffff;--bslib-color-bg: #d8346b;background:linear-gradient(var(--bg-gradient-deg, 140deg), #d63384 var(--bg-gradient-start, 36%), #dc3545 var(--bg-gradient-end, 180%)) #d8346b;color:#fff}.bg-gradient-pink-orange{--bslib-color-fg: #000;--bslib-color-bg: #e65157;background:linear-gradient(var(--bg-gradient-deg, 140deg), #d63384 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) #e65157;color:#000}.bg-gradient-pink-yellow{--bslib-color-fg: #000;--bslib-color-bg: #e66c52;background:linear-gradient(var(--bg-gradient-deg, 140deg), #d63384 var(--bg-gradient-start, 36%), #ffc107 var(--bg-gradient-end, 180%)) #e66c52;color:#000}.bg-gradient-pink-green{--bslib-color-fg: #ffffff;--bslib-color-bg: #8a5571;background:linear-gradient(var(--bg-gradient-deg, 140deg), #d63384 var(--bg-gradient-start, 36%), #198754 var(--bg-gradient-end, 180%)) #8a5571;color:#fff}.bg-gradient-pink-teal{--bslib-color-fg: #000;--bslib-color-bg: #8d6f8c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #d63384 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #8d6f8c;color:#000}.bg-gradient-pink-cyan{--bslib-color-fg: #000;--bslib-color-bg: #866faf;background:linear-gradient(var(--bg-gradient-deg, 140deg), #d63384 var(--bg-gradient-start, 36%), #0dcaf0 var(--bg-gradient-end, 180%)) #866faf;color:#000}.bg-gradient-red-blue{--bslib-color-fg: #ffffff;--bslib-color-bg: #894c8f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #dc3545 var(--bg-gradient-start, 36%), #0d6efd var(--bg-gradient-end, 180%)) #894c8f;color:#fff}.bg-gradient-red-indigo{--bslib-color-fg: #ffffff;--bslib-color-bg: #ad268a;background:linear-gradient(var(--bg-gradient-deg, 140deg), #dc3545 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #ad268a;color:#fff}.bg-gradient-red-purple{--bslib-color-fg: #ffffff;--bslib-color-bg: #b03a77;background:linear-gradient(var(--bg-gradient-deg, 140deg), #dc3545 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) #b03a77;color:#fff}.bg-gradient-red-pink{--bslib-color-fg: #ffffff;--bslib-color-bg: #da345e;background:linear-gradient(var(--bg-gradient-deg, 140deg), #dc3545 var(--bg-gradient-start, 36%), #d63384 var(--bg-gradient-end, 180%)) #da345e;color:#fff}.bg-gradient-red-orange{--bslib-color-fg: #000;--bslib-color-bg: #e95231;background:linear-gradient(var(--bg-gradient-deg, 140deg), #dc3545 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) #e95231;color:#000}.bg-gradient-red-yellow{--bslib-color-fg: #000;--bslib-color-bg: #ea6d2c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #dc3545 var(--bg-gradient-start, 36%), #ffc107 var(--bg-gradient-end, 180%)) #ea6d2c;color:#000}.bg-gradient-red-green{--bslib-color-fg: #ffffff;--bslib-color-bg: #8e564b;background:linear-gradient(var(--bg-gradient-deg, 140deg), #dc3545 var(--bg-gradient-start, 36%), #198754 var(--bg-gradient-end, 180%)) #8e564b;color:#fff}.bg-gradient-red-teal{--bslib-color-fg: #000;--bslib-color-bg: #917066;background:linear-gradient(var(--bg-gradient-deg, 140deg), #dc3545 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #917066;color:#000}.bg-gradient-red-cyan{--bslib-color-fg: #000;--bslib-color-bg: #897189;background:linear-gradient(var(--bg-gradient-deg, 140deg), #dc3545 var(--bg-gradient-start, 36%), #0dcaf0 var(--bg-gradient-end, 180%)) #897189;color:#000}.bg-gradient-orange-blue{--bslib-color-fg: #000;--bslib-color-bg: #9d7871;background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #0d6efd var(--bg-gradient-end, 180%)) #9d7871;color:#000}.bg-gradient-orange-indigo{--bslib-color-fg: #000;--bslib-color-bg: #c1526d;background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #c1526d;color:#000}.bg-gradient-orange-purple{--bslib-color-fg: #000;--bslib-color-bg: #c46659;background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) #c46659;color:#000}.bg-gradient-orange-pink{--bslib-color-fg: #000;--bslib-color-bg: #ed6041;background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #d63384 var(--bg-gradient-end, 180%)) #ed6041;color:#000}.bg-gradient-orange-red{--bslib-color-fg: #000;--bslib-color-bg: #f06128;background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #dc3545 var(--bg-gradient-end, 180%)) #f06128;color:#000}.bg-gradient-orange-yellow{--bslib-color-fg: #000;--bslib-color-bg: #fe990f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #ffc107 var(--bg-gradient-end, 180%)) #fe990f;color:#000}.bg-gradient-orange-green{--bslib-color-fg: #000;--bslib-color-bg: #a2822e;background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #198754 var(--bg-gradient-end, 180%)) #a2822e;color:#000}.bg-gradient-orange-teal{--bslib-color-fg: #000;--bslib-color-bg: #a59c48;background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #a59c48;color:#000}.bg-gradient-orange-cyan{--bslib-color-fg: #000;--bslib-color-bg: #9d9c6c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #0dcaf0 var(--bg-gradient-end, 180%)) #9d9c6c;color:#000}.bg-gradient-yellow-blue{--bslib-color-fg: #000;--bslib-color-bg: #9ea069;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ffc107 var(--bg-gradient-start, 36%), #0d6efd var(--bg-gradient-end, 180%)) #9ea069;color:#000}.bg-gradient-yellow-indigo{--bslib-color-fg: #000;--bslib-color-bg: #c27a65;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ffc107 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #c27a65;color:#000}.bg-gradient-yellow-purple{--bslib-color-fg: #000;--bslib-color-bg: #c58e51;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ffc107 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) #c58e51;color:#000}.bg-gradient-yellow-pink{--bslib-color-fg: #000;--bslib-color-bg: #ef8839;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ffc107 var(--bg-gradient-start, 36%), #d63384 var(--bg-gradient-end, 180%)) #ef8839;color:#000}.bg-gradient-yellow-red{--bslib-color-fg: #000;--bslib-color-bg: #f18920;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ffc107 var(--bg-gradient-start, 36%), #dc3545 var(--bg-gradient-end, 180%)) #f18920;color:#000}.bg-gradient-yellow-orange{--bslib-color-fg: #000;--bslib-color-bg: #fea60c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ffc107 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) #fea60c;color:#000}.bg-gradient-yellow-green{--bslib-color-fg: #000;--bslib-color-bg: #a3aa26;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ffc107 var(--bg-gradient-start, 36%), #198754 var(--bg-gradient-end, 180%)) #a3aa26;color:#000}.bg-gradient-yellow-teal{--bslib-color-fg: #000;--bslib-color-bg: #a6c441;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ffc107 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #a6c441;color:#000}.bg-gradient-yellow-cyan{--bslib-color-fg: #000;--bslib-color-bg: #9ec564;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ffc107 var(--bg-gradient-start, 36%), #0dcaf0 var(--bg-gradient-end, 180%)) #9ec564;color:#000}.bg-gradient-green-blue{--bslib-color-fg: #ffffff;--bslib-color-bg: #147d98;background:linear-gradient(var(--bg-gradient-deg, 140deg), #198754 var(--bg-gradient-start, 36%), #0d6efd var(--bg-gradient-end, 180%)) #147d98;color:#fff}.bg-gradient-green-indigo{--bslib-color-fg: #ffffff;--bslib-color-bg: #385793;background:linear-gradient(var(--bg-gradient-deg, 140deg), #198754 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #385793;color:#fff}.bg-gradient-green-purple{--bslib-color-fg: #ffffff;--bslib-color-bg: #3b6b80;background:linear-gradient(var(--bg-gradient-deg, 140deg), #198754 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) #3b6b80;color:#fff}.bg-gradient-green-pink{--bslib-color-fg: #ffffff;--bslib-color-bg: #656567;background:linear-gradient(var(--bg-gradient-deg, 140deg), #198754 var(--bg-gradient-start, 36%), #d63384 var(--bg-gradient-end, 180%)) #656567;color:#fff}.bg-gradient-green-red{--bslib-color-fg: #ffffff;--bslib-color-bg: #67664e;background:linear-gradient(var(--bg-gradient-deg, 140deg), #198754 var(--bg-gradient-start, 36%), #dc3545 var(--bg-gradient-end, 180%)) #67664e;color:#fff}.bg-gradient-green-orange{--bslib-color-fg: #000;--bslib-color-bg: #74833a;background:linear-gradient(var(--bg-gradient-deg, 140deg), #198754 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) #74833a;color:#000}.bg-gradient-green-yellow{--bslib-color-fg: #000;--bslib-color-bg: #759e35;background:linear-gradient(var(--bg-gradient-deg, 140deg), #198754 var(--bg-gradient-start, 36%), #ffc107 var(--bg-gradient-end, 180%)) #759e35;color:#000}.bg-gradient-green-teal{--bslib-color-fg: #000;--bslib-color-bg: #1ca16f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #198754 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #1ca16f;color:#000}.bg-gradient-green-cyan{--bslib-color-fg: #000;--bslib-color-bg: #14a292;background:linear-gradient(var(--bg-gradient-deg, 140deg), #198754 var(--bg-gradient-start, 36%), #0dcaf0 var(--bg-gradient-end, 180%)) #14a292;color:#000}.bg-gradient-teal-blue{--bslib-color-fg: #000;--bslib-color-bg: #18a5c0;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #0d6efd var(--bg-gradient-end, 180%)) #18a5c0;color:#000}.bg-gradient-teal-indigo{--bslib-color-fg: #000;--bslib-color-bg: #3c7fbb;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #3c7fbb;color:#000}.bg-gradient-teal-purple{--bslib-color-fg: #000;--bslib-color-bg: #4093a8;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) #4093a8;color:#000}.bg-gradient-teal-pink{--bslib-color-fg: #000;--bslib-color-bg: #698d8f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #d63384 var(--bg-gradient-end, 180%)) #698d8f;color:#000}.bg-gradient-teal-red{--bslib-color-fg: #000;--bslib-color-bg: #6b8e76;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #dc3545 var(--bg-gradient-end, 180%)) #6b8e76;color:#000}.bg-gradient-teal-orange{--bslib-color-fg: #000;--bslib-color-bg: #78ab63;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) #78ab63;color:#000}.bg-gradient-teal-yellow{--bslib-color-fg: #000;--bslib-color-bg: #79c65d;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #ffc107 var(--bg-gradient-end, 180%)) #79c65d;color:#000}.bg-gradient-teal-green{--bslib-color-fg: #000;--bslib-color-bg: #1daf7c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #198754 var(--bg-gradient-end, 180%)) #1daf7c;color:#000}.bg-gradient-teal-cyan{--bslib-color-fg: #000;--bslib-color-bg: #18c9bb;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #0dcaf0 var(--bg-gradient-end, 180%)) #18c9bb;color:#000}.bg-gradient-cyan-blue{--bslib-color-fg: #000;--bslib-color-bg: #0da5f5;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0dcaf0 var(--bg-gradient-start, 36%), #0d6efd var(--bg-gradient-end, 180%)) #0da5f5;color:#000}.bg-gradient-cyan-indigo{--bslib-color-fg: #000;--bslib-color-bg: #3180f1;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0dcaf0 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #3180f1;color:#000}.bg-gradient-cyan-purple{--bslib-color-fg: #000;--bslib-color-bg: #3494dd;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0dcaf0 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) #3494dd;color:#000}.bg-gradient-cyan-pink{--bslib-color-fg: #000;--bslib-color-bg: #5d8ec5;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0dcaf0 var(--bg-gradient-start, 36%), #d63384 var(--bg-gradient-end, 180%)) #5d8ec5;color:#000}.bg-gradient-cyan-red{--bslib-color-fg: #000;--bslib-color-bg: #608eac;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0dcaf0 var(--bg-gradient-start, 36%), #dc3545 var(--bg-gradient-end, 180%)) #608eac;color:#000}.bg-gradient-cyan-orange{--bslib-color-fg: #000;--bslib-color-bg: #6dac98;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0dcaf0 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) #6dac98;color:#000}.bg-gradient-cyan-yellow{--bslib-color-fg: #000;--bslib-color-bg: #6ec693;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0dcaf0 var(--bg-gradient-start, 36%), #ffc107 var(--bg-gradient-end, 180%)) #6ec693;color:#000}.bg-gradient-cyan-green{--bslib-color-fg: #000;--bslib-color-bg: #12afb2;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0dcaf0 var(--bg-gradient-start, 36%), #198754 var(--bg-gradient-end, 180%)) #12afb2;color:#000}.bg-gradient-cyan-teal{--bslib-color-fg: #000;--bslib-color-bg: #15cacc;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0dcaf0 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #15cacc;color:#000}.tab-content>.tab-pane.html-fill-container{display:none}.tab-content>.active.html-fill-container{display:flex}.tab-content.html-fill-container{padding:0}:root{--bslib-spacer: 1rem;--bslib-mb-spacer: var(--bslib-spacer, 1rem)}.bslib-mb-spacing{margin-bottom:var(--bslib-mb-spacer)}.bslib-gap-spacing{gap:var(--bslib-mb-spacer)}.bslib-gap-spacing>.bslib-mb-spacing,.bslib-gap-spacing>.form-group,.bslib-gap-spacing>p,.bslib-gap-spacing>pre{margin-bottom:0}.html-fill-container>.html-fill-item.bslib-mb-spacing{margin-bottom:0}.bg-blue{--bslib-color-bg: #0d6efd;--bslib-color-fg: #ffffff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-blue{--bslib-color-fg: #0d6efd;color:var(--bslib-color-fg)}.bg-indigo{--bslib-color-bg: #6610f2;--bslib-color-fg: #ffffff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-indigo{--bslib-color-fg: #6610f2;color:var(--bslib-color-fg)}.bg-purple{--bslib-color-bg: #6f42c1;--bslib-color-fg: #ffffff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-purple{--bslib-color-fg: #6f42c1;color:var(--bslib-color-fg)}.bg-pink{--bslib-color-bg: #d63384;--bslib-color-fg: #ffffff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-pink{--bslib-color-fg: #d63384;color:var(--bslib-color-fg)}.bg-red{--bslib-color-bg: #dc3545;--bslib-color-fg: #ffffff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-red{--bslib-color-fg: #dc3545;color:var(--bslib-color-fg)}.bg-orange{--bslib-color-bg: #fd7e14;--bslib-color-fg: #000;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-orange{--bslib-color-fg: #fd7e14;color:var(--bslib-color-fg)}.bg-yellow{--bslib-color-bg: #ffc107;--bslib-color-fg: #000;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-yellow{--bslib-color-fg: #ffc107;color:var(--bslib-color-fg)}.bg-green{--bslib-color-bg: #198754;--bslib-color-fg: #ffffff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-green{--bslib-color-fg: #198754;color:var(--bslib-color-fg)}.bg-teal{--bslib-color-bg: #20c997;--bslib-color-fg: #000;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-teal{--bslib-color-fg: #20c997;color:var(--bslib-color-fg)}.bg-cyan{--bslib-color-bg: #0dcaf0;--bslib-color-fg: #000;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-cyan{--bslib-color-fg: #0dcaf0;color:var(--bslib-color-fg)}.text-default{--bslib-color-fg: #dee2e6}.bg-default{--bslib-color-bg: #dee2e6;--bslib-color-fg: #000}.text-primary{--bslib-color-fg: #0d6efd}.bg-primary{--bslib-color-bg: #0d6efd;--bslib-color-fg: #ffffff}.text-secondary{--bslib-color-fg: #6c757d}.bg-secondary{--bslib-color-bg: #6c757d;--bslib-color-fg: #ffffff}.text-success{--bslib-color-fg: #198754}.bg-success{--bslib-color-bg: #198754;--bslib-color-fg: #ffffff}.text-info{--bslib-color-fg: #0dcaf0}.bg-info{--bslib-color-bg: #0dcaf0;--bslib-color-fg: #000}.text-warning{--bslib-color-fg: #ffc107}.bg-warning{--bslib-color-bg: #ffc107;--bslib-color-fg: #000}.text-danger{--bslib-color-fg: #dc3545}.bg-danger{--bslib-color-bg: #dc3545;--bslib-color-fg: #ffffff}.text-light{--bslib-color-fg: #f8f9fa}.bg-light{--bslib-color-bg: #f8f9fa;--bslib-color-fg: #000}.text-dark{--bslib-color-fg: #212529}.bg-dark{--bslib-color-bg: #212529;--bslib-color-fg: #ffffff}.bg-gradient-blue-indigo{--bslib-color-fg: #ffffff;--bslib-color-bg: #3148f9;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0d6efd var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #3148f9;color:#fff}.bg-gradient-blue-purple{--bslib-color-fg: #ffffff;--bslib-color-bg: #345ce5;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0d6efd var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) #345ce5;color:#fff}.bg-gradient-blue-pink{--bslib-color-fg: #ffffff;--bslib-color-bg: #5d56cd;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0d6efd var(--bg-gradient-start, 36%), #d63384 var(--bg-gradient-end, 180%)) #5d56cd;color:#fff}.bg-gradient-blue-red{--bslib-color-fg: #ffffff;--bslib-color-bg: #6057b3;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0d6efd var(--bg-gradient-start, 36%), #dc3545 var(--bg-gradient-end, 180%)) #6057b3;color:#fff}.bg-gradient-blue-orange{--bslib-color-fg: #ffffff;--bslib-color-bg: #6d74a0;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0d6efd var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) #6d74a0;color:#fff}.bg-gradient-blue-yellow{--bslib-color-fg: #000;--bslib-color-bg: #6e8f9b;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0d6efd var(--bg-gradient-start, 36%), #ffc107 var(--bg-gradient-end, 180%)) #6e8f9b;color:#000}.bg-gradient-blue-green{--bslib-color-fg: #ffffff;--bslib-color-bg: #1278b9;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0d6efd var(--bg-gradient-start, 36%), #198754 var(--bg-gradient-end, 180%)) #1278b9;color:#fff}.bg-gradient-blue-teal{--bslib-color-fg: #000;--bslib-color-bg: #1592d4;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0d6efd var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #1592d4;color:#000}.bg-gradient-blue-cyan{--bslib-color-fg: #000;--bslib-color-bg: #0d93f8;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0d6efd var(--bg-gradient-start, 36%), #0dcaf0 var(--bg-gradient-end, 180%)) #0d93f8;color:#000}.bg-gradient-indigo-blue{--bslib-color-fg: #ffffff;--bslib-color-bg: #4236f6;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #0d6efd var(--bg-gradient-end, 180%)) #4236f6;color:#fff}.bg-gradient-indigo-purple{--bslib-color-fg: #ffffff;--bslib-color-bg: #6a24de;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) #6a24de;color:#fff}.bg-gradient-indigo-pink{--bslib-color-fg: #ffffff;--bslib-color-bg: #931ec6;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #d63384 var(--bg-gradient-end, 180%)) #931ec6;color:#fff}.bg-gradient-indigo-red{--bslib-color-fg: #ffffff;--bslib-color-bg: #951fad;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #dc3545 var(--bg-gradient-end, 180%)) #951fad;color:#fff}.bg-gradient-indigo-orange{--bslib-color-fg: #ffffff;--bslib-color-bg: #a23c99;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) #a23c99;color:#fff}.bg-gradient-indigo-yellow{--bslib-color-fg: #ffffff;--bslib-color-bg: #a35794;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #ffc107 var(--bg-gradient-end, 180%)) #a35794;color:#fff}.bg-gradient-indigo-green{--bslib-color-fg: #ffffff;--bslib-color-bg: #4740b3;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #198754 var(--bg-gradient-end, 180%)) #4740b3;color:#fff}.bg-gradient-indigo-teal{--bslib-color-fg: #ffffff;--bslib-color-bg: #4a5ace;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #4a5ace;color:#fff}.bg-gradient-indigo-cyan{--bslib-color-fg: #ffffff;--bslib-color-bg: #425af1;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #0dcaf0 var(--bg-gradient-end, 180%)) #425af1;color:#fff}.bg-gradient-purple-blue{--bslib-color-fg: #ffffff;--bslib-color-bg: #4854d9;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #0d6efd var(--bg-gradient-end, 180%)) #4854d9;color:#fff}.bg-gradient-purple-indigo{--bslib-color-fg: #ffffff;--bslib-color-bg: #6b2ed5;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #6b2ed5;color:#fff}.bg-gradient-purple-pink{--bslib-color-fg: #ffffff;--bslib-color-bg: #983ca9;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #d63384 var(--bg-gradient-end, 180%)) #983ca9;color:#fff}.bg-gradient-purple-red{--bslib-color-fg: #ffffff;--bslib-color-bg: #9b3d8f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #dc3545 var(--bg-gradient-end, 180%)) #9b3d8f;color:#fff}.bg-gradient-purple-orange{--bslib-color-fg: #ffffff;--bslib-color-bg: #a85a7c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) #a85a7c;color:#fff}.bg-gradient-purple-yellow{--bslib-color-fg: #000;--bslib-color-bg: #a97577;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #ffc107 var(--bg-gradient-end, 180%)) #a97577;color:#000}.bg-gradient-purple-green{--bslib-color-fg: #ffffff;--bslib-color-bg: #4d5e95;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #198754 var(--bg-gradient-end, 180%)) #4d5e95;color:#fff}.bg-gradient-purple-teal{--bslib-color-fg: #ffffff;--bslib-color-bg: #4f78b0;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #4f78b0;color:#fff}.bg-gradient-purple-cyan{--bslib-color-fg: #000;--bslib-color-bg: #4878d4;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #0dcaf0 var(--bg-gradient-end, 180%)) #4878d4;color:#000}.bg-gradient-pink-blue{--bslib-color-fg: #ffffff;--bslib-color-bg: #864bb4;background:linear-gradient(var(--bg-gradient-deg, 140deg), #d63384 var(--bg-gradient-start, 36%), #0d6efd var(--bg-gradient-end, 180%)) #864bb4;color:#fff}.bg-gradient-pink-indigo{--bslib-color-fg: #ffffff;--bslib-color-bg: #a925b0;background:linear-gradient(var(--bg-gradient-deg, 140deg), #d63384 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #a925b0;color:#fff}.bg-gradient-pink-purple{--bslib-color-fg: #ffffff;--bslib-color-bg: #ad399c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #d63384 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) #ad399c;color:#fff}.bg-gradient-pink-red{--bslib-color-fg: #ffffff;--bslib-color-bg: #d8346b;background:linear-gradient(var(--bg-gradient-deg, 140deg), #d63384 var(--bg-gradient-start, 36%), #dc3545 var(--bg-gradient-end, 180%)) #d8346b;color:#fff}.bg-gradient-pink-orange{--bslib-color-fg: #000;--bslib-color-bg: #e65157;background:linear-gradient(var(--bg-gradient-deg, 140deg), #d63384 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) #e65157;color:#000}.bg-gradient-pink-yellow{--bslib-color-fg: #000;--bslib-color-bg: #e66c52;background:linear-gradient(var(--bg-gradient-deg, 140deg), #d63384 var(--bg-gradient-start, 36%), #ffc107 var(--bg-gradient-end, 180%)) #e66c52;color:#000}.bg-gradient-pink-green{--bslib-color-fg: #ffffff;--bslib-color-bg: #8a5571;background:linear-gradient(var(--bg-gradient-deg, 140deg), #d63384 var(--bg-gradient-start, 36%), #198754 var(--bg-gradient-end, 180%)) #8a5571;color:#fff}.bg-gradient-pink-teal{--bslib-color-fg: #000;--bslib-color-bg: #8d6f8c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #d63384 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #8d6f8c;color:#000}.bg-gradient-pink-cyan{--bslib-color-fg: #000;--bslib-color-bg: #866faf;background:linear-gradient(var(--bg-gradient-deg, 140deg), #d63384 var(--bg-gradient-start, 36%), #0dcaf0 var(--bg-gradient-end, 180%)) #866faf;color:#000}.bg-gradient-red-blue{--bslib-color-fg: #ffffff;--bslib-color-bg: #894c8f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #dc3545 var(--bg-gradient-start, 36%), #0d6efd var(--bg-gradient-end, 180%)) #894c8f;color:#fff}.bg-gradient-red-indigo{--bslib-color-fg: #ffffff;--bslib-color-bg: #ad268a;background:linear-gradient(var(--bg-gradient-deg, 140deg), #dc3545 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #ad268a;color:#fff}.bg-gradient-red-purple{--bslib-color-fg: #ffffff;--bslib-color-bg: #b03a77;background:linear-gradient(var(--bg-gradient-deg, 140deg), #dc3545 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) #b03a77;color:#fff}.bg-gradient-red-pink{--bslib-color-fg: #ffffff;--bslib-color-bg: #da345e;background:linear-gradient(var(--bg-gradient-deg, 140deg), #dc3545 var(--bg-gradient-start, 36%), #d63384 var(--bg-gradient-end, 180%)) #da345e;color:#fff}.bg-gradient-red-orange{--bslib-color-fg: #000;--bslib-color-bg: #e95231;background:linear-gradient(var(--bg-gradient-deg, 140deg), #dc3545 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) #e95231;color:#000}.bg-gradient-red-yellow{--bslib-color-fg: #000;--bslib-color-bg: #ea6d2c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #dc3545 var(--bg-gradient-start, 36%), #ffc107 var(--bg-gradient-end, 180%)) #ea6d2c;color:#000}.bg-gradient-red-green{--bslib-color-fg: #ffffff;--bslib-color-bg: #8e564b;background:linear-gradient(var(--bg-gradient-deg, 140deg), #dc3545 var(--bg-gradient-start, 36%), #198754 var(--bg-gradient-end, 180%)) #8e564b;color:#fff}.bg-gradient-red-teal{--bslib-color-fg: #000;--bslib-color-bg: #917066;background:linear-gradient(var(--bg-gradient-deg, 140deg), #dc3545 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #917066;color:#000}.bg-gradient-red-cyan{--bslib-color-fg: #000;--bslib-color-bg: #897189;background:linear-gradient(var(--bg-gradient-deg, 140deg), #dc3545 var(--bg-gradient-start, 36%), #0dcaf0 var(--bg-gradient-end, 180%)) #897189;color:#000}.bg-gradient-orange-blue{--bslib-color-fg: #000;--bslib-color-bg: #9d7871;background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #0d6efd var(--bg-gradient-end, 180%)) #9d7871;color:#000}.bg-gradient-orange-indigo{--bslib-color-fg: #000;--bslib-color-bg: #c1526d;background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #c1526d;color:#000}.bg-gradient-orange-purple{--bslib-color-fg: #000;--bslib-color-bg: #c46659;background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) #c46659;color:#000}.bg-gradient-orange-pink{--bslib-color-fg: #000;--bslib-color-bg: #ed6041;background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #d63384 var(--bg-gradient-end, 180%)) #ed6041;color:#000}.bg-gradient-orange-red{--bslib-color-fg: #000;--bslib-color-bg: #f06128;background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #dc3545 var(--bg-gradient-end, 180%)) #f06128;color:#000}.bg-gradient-orange-yellow{--bslib-color-fg: #000;--bslib-color-bg: #fe990f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #ffc107 var(--bg-gradient-end, 180%)) #fe990f;color:#000}.bg-gradient-orange-green{--bslib-color-fg: #000;--bslib-color-bg: #a2822e;background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #198754 var(--bg-gradient-end, 180%)) #a2822e;color:#000}.bg-gradient-orange-teal{--bslib-color-fg: #000;--bslib-color-bg: #a59c48;background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #a59c48;color:#000}.bg-gradient-orange-cyan{--bslib-color-fg: #000;--bslib-color-bg: #9d9c6c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #0dcaf0 var(--bg-gradient-end, 180%)) #9d9c6c;color:#000}.bg-gradient-yellow-blue{--bslib-color-fg: #000;--bslib-color-bg: #9ea069;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ffc107 var(--bg-gradient-start, 36%), #0d6efd var(--bg-gradient-end, 180%)) #9ea069;color:#000}.bg-gradient-yellow-indigo{--bslib-color-fg: #000;--bslib-color-bg: #c27a65;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ffc107 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #c27a65;color:#000}.bg-gradient-yellow-purple{--bslib-color-fg: #000;--bslib-color-bg: #c58e51;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ffc107 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) #c58e51;color:#000}.bg-gradient-yellow-pink{--bslib-color-fg: #000;--bslib-color-bg: #ef8839;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ffc107 var(--bg-gradient-start, 36%), #d63384 var(--bg-gradient-end, 180%)) #ef8839;color:#000}.bg-gradient-yellow-red{--bslib-color-fg: #000;--bslib-color-bg: #f18920;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ffc107 var(--bg-gradient-start, 36%), #dc3545 var(--bg-gradient-end, 180%)) #f18920;color:#000}.bg-gradient-yellow-orange{--bslib-color-fg: #000;--bslib-color-bg: #fea60c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ffc107 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) #fea60c;color:#000}.bg-gradient-yellow-green{--bslib-color-fg: #000;--bslib-color-bg: #a3aa26;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ffc107 var(--bg-gradient-start, 36%), #198754 var(--bg-gradient-end, 180%)) #a3aa26;color:#000}.bg-gradient-yellow-teal{--bslib-color-fg: #000;--bslib-color-bg: #a6c441;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ffc107 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #a6c441;color:#000}.bg-gradient-yellow-cyan{--bslib-color-fg: #000;--bslib-color-bg: #9ec564;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ffc107 var(--bg-gradient-start, 36%), #0dcaf0 var(--bg-gradient-end, 180%)) #9ec564;color:#000}.bg-gradient-green-blue{--bslib-color-fg: #ffffff;--bslib-color-bg: #147d98;background:linear-gradient(var(--bg-gradient-deg, 140deg), #198754 var(--bg-gradient-start, 36%), #0d6efd var(--bg-gradient-end, 180%)) #147d98;color:#fff}.bg-gradient-green-indigo{--bslib-color-fg: #ffffff;--bslib-color-bg: #385793;background:linear-gradient(var(--bg-gradient-deg, 140deg), #198754 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #385793;color:#fff}.bg-gradient-green-purple{--bslib-color-fg: #ffffff;--bslib-color-bg: #3b6b80;background:linear-gradient(var(--bg-gradient-deg, 140deg), #198754 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) #3b6b80;color:#fff}.bg-gradient-green-pink{--bslib-color-fg: #ffffff;--bslib-color-bg: #656567;background:linear-gradient(var(--bg-gradient-deg, 140deg), #198754 var(--bg-gradient-start, 36%), #d63384 var(--bg-gradient-end, 180%)) #656567;color:#fff}.bg-gradient-green-red{--bslib-color-fg: #ffffff;--bslib-color-bg: #67664e;background:linear-gradient(var(--bg-gradient-deg, 140deg), #198754 var(--bg-gradient-start, 36%), #dc3545 var(--bg-gradient-end, 180%)) #67664e;color:#fff}.bg-gradient-green-orange{--bslib-color-fg: #000;--bslib-color-bg: #74833a;background:linear-gradient(var(--bg-gradient-deg, 140deg), #198754 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) #74833a;color:#000}.bg-gradient-green-yellow{--bslib-color-fg: #000;--bslib-color-bg: #759e35;background:linear-gradient(var(--bg-gradient-deg, 140deg), #198754 var(--bg-gradient-start, 36%), #ffc107 var(--bg-gradient-end, 180%)) #759e35;color:#000}.bg-gradient-green-teal{--bslib-color-fg: #000;--bslib-color-bg: #1ca16f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #198754 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #1ca16f;color:#000}.bg-gradient-green-cyan{--bslib-color-fg: #000;--bslib-color-bg: #14a292;background:linear-gradient(var(--bg-gradient-deg, 140deg), #198754 var(--bg-gradient-start, 36%), #0dcaf0 var(--bg-gradient-end, 180%)) #14a292;color:#000}.bg-gradient-teal-blue{--bslib-color-fg: #000;--bslib-color-bg: #18a5c0;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #0d6efd var(--bg-gradient-end, 180%)) #18a5c0;color:#000}.bg-gradient-teal-indigo{--bslib-color-fg: #000;--bslib-color-bg: #3c7fbb;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #3c7fbb;color:#000}.bg-gradient-teal-purple{--bslib-color-fg: #000;--bslib-color-bg: #4093a8;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) #4093a8;color:#000}.bg-gradient-teal-pink{--bslib-color-fg: #000;--bslib-color-bg: #698d8f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #d63384 var(--bg-gradient-end, 180%)) #698d8f;color:#000}.bg-gradient-teal-red{--bslib-color-fg: #000;--bslib-color-bg: #6b8e76;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #dc3545 var(--bg-gradient-end, 180%)) #6b8e76;color:#000}.bg-gradient-teal-orange{--bslib-color-fg: #000;--bslib-color-bg: #78ab63;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) #78ab63;color:#000}.bg-gradient-teal-yellow{--bslib-color-fg: #000;--bslib-color-bg: #79c65d;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #ffc107 var(--bg-gradient-end, 180%)) #79c65d;color:#000}.bg-gradient-teal-green{--bslib-color-fg: #000;--bslib-color-bg: #1daf7c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #198754 var(--bg-gradient-end, 180%)) #1daf7c;color:#000}.bg-gradient-teal-cyan{--bslib-color-fg: #000;--bslib-color-bg: #18c9bb;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #0dcaf0 var(--bg-gradient-end, 180%)) #18c9bb;color:#000}.bg-gradient-cyan-blue{--bslib-color-fg: #000;--bslib-color-bg: #0da5f5;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0dcaf0 var(--bg-gradient-start, 36%), #0d6efd var(--bg-gradient-end, 180%)) #0da5f5;color:#000}.bg-gradient-cyan-indigo{--bslib-color-fg: #000;--bslib-color-bg: #3180f1;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0dcaf0 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #3180f1;color:#000}.bg-gradient-cyan-purple{--bslib-color-fg: #000;--bslib-color-bg: #3494dd;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0dcaf0 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) #3494dd;color:#000}.bg-gradient-cyan-pink{--bslib-color-fg: #000;--bslib-color-bg: #5d8ec5;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0dcaf0 var(--bg-gradient-start, 36%), #d63384 var(--bg-gradient-end, 180%)) #5d8ec5;color:#000}.bg-gradient-cyan-red{--bslib-color-fg: #000;--bslib-color-bg: #608eac;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0dcaf0 var(--bg-gradient-start, 36%), #dc3545 var(--bg-gradient-end, 180%)) #608eac;color:#000}.bg-gradient-cyan-orange{--bslib-color-fg: #000;--bslib-color-bg: #6dac98;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0dcaf0 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) #6dac98;color:#000}.bg-gradient-cyan-yellow{--bslib-color-fg: #000;--bslib-color-bg: #6ec693;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0dcaf0 var(--bg-gradient-start, 36%), #ffc107 var(--bg-gradient-end, 180%)) #6ec693;color:#000}.bg-gradient-cyan-green{--bslib-color-fg: #000;--bslib-color-bg: #12afb2;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0dcaf0 var(--bg-gradient-start, 36%), #198754 var(--bg-gradient-end, 180%)) #12afb2;color:#000}.bg-gradient-cyan-teal{--bslib-color-fg: #000;--bslib-color-bg: #15cacc;background:linear-gradient(var(--bg-gradient-deg, 140deg), #0dcaf0 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #15cacc;color:#000}:root{--bslib-value-box-shadow: none;--bslib-value-box-border-width-auto-yes: var(--bslib-value-box-border-width-baseline);--bslib-value-box-border-width-auto-no: 0;--bslib-value-box-border-width-baseline: 1px}.bslib-value-box{border-width:var(--bslib-value-box-border-width-auto-no, var(--bslib-value-box-border-width-baseline));container-name:bslib-value-box;container-type:inline-size}.bslib-value-box.card{box-shadow:var(--bslib-value-box-shadow)}.bslib-value-box.border-auto{border-width:var(--bslib-value-box-border-width-auto-yes, var(--bslib-value-box-border-width-baseline))}.bslib-value-box.default{--bslib-value-box-bg-default: var(--bs-card-bg, #ffffff);--bslib-value-box-border-color-default: var(--bs-card-border-color, rgba(0, 0, 0, 0.175));color:var(--bslib-value-box-color);background-color:var(--bslib-value-box-bg, var(--bslib-value-box-bg-default));border-color:var(--bslib-value-box-border-color, var(--bslib-value-box-border-color-default))}.bslib-value-box .value-box-grid{display:grid;grid-template-areas:"left right";align-items:center;overflow:hidden}.bslib-value-box .value-box-showcase{height:100%;max-height:var(---bslib-value-box-showcase-max-h, 100%)}.bslib-value-box .value-box-showcase,.bslib-value-box .value-box-showcase>.html-fill-item{width:100%}.bslib-value-box[data-full-screen=true] .value-box-showcase{max-height:var(---bslib-value-box-showcase-max-h-fs, 100%)}@media screen and (min-width: 575.98px){@container bslib-value-box (max-width: 300px){.bslib-value-box:not(.showcase-bottom) .value-box-grid{grid-template-columns:1fr !important;grid-template-rows:auto auto;grid-template-areas:"top" "bottom"}.bslib-value-box:not(.showcase-bottom) .value-box-grid .value-box-showcase{grid-area:top !important}.bslib-value-box:not(.showcase-bottom) .value-box-grid .value-box-area{grid-area:bottom !important;justify-content:end}}}.bslib-value-box .value-box-area{justify-content:center;padding:1.5rem 1rem;font-size:.9rem;font-weight:500}.bslib-value-box .value-box-area *{margin-bottom:0;margin-top:0}.bslib-value-box .value-box-title{font-size:1rem;margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}.bslib-value-box .value-box-title:empty::after{content:" "}.bslib-value-box .value-box-value{font-size:calc(1.29rem + 0.48vw);margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}@media(min-width: 1200px){.bslib-value-box .value-box-value{font-size:1.65rem}}.bslib-value-box .value-box-value:empty::after{content:" "}.bslib-value-box .value-box-showcase{align-items:center;justify-content:center;margin-top:auto;margin-bottom:auto;padding:1rem}.bslib-value-box .value-box-showcase .bi,.bslib-value-box .value-box-showcase .fa,.bslib-value-box .value-box-showcase .fab,.bslib-value-box .value-box-showcase .fas,.bslib-value-box .value-box-showcase .far{opacity:.85;min-width:50px;max-width:125%}.bslib-value-box .value-box-showcase .bi,.bslib-value-box .value-box-showcase .fa,.bslib-value-box .value-box-showcase .fab,.bslib-value-box .value-box-showcase .fas,.bslib-value-box .value-box-showcase .far{font-size:4rem}.bslib-value-box.showcase-top-right .value-box-grid{grid-template-columns:1fr var(---bslib-value-box-showcase-w, 50%)}.bslib-value-box.showcase-top-right .value-box-grid .value-box-showcase{grid-area:right;margin-left:auto;align-self:start;align-items:end;padding-left:0;padding-bottom:0}.bslib-value-box.showcase-top-right .value-box-grid .value-box-area{grid-area:left;align-self:end}.bslib-value-box.showcase-top-right[data-full-screen=true] .value-box-grid{grid-template-columns:auto var(---bslib-value-box-showcase-w-fs, 1fr)}.bslib-value-box.showcase-top-right[data-full-screen=true] .value-box-grid>div{align-self:center}.bslib-value-box.showcase-top-right:not([data-full-screen=true]) .value-box-showcase{margin-top:0}@container bslib-value-box (max-width: 300px){.bslib-value-box.showcase-top-right:not([data-full-screen=true]) .value-box-grid .value-box-showcase{padding-left:1rem}}.bslib-value-box.showcase-left-center .value-box-grid{grid-template-columns:var(---bslib-value-box-showcase-w, 30%) auto}.bslib-value-box.showcase-left-center[data-full-screen=true] .value-box-grid{grid-template-columns:var(---bslib-value-box-showcase-w-fs, 1fr) auto}.bslib-value-box.showcase-left-center:not([data-fill-screen=true]) .value-box-grid .value-box-showcase{grid-area:left}.bslib-value-box.showcase-left-center:not([data-fill-screen=true]) .value-box-grid .value-box-area{grid-area:right}.bslib-value-box.showcase-bottom .value-box-grid{grid-template-columns:1fr;grid-template-rows:1fr var(---bslib-value-box-showcase-h, auto);grid-template-areas:"top" "bottom";overflow:hidden}.bslib-value-box.showcase-bottom .value-box-grid .value-box-showcase{grid-area:bottom;padding:0;margin:0}.bslib-value-box.showcase-bottom .value-box-grid .value-box-area{grid-area:top}.bslib-value-box.showcase-bottom[data-full-screen=true] .value-box-grid{grid-template-rows:1fr var(---bslib-value-box-showcase-h-fs, 2fr)}.bslib-value-box.showcase-bottom[data-full-screen=true] .value-box-grid .value-box-showcase{padding:1rem}[data-bs-theme=dark] .bslib-value-box{--bslib-value-box-shadow: 0 0.5rem 1rem rgb(0 0 0 / 50%)}@media(min-width: 576px){.nav:not(.nav-hidden){display:flex !important;display:-webkit-flex !important}.nav:not(.nav-hidden):not(.nav-stacked):not(.flex-column){float:none !important}.nav:not(.nav-hidden):not(.nav-stacked):not(.flex-column)>.bslib-nav-spacer{margin-left:auto !important}.nav:not(.nav-hidden):not(.nav-stacked):not(.flex-column)>.form-inline{margin-top:auto;margin-bottom:auto}.nav:not(.nav-hidden).nav-stacked{flex-direction:column;-webkit-flex-direction:column;height:100%}.nav:not(.nav-hidden).nav-stacked>.bslib-nav-spacer{margin-top:auto !important}}.bslib-card{overflow:auto}.bslib-card .card-body+.card-body{padding-top:0}.bslib-card .card-body{overflow:auto}.bslib-card .card-body p{margin-top:0}.bslib-card .card-body p:last-child{margin-bottom:0}.bslib-card .card-body{max-height:var(--bslib-card-body-max-height, none)}.bslib-card[data-full-screen=true]>.card-body{max-height:var(--bslib-card-body-max-height-full-screen, none)}.bslib-card .card-header .form-group{margin-bottom:0}.bslib-card .card-header .selectize-control{margin-bottom:0}.bslib-card .card-header .selectize-control .item{margin-right:1.15rem}.bslib-card .card-footer{margin-top:auto}.bslib-card .bslib-navs-card-title{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center}.bslib-card .bslib-navs-card-title .nav{margin-left:auto}.bslib-card .bslib-sidebar-layout:not([data-bslib-sidebar-border=true]){border:none}.bslib-card .bslib-sidebar-layout:not([data-bslib-sidebar-border-radius=true]){border-top-left-radius:0;border-top-right-radius:0}[data-full-screen=true]{position:fixed;inset:3.5rem 1rem 1rem;height:auto !important;max-height:none !important;width:auto !important;z-index:1070}.bslib-full-screen-enter{display:none;position:absolute;bottom:var(--bslib-full-screen-enter-bottom, 0.2rem);right:var(--bslib-full-screen-enter-right, 0);top:var(--bslib-full-screen-enter-top);left:var(--bslib-full-screen-enter-left);color:var(--bslib-color-fg, var(--bs-card-color));background-color:var(--bslib-color-bg, var(--bs-card-bg, var(--bs-body-bg)));border:var(--bs-card-border-width) solid var(--bslib-color-fg, var(--bs-card-border-color));box-shadow:0 2px 4px rgba(0,0,0,.15);margin:.2rem .4rem;padding:.55rem !important;font-size:.8rem;cursor:pointer;opacity:.7;z-index:1070}.bslib-full-screen-enter:hover{opacity:1}.card[data-full-screen=false]:hover>*>.bslib-full-screen-enter{display:block}.bslib-has-full-screen .card:hover>*>.bslib-full-screen-enter{display:none}@media(max-width: 575.98px){.bslib-full-screen-enter{display:none !important}}.bslib-full-screen-exit{position:relative;top:1.35rem;font-size:.9rem;cursor:pointer;text-decoration:none;display:flex;float:right;margin-right:2.15rem;align-items:center;color:rgba(var(--bs-body-bg-rgb), 0.8)}.bslib-full-screen-exit:hover{color:rgba(var(--bs-body-bg-rgb), 1)}.bslib-full-screen-exit svg{margin-left:.5rem;font-size:1.5rem}#bslib-full-screen-overlay{position:fixed;inset:0;background-color:rgba(var(--bs-body-color-rgb), 0.6);backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);z-index:1069;animation:bslib-full-screen-overlay-enter 400ms cubic-bezier(0.6, 0.02, 0.65, 1) forwards}@keyframes bslib-full-screen-overlay-enter{0%{opacity:0}100%{opacity:1}}.bslib-grid{display:grid !important;gap:var(--bslib-spacer, 1rem);height:var(--bslib-grid-height)}.bslib-grid.grid{grid-template-columns:repeat(var(--bs-columns, 12), minmax(0, 1fr));grid-template-rows:unset;grid-auto-rows:var(--bslib-grid--row-heights);--bslib-grid--row-heights--xs: unset;--bslib-grid--row-heights--sm: unset;--bslib-grid--row-heights--md: unset;--bslib-grid--row-heights--lg: unset;--bslib-grid--row-heights--xl: unset;--bslib-grid--row-heights--xxl: unset}.bslib-grid.grid.bslib-grid--row-heights--xs{--bslib-grid--row-heights: var(--bslib-grid--row-heights--xs)}@media(min-width: 576px){.bslib-grid.grid.bslib-grid--row-heights--sm{--bslib-grid--row-heights: var(--bslib-grid--row-heights--sm)}}@media(min-width: 768px){.bslib-grid.grid.bslib-grid--row-heights--md{--bslib-grid--row-heights: var(--bslib-grid--row-heights--md)}}@media(min-width: 992px){.bslib-grid.grid.bslib-grid--row-heights--lg{--bslib-grid--row-heights: var(--bslib-grid--row-heights--lg)}}@media(min-width: 1200px){.bslib-grid.grid.bslib-grid--row-heights--xl{--bslib-grid--row-heights: var(--bslib-grid--row-heights--xl)}}@media(min-width: 1400px){.bslib-grid.grid.bslib-grid--row-heights--xxl{--bslib-grid--row-heights: var(--bslib-grid--row-heights--xxl)}}.bslib-grid>*>.shiny-input-container{width:100%}.bslib-grid-item{grid-column:auto/span 1}@media(max-width: 767.98px){.bslib-grid-item{grid-column:1/-1}}@media(max-width: 575.98px){.bslib-grid{grid-template-columns:1fr !important;height:var(--bslib-grid-height-mobile)}.bslib-grid.grid{height:unset !important;grid-auto-rows:var(--bslib-grid--row-heights--xs, auto)}}.accordion .accordion-header{font-size:calc(1.29rem + 0.48vw);margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color);margin-bottom:0}@media(min-width: 1200px){.accordion .accordion-header{font-size:1.65rem}}.accordion .accordion-icon:not(:empty){margin-right:.75rem;display:flex}.accordion .accordion-button:not(.collapsed){box-shadow:none}.accordion .accordion-button:not(.collapsed):focus{box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.navbar+.container-fluid:has(>.tab-content>.tab-pane.active.html-fill-container),.navbar+.container-sm:has(>.tab-content>.tab-pane.active.html-fill-container),.navbar+.container-md:has(>.tab-content>.tab-pane.active.html-fill-container),.navbar+.container-lg:has(>.tab-content>.tab-pane.active.html-fill-container),.navbar+.container-xl:has(>.tab-content>.tab-pane.active.html-fill-container),.navbar+.container-xxl:has(>.tab-content>.tab-pane.active.html-fill-container){padding-left:0;padding-right:0}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container,.navbar+.container-sm>.tab-content>.tab-pane.active.html-fill-container,.navbar+.container-md>.tab-content>.tab-pane.active.html-fill-container,.navbar+.container-lg>.tab-content>.tab-pane.active.html-fill-container,.navbar+.container-xl>.tab-content>.tab-pane.active.html-fill-container,.navbar+.container-xxl>.tab-content>.tab-pane.active.html-fill-container{padding:var(--bslib-spacer, 1rem);gap:var(--bslib-spacer, 1rem)}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child),.navbar+.container-sm>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child),.navbar+.container-md>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child),.navbar+.container-lg>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child),.navbar+.container-xl>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child),.navbar+.container-xxl>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child){padding:0}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border=true]),.navbar+.container-sm>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border=true]),.navbar+.container-md>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border=true]),.navbar+.container-lg>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border=true]),.navbar+.container-xl>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border=true]),.navbar+.container-xxl>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border=true]){border-left:none;border-right:none;border-bottom:none}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius=true]),.navbar+.container-sm>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius=true]),.navbar+.container-md>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius=true]),.navbar+.container-lg>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius=true]),.navbar+.container-xl>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius=true]),.navbar+.container-xxl>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius=true]){border-radius:0}.navbar+div>.bslib-sidebar-layout{border-top:var(--bslib-sidebar-border)}html{height:100%}.bslib-page-fill{width:100%;height:100%;margin:0;padding:var(--bslib-spacer, 1rem);gap:var(--bslib-spacer, 1rem)}@media(max-width: 575.98px){.bslib-page-fill{height:var(--bslib-page-fill-mobile-height, auto)}}:root{--bslib-page-sidebar-title-bg: #517699;--bslib-page-sidebar-title-color: #ffffff}.bslib-page-title{background-color:var(--bslib-page-sidebar-title-bg);color:var(--bslib-page-sidebar-title-color);font-size:1.25rem;font-weight:300;padding:var(--bslib-spacer, 1rem);padding-left:1.5rem;margin-bottom:0;border-bottom:1px solid #dee2e6}.bslib-sidebar-layout{--bslib-sidebar-transition-duration: 500ms;--bslib-sidebar-transition-easing-x: cubic-bezier(0.8, 0.78, 0.22, 1.07);--bslib-sidebar-border: var(--bs-card-border-width, 1px) solid var(--bs-card-border-color, rgba(0, 0, 0, 0.175));--bslib-sidebar-border-radius: var(--bs-border-radius);--bslib-sidebar-vert-border: var(--bs-card-border-width, 1px) solid var(--bs-card-border-color, rgba(0, 0, 0, 0.175));--bslib-sidebar-bg: rgba(var(--bs-emphasis-color-rgb, 0, 0, 0), 0.05);--bslib-sidebar-fg: var(--bs-emphasis-color, black);--bslib-sidebar-main-fg: var(--bs-card-color, var(--bs-body-color));--bslib-sidebar-main-bg: var(--bs-card-bg, var(--bs-body-bg));--bslib-sidebar-toggle-bg: rgba(var(--bs-emphasis-color-rgb, 0, 0, 0), 0.1);--bslib-sidebar-padding: calc(var(--bslib-spacer) * 1.5);--bslib-sidebar-icon-size: var(--bslib-spacer, 1rem);--bslib-sidebar-icon-button-size: calc(var(--bslib-sidebar-icon-size, 1rem) * 2);--bslib-sidebar-padding-icon: calc(var(--bslib-sidebar-icon-button-size, 2rem) * 1.5);--bslib-collapse-toggle-border-radius: var(--bs-border-radius, 0.375rem);--bslib-collapse-toggle-transform: 0deg;--bslib-sidebar-toggle-transition-easing: cubic-bezier(1, 0, 0, 1);--bslib-collapse-toggle-right-transform: 180deg;--bslib-sidebar-column-main: minmax(0, 1fr);display:grid !important;grid-template-columns:min(100% - var(--bslib-sidebar-icon-size),var(--bslib-sidebar-width, 250px)) var(--bslib-sidebar-column-main);position:relative;transition:grid-template-columns ease-in-out var(--bslib-sidebar-transition-duration);border:var(--bslib-sidebar-border);border-radius:var(--bslib-sidebar-border-radius)}@media(prefers-reduced-motion: reduce){.bslib-sidebar-layout{transition:none}}.bslib-sidebar-layout[data-bslib-sidebar-border=false]{border:none}.bslib-sidebar-layout[data-bslib-sidebar-border-radius=false]{border-radius:initial}.bslib-sidebar-layout>.main,.bslib-sidebar-layout>.sidebar{grid-row:1/2;border-radius:inherit;overflow:auto}.bslib-sidebar-layout>.main{grid-column:2/3;border-top-left-radius:0;border-bottom-left-radius:0;padding:var(--bslib-sidebar-padding);transition:padding var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration);color:var(--bslib-sidebar-main-fg);background-color:var(--bslib-sidebar-main-bg)}.bslib-sidebar-layout>.sidebar{grid-column:1/2;width:100%;height:100%;border-right:var(--bslib-sidebar-vert-border);border-top-right-radius:0;border-bottom-right-radius:0;color:var(--bslib-sidebar-fg);background-color:var(--bslib-sidebar-bg);backdrop-filter:blur(5px)}.bslib-sidebar-layout>.sidebar>.sidebar-content{display:flex;flex-direction:column;gap:var(--bslib-spacer, 1rem);padding:var(--bslib-sidebar-padding);padding-top:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout>.sidebar>.sidebar-content>:last-child:not(.sidebar-title){margin-bottom:0}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion{margin-left:calc(-1*var(--bslib-sidebar-padding));margin-right:calc(-1*var(--bslib-sidebar-padding))}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion:last-child{margin-bottom:calc(-1*var(--bslib-sidebar-padding))}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion:not(:last-child){margin-bottom:1rem}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion .accordion-body{display:flex;flex-direction:column}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion:not(:first-child) .accordion-item:first-child{border-top:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion:not(:last-child) .accordion-item:last-child{border-bottom:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.bslib-sidebar-layout>.sidebar>.sidebar-content.has-accordion>.sidebar-title{border-bottom:none;padding-bottom:0}.bslib-sidebar-layout>.sidebar .shiny-input-container{width:100%}.bslib-sidebar-layout[data-bslib-sidebar-open=always]>.sidebar>.sidebar-content{padding-top:var(--bslib-sidebar-padding)}.bslib-sidebar-layout>.collapse-toggle{grid-row:1/2;grid-column:1/2;display:inline-flex;align-items:center;position:absolute;right:calc(var(--bslib-sidebar-icon-size));top:calc(var(--bslib-sidebar-icon-size, 1rem)/2);border:none;border-radius:var(--bslib-collapse-toggle-border-radius);height:var(--bslib-sidebar-icon-button-size, 2rem);width:var(--bslib-sidebar-icon-button-size, 2rem);display:flex;align-items:center;justify-content:center;padding:0;color:var(--bslib-sidebar-fg);background-color:unset;transition:color var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration),top var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration),right var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration),left var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration)}.bslib-sidebar-layout>.collapse-toggle:hover{background-color:var(--bslib-sidebar-toggle-bg)}.bslib-sidebar-layout>.collapse-toggle>.collapse-icon{opacity:.8;width:var(--bslib-sidebar-icon-size);height:var(--bslib-sidebar-icon-size);transform:rotateY(var(--bslib-collapse-toggle-transform));transition:transform var(--bslib-sidebar-toggle-transition-easing) var(--bslib-sidebar-transition-duration)}.bslib-sidebar-layout>.collapse-toggle:hover>.collapse-icon{opacity:1}.bslib-sidebar-layout .sidebar-title{font-size:1.25rem;line-height:1.25;margin-top:0;margin-bottom:1rem;padding-bottom:1rem;border-bottom:var(--bslib-sidebar-border)}.bslib-sidebar-layout.sidebar-right{grid-template-columns:var(--bslib-sidebar-column-main) min(100% - var(--bslib-sidebar-icon-size),var(--bslib-sidebar-width, 250px))}.bslib-sidebar-layout.sidebar-right>.main{grid-column:1/2;border-top-right-radius:0;border-bottom-right-radius:0;border-top-left-radius:inherit;border-bottom-left-radius:inherit}.bslib-sidebar-layout.sidebar-right>.sidebar{grid-column:2/3;border-right:none;border-left:var(--bslib-sidebar-vert-border);border-top-left-radius:0;border-bottom-left-radius:0}.bslib-sidebar-layout.sidebar-right>.collapse-toggle{grid-column:2/3;left:var(--bslib-sidebar-icon-size);right:unset;border:var(--bslib-collapse-toggle-border)}.bslib-sidebar-layout.sidebar-right>.collapse-toggle>.collapse-icon{transform:rotateY(var(--bslib-collapse-toggle-right-transform))}.bslib-sidebar-layout.sidebar-collapsed{--bslib-collapse-toggle-transform: 180deg;--bslib-collapse-toggle-right-transform: 0deg;--bslib-sidebar-vert-border: none;grid-template-columns:0 minmax(0, 1fr)}.bslib-sidebar-layout.sidebar-collapsed.sidebar-right{grid-template-columns:minmax(0, 1fr) 0}.bslib-sidebar-layout.sidebar-collapsed:not(.transitioning)>.sidebar>*{display:none}.bslib-sidebar-layout.sidebar-collapsed>.main{border-radius:inherit}.bslib-sidebar-layout.sidebar-collapsed:not(.sidebar-right)>.main{padding-left:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout.sidebar-collapsed.sidebar-right>.main{padding-right:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout.sidebar-collapsed>.collapse-toggle{color:var(--bslib-sidebar-main-fg);top:calc(var(--bslib-sidebar-overlap-counter, 0)*(var(--bslib-sidebar-icon-size) + var(--bslib-sidebar-padding)) + var(--bslib-sidebar-icon-size, 1rem)/2);right:calc(-2.5*var(--bslib-sidebar-icon-size) - var(--bs-card-border-width, 1px))}.bslib-sidebar-layout.sidebar-collapsed.sidebar-right>.collapse-toggle{left:calc(-2.5*var(--bslib-sidebar-icon-size) - var(--bs-card-border-width, 1px));right:unset}@media(min-width: 576px){.bslib-sidebar-layout.transitioning>.sidebar>.sidebar-content{display:none}}@media(max-width: 575.98px){.bslib-sidebar-layout[data-bslib-sidebar-open=desktop]{--bslib-sidebar-js-init-collapsed: true}.bslib-sidebar-layout>.sidebar,.bslib-sidebar-layout.sidebar-right>.sidebar{border:none}.bslib-sidebar-layout>.main,.bslib-sidebar-layout.sidebar-right>.main{grid-column:1/3}.bslib-sidebar-layout[data-bslib-sidebar-open=always]{display:block !important}.bslib-sidebar-layout[data-bslib-sidebar-open=always]>.sidebar{max-height:var(--bslib-sidebar-max-height-mobile);overflow-y:auto;border-top:var(--bslib-sidebar-vert-border)}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]){grid-template-columns:100% 0}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]):not(.sidebar-collapsed)>.sidebar{z-index:1}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]):not(.sidebar-collapsed)>.collapse-toggle{z-index:1}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]).sidebar-right{grid-template-columns:0 100%}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]).sidebar-collapsed{grid-template-columns:0 100%}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]).sidebar-collapsed.sidebar-right{grid-template-columns:100% 0}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]):not(.sidebar-right)>.main{padding-left:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]).sidebar-right>.main{padding-right:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always])>.main{opacity:0;transition:opacity var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration)}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]).sidebar-collapsed>.main{opacity:1}}.html-fill-container{display:flex;flex-direction:column;min-height:0;min-width:0}.html-fill-container>.html-fill-item{flex:1 1 auto;min-height:0;min-width:0}.html-fill-container>:not(.html-fill-item){flex:0 0 auto}.tippy-box[data-theme~=quarto]{background-color:#fff;border:solid 1px #dee2e6;border-radius:.375rem;color:#212529;font-size:.875rem}.tippy-box[data-theme~=quarto]>.tippy-backdrop{background-color:#fff}.tippy-box[data-theme~=quarto]>.tippy-arrow:after,.tippy-box[data-theme~=quarto]>.tippy-svg-arrow:after{content:"";position:absolute;z-index:-1}.tippy-box[data-theme~=quarto]>.tippy-arrow:after{border-color:rgba(0,0,0,0);border-style:solid}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-6px}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-6px}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-6px}.tippy-box[data-placement^=left]>.tippy-arrow:before{right:-6px}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-arrow:before{border-top-color:#fff}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-arrow:after{border-top-color:#dee2e6;border-width:7px 7px 0;top:17px;left:1px}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-svg-arrow>svg{top:16px}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-svg-arrow:after{top:17px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-arrow:before{border-bottom-color:#fff;bottom:16px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-arrow:after{border-bottom-color:#dee2e6;border-width:0 7px 7px;bottom:17px;left:1px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-svg-arrow>svg{bottom:15px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-svg-arrow:after{bottom:17px}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-arrow:before{border-left-color:#fff}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-arrow:after{border-left-color:#dee2e6;border-width:7px 0 7px 7px;left:17px;top:1px}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-svg-arrow>svg{left:11px}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-svg-arrow:after{left:12px}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-arrow:before{border-right-color:#fff;right:16px}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-arrow:after{border-width:7px 7px 7px 0;right:17px;top:1px;border-right-color:#dee2e6}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-svg-arrow>svg{right:11px}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-svg-arrow:after{right:12px}.tippy-box[data-theme~=quarto]>.tippy-svg-arrow{fill:#212529}.tippy-box[data-theme~=quarto]>.tippy-svg-arrow:after{background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMCA2czEuNzk2LS4wMTMgNC42Ny0zLjYxNUM1Ljg1MS45IDYuOTMuMDA2IDggMGMxLjA3LS4wMDYgMi4xNDguODg3IDMuMzQzIDIuMzg1QzE0LjIzMyA2LjAwNSAxNiA2IDE2IDZIMHoiIGZpbGw9InJnYmEoMCwgOCwgMTYsIDAuMikiLz48L3N2Zz4=);background-size:16px 6px;width:16px;height:6px}.top-right{position:absolute;top:1em;right:1em}.visually-hidden{border:0;clip:rect(0 0 0 0);height:auto;margin:0;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap}.hidden{display:none !important}.zindex-bottom{z-index:-1 !important}figure.figure{display:block}.quarto-layout-panel{margin-bottom:1em}.quarto-layout-panel>figure{width:100%}.quarto-layout-panel>figure>figcaption,.quarto-layout-panel>.panel-caption{margin-top:10pt}.quarto-layout-panel>.table-caption{margin-top:0px}.table-caption p{margin-bottom:.5em}.quarto-layout-row{display:flex;flex-direction:row;align-items:flex-start}.quarto-layout-valign-top{align-items:flex-start}.quarto-layout-valign-bottom{align-items:flex-end}.quarto-layout-valign-center{align-items:center}.quarto-layout-cell{position:relative;margin-right:20px}.quarto-layout-cell:last-child{margin-right:0}.quarto-layout-cell figure,.quarto-layout-cell>p{margin:.2em}.quarto-layout-cell img{max-width:100%}.quarto-layout-cell .html-widget{width:100% !important}.quarto-layout-cell div figure p{margin:0}.quarto-layout-cell figure{display:block;margin-inline-start:0;margin-inline-end:0}.quarto-layout-cell table{display:inline-table}.quarto-layout-cell-subref figcaption,figure .quarto-layout-row figure figcaption{text-align:center;font-style:italic}.quarto-figure{position:relative;margin-bottom:1em}.quarto-figure>figure{width:100%;margin-bottom:0}.quarto-figure-left>figure>p,.quarto-figure-left>figure>div{text-align:left}.quarto-figure-center>figure>p,.quarto-figure-center>figure>div{text-align:center}.quarto-figure-right>figure>p,.quarto-figure-right>figure>div{text-align:right}.quarto-figure>figure>div.cell-annotation,.quarto-figure>figure>div code{text-align:left}figure>p:empty{display:none}figure>p:first-child{margin-top:0;margin-bottom:0}figure>figcaption.quarto-float-caption-bottom{margin-bottom:.5em}figure>figcaption.quarto-float-caption-top{margin-top:.5em}div[id^=tbl-]{position:relative}.quarto-figure>.anchorjs-link{position:absolute;top:.6em;right:.5em}div[id^=tbl-]>.anchorjs-link{position:absolute;top:.7em;right:.3em}.quarto-figure:hover>.anchorjs-link,div[id^=tbl-]:hover>.anchorjs-link,h2:hover>.anchorjs-link,.h2:hover>.anchorjs-link,h3:hover>.anchorjs-link,.h3:hover>.anchorjs-link,h4:hover>.anchorjs-link,.h4:hover>.anchorjs-link,h5:hover>.anchorjs-link,.h5:hover>.anchorjs-link,h6:hover>.anchorjs-link,.h6:hover>.anchorjs-link,.reveal-anchorjs-link>.anchorjs-link{opacity:1}#title-block-header{margin-block-end:1rem;position:relative;margin-top:-1px}#title-block-header .abstract{margin-block-start:1rem}#title-block-header .abstract .abstract-title{font-weight:600}#title-block-header a{text-decoration:none}#title-block-header .author,#title-block-header .date,#title-block-header .doi{margin-block-end:.2rem}#title-block-header .quarto-title-block>div{display:flex}#title-block-header .quarto-title-block>div>h1,#title-block-header .quarto-title-block>div>.h1{flex-grow:1}#title-block-header .quarto-title-block>div>button{flex-shrink:0;height:2.25rem;margin-top:0}@media(min-width: 992px){#title-block-header .quarto-title-block>div>button{margin-top:5px}}tr.header>th>p:last-of-type{margin-bottom:0px}table,table.table{margin-top:.5rem;margin-bottom:.5rem}caption,.table-caption{padding-top:.5rem;padding-bottom:.5rem;text-align:center}figure.quarto-float-tbl figcaption.quarto-float-caption-top{margin-top:.5rem;margin-bottom:.25rem;text-align:center}figure.quarto-float-tbl figcaption.quarto-float-caption-bottom{padding-top:.25rem;margin-bottom:.5rem;text-align:center}.utterances{max-width:none;margin-left:-8px}iframe{margin-bottom:1em}details{margin-bottom:1em}details[show]{margin-bottom:0}details>summary{color:rgba(33,37,41,.75)}details>summary>p:only-child{display:inline}pre.sourceCode,code.sourceCode{position:relative}p code:not(.sourceCode){white-space:pre-wrap}code{white-space:pre}@media print{code{white-space:pre-wrap}}pre>code{display:block}pre>code.sourceCode{white-space:pre}pre>code.sourceCode>span>a:first-child::before{text-decoration:none}pre.code-overflow-wrap>code.sourceCode{white-space:pre-wrap}pre.code-overflow-scroll>code.sourceCode{white-space:pre}code a:any-link{color:inherit;text-decoration:none}code a:hover{color:inherit;text-decoration:underline}ul.task-list{padding-left:1em}[data-tippy-root]{display:inline-block}.tippy-content .footnote-back{display:none}.footnote-back{margin-left:.2em}.tippy-content{overflow-x:auto}.quarto-embedded-source-code{display:none}.quarto-unresolved-ref{font-weight:600}.quarto-cover-image{max-width:35%;float:right;margin-left:30px}.cell-output-display .widget-subarea{margin-bottom:1em}.cell-output-display:not(.no-overflow-x),.knitsql-table:not(.no-overflow-x){overflow-x:auto}.panel-input{margin-bottom:1em}.panel-input>div,.panel-input>div>div{display:inline-block;vertical-align:top;padding-right:12px}.panel-input>p:last-child{margin-bottom:0}.layout-sidebar{margin-bottom:1em}.layout-sidebar .tab-content{border:none}.tab-content>.page-columns.active{display:grid}div.sourceCode>iframe{width:100%;height:300px;margin-bottom:-0.5em}a{text-underline-offset:3px}div.ansi-escaped-output{font-family:monospace;display:block}/*!
+*
+* ansi colors from IPython notebook's
+*
+* we also add `bright-[color]-` synonyms for the `-[color]-intense` classes since
+* that seems to be what ansi_up emits
+*
+*/.ansi-black-fg{color:#3e424d}.ansi-black-bg{background-color:#3e424d}.ansi-black-intense-black,.ansi-bright-black-fg{color:#282c36}.ansi-black-intense-black,.ansi-bright-black-bg{background-color:#282c36}.ansi-red-fg{color:#e75c58}.ansi-red-bg{background-color:#e75c58}.ansi-red-intense-red,.ansi-bright-red-fg{color:#b22b31}.ansi-red-intense-red,.ansi-bright-red-bg{background-color:#b22b31}.ansi-green-fg{color:#00a250}.ansi-green-bg{background-color:#00a250}.ansi-green-intense-green,.ansi-bright-green-fg{color:#007427}.ansi-green-intense-green,.ansi-bright-green-bg{background-color:#007427}.ansi-yellow-fg{color:#ddb62b}.ansi-yellow-bg{background-color:#ddb62b}.ansi-yellow-intense-yellow,.ansi-bright-yellow-fg{color:#b27d12}.ansi-yellow-intense-yellow,.ansi-bright-yellow-bg{background-color:#b27d12}.ansi-blue-fg{color:#208ffb}.ansi-blue-bg{background-color:#208ffb}.ansi-blue-intense-blue,.ansi-bright-blue-fg{color:#0065ca}.ansi-blue-intense-blue,.ansi-bright-blue-bg{background-color:#0065ca}.ansi-magenta-fg{color:#d160c4}.ansi-magenta-bg{background-color:#d160c4}.ansi-magenta-intense-magenta,.ansi-bright-magenta-fg{color:#a03196}.ansi-magenta-intense-magenta,.ansi-bright-magenta-bg{background-color:#a03196}.ansi-cyan-fg{color:#60c6c8}.ansi-cyan-bg{background-color:#60c6c8}.ansi-cyan-intense-cyan,.ansi-bright-cyan-fg{color:#258f8f}.ansi-cyan-intense-cyan,.ansi-bright-cyan-bg{background-color:#258f8f}.ansi-white-fg{color:#c5c1b4}.ansi-white-bg{background-color:#c5c1b4}.ansi-white-intense-white,.ansi-bright-white-fg{color:#a1a6b2}.ansi-white-intense-white,.ansi-bright-white-bg{background-color:#a1a6b2}.ansi-default-inverse-fg{color:#fff}.ansi-default-inverse-bg{background-color:#000}.ansi-bold{font-weight:bold}.ansi-underline{text-decoration:underline}:root{--quarto-body-bg: #ffffff;--quarto-body-color: #212529;--quarto-text-muted: rgba(33, 37, 41, 0.75);--quarto-border-color: #dee2e6;--quarto-border-width: 1px;--quarto-border-radius: 0.375rem}table.gt_table{color:var(--quarto-body-color);font-size:1em;width:100%;background-color:rgba(0,0,0,0);border-top-width:inherit;border-bottom-width:inherit;border-color:var(--quarto-border-color)}table.gt_table th.gt_column_spanner_outer{color:var(--quarto-body-color);background-color:rgba(0,0,0,0);border-top-width:inherit;border-bottom-width:inherit;border-color:var(--quarto-border-color)}table.gt_table th.gt_col_heading{color:var(--quarto-body-color);font-weight:bold;background-color:rgba(0,0,0,0)}table.gt_table thead.gt_col_headings{border-bottom:1px solid currentColor;border-top-width:inherit;border-top-color:var(--quarto-border-color)}table.gt_table thead.gt_col_headings:not(:first-child){border-top-width:1px;border-top-color:var(--quarto-border-color)}table.gt_table td.gt_row{border-bottom-width:1px;border-bottom-color:var(--quarto-border-color);border-top-width:0px}table.gt_table tbody.gt_table_body{border-top-width:1px;border-bottom-width:1px;border-bottom-color:var(--quarto-border-color);border-top-color:currentColor}div.columns{display:initial;gap:initial}div.column{display:inline-block;overflow-x:initial;vertical-align:top;width:50%}.code-annotation-tip-content{word-wrap:break-word}.code-annotation-container-hidden{display:none !important}dl.code-annotation-container-grid{display:grid;grid-template-columns:min-content auto}dl.code-annotation-container-grid dt{grid-column:1}dl.code-annotation-container-grid dd{grid-column:2}pre.sourceCode.code-annotation-code{padding-right:0}code.sourceCode .code-annotation-anchor{z-index:100;position:relative;float:right;background-color:rgba(0,0,0,0)}input[type=checkbox]{margin-right:.5ch}:root{--mermaid-bg-color: #ffffff;--mermaid-edge-color: #6c757d;--mermaid-node-fg-color: #212529;--mermaid-fg-color: #212529;--mermaid-fg-color--lighter: #383f45;--mermaid-fg-color--lightest: #4e5862;--mermaid-font-family: system-ui, -apple-system, Segoe UI, Roboto, Helvetica Neue, Noto Sans, Liberation Sans, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;--mermaid-label-bg-color: #ffffff;--mermaid-label-fg-color: #0d6efd;--mermaid-node-bg-color: rgba(13, 110, 253, 0.1);--mermaid-node-fg-color: #212529}@media print{:root{font-size:11pt}#quarto-sidebar,#TOC,.nav-page{display:none}.page-columns .content{grid-column-start:page-start}.fixed-top{position:relative}.panel-caption,.figure-caption,figcaption{color:#666}}.code-copy-button{position:absolute;top:0;right:0;border:0;margin-top:5px;margin-right:5px;background-color:rgba(0,0,0,0);z-index:3}.code-copy-button:focus{outline:none}.code-copy-button-tooltip{font-size:.75em}pre.sourceCode:hover>.code-copy-button>.bi::before{display:inline-block;height:1rem;width:1rem;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml, ');background-repeat:no-repeat;background-size:1rem 1rem}pre.sourceCode:hover>.code-copy-button-checked>.bi::before{background-image:url('data:image/svg+xml, ')}pre.sourceCode:hover>.code-copy-button:hover>.bi::before{background-image:url('data:image/svg+xml, ')}pre.sourceCode:hover>.code-copy-button-checked:hover>.bi::before{background-image:url('data:image/svg+xml, ')}main ol ol,main ul ul,main ol ul,main ul ol{margin-bottom:1em}ul>li:not(:has(>p))>ul,ol>li:not(:has(>p))>ul,ul>li:not(:has(>p))>ol,ol>li:not(:has(>p))>ol{margin-bottom:0}ul>li:not(:has(>p))>ul>li:has(>p),ol>li:not(:has(>p))>ul>li:has(>p),ul>li:not(:has(>p))>ol>li:has(>p),ol>li:not(:has(>p))>ol>li:has(>p){margin-top:1rem}body{margin:0}main.page-columns>header>h1.title,main.page-columns>header>.title.h1{margin-bottom:0}@media(min-width: 992px){body .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(500px, calc(850px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.fullcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(500px, calc(850px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] 35px [page-end-inset page-end] 5fr [screen-end-inset] 1.5em}body.slimcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(500px, calc(850px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.listing:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc(850px - 3em)) [body-content-end] 3em [body-end] 50px [body-end-outset] minmax(0px, 250px) [page-end-inset] minmax(50px, 100px) [page-end] 1fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 175px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 175px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] minmax(25px, 50px) [page-start-inset] minmax(50px, 150px) [body-start-outset] minmax(25px, 50px) [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] minmax(25px, 50px) [body-end-outset] minmax(50px, 150px) [page-end-inset] minmax(25px, 50px) [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc(1000px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(50px, 100px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc(1000px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 50px [page-start-inset] minmax(50px, 150px) [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(450px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc(1000px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 50px [page-start-inset] minmax(50px, 150px) [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(450px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(50px, 150px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] minmax(25px, 50px) [page-start-inset] minmax(50px, 150px) [body-start-outset] minmax(25px, 50px) [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] minmax(25px, 50px) [body-end-outset] minmax(50px, 150px) [page-end-inset] minmax(25px, 50px) [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}}@media(max-width: 991.98px){body .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.fullcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.slimcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.listing:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc(1250px - 3em)) [body-content-end body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 145px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc(800px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 145px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc(800px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1.5em [body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(75px, 150px) [page-end-inset] 25px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(25px, 50px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc(1000px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 4fr [screen-end-inset] 1.5em [screen-end]}body.docked.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(25px, 50px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(25px, 50px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 4fr [screen-end-inset] 1.5em [screen-end]}body.floating.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(75px, 150px) [page-end-inset] 25px [page-end] 4fr [screen-end-inset] 1.5em [screen-end]}}@media(max-width: 767.98px){body .page-columns,body.fullcontent:not(.floating):not(.docked) .page-columns,body.slimcontent:not(.floating):not(.docked) .page-columns,body.docked .page-columns,body.docked.slimcontent .page-columns,body.docked.fullcontent .page-columns,body.floating .page-columns,body.floating.slimcontent .page-columns,body.floating.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end]}nav[role=doc-toc]{display:none}}body,.page-row-navigation{grid-template-rows:[page-top] max-content [contents-top] max-content [contents-bottom] max-content [page-bottom]}.page-rows-contents{grid-template-rows:[content-top] minmax(max-content, 1fr) [content-bottom] minmax(60px, max-content) [page-bottom]}.page-full{grid-column:screen-start/screen-end !important}.page-columns>*{grid-column:body-content-start/body-content-end}.page-columns.column-page>*{grid-column:page-start/page-end}.page-columns.column-page-left .page-columns.page-full>*,.page-columns.column-page-left>*{grid-column:page-start/body-content-end}.page-columns.column-page-right .page-columns.page-full>*,.page-columns.column-page-right>*{grid-column:body-content-start/page-end}.page-rows{grid-auto-rows:auto}.header{grid-column:screen-start/screen-end;grid-row:page-top/contents-top}#quarto-content{padding:0;grid-column:screen-start/screen-end;grid-row:contents-top/contents-bottom}body.floating .sidebar.sidebar-navigation{grid-column:page-start/body-start;grid-row:content-top/page-bottom}body.docked .sidebar.sidebar-navigation{grid-column:screen-start/body-start;grid-row:content-top/page-bottom}.sidebar.toc-left{grid-column:page-start/body-start;grid-row:content-top/page-bottom}.sidebar.margin-sidebar{grid-column:body-end/page-end;grid-row:content-top/page-bottom}.page-columns .content{grid-column:body-content-start/body-content-end;grid-row:content-top/content-bottom;align-content:flex-start}.page-columns .page-navigation{grid-column:body-content-start/body-content-end;grid-row:content-bottom/page-bottom}.page-columns .footer{grid-column:screen-start/screen-end;grid-row:contents-bottom/page-bottom}.page-columns .column-body{grid-column:body-content-start/body-content-end}.page-columns .column-body-fullbleed{grid-column:body-start/body-end}.page-columns .column-body-outset{grid-column:body-start-outset/body-end-outset;z-index:998;opacity:.999}.page-columns .column-body-outset table{background:#fff}.page-columns .column-body-outset-left{grid-column:body-start-outset/body-content-end;z-index:998;opacity:.999}.page-columns .column-body-outset-left table{background:#fff}.page-columns .column-body-outset-right{grid-column:body-content-start/body-end-outset;z-index:998;opacity:.999}.page-columns .column-body-outset-right table{background:#fff}.page-columns .column-page{grid-column:page-start/page-end;z-index:998;opacity:.999}.page-columns .column-page table{background:#fff}.page-columns .column-page-inset{grid-column:page-start-inset/page-end-inset;z-index:998;opacity:.999}.page-columns .column-page-inset table{background:#fff}.page-columns .column-page-inset-left{grid-column:page-start-inset/body-content-end;z-index:998;opacity:.999}.page-columns .column-page-inset-left table{background:#fff}.page-columns .column-page-inset-right{grid-column:body-content-start/page-end-inset;z-index:998;opacity:.999}.page-columns .column-page-inset-right figcaption table{background:#fff}.page-columns .column-page-left{grid-column:page-start/body-content-end;z-index:998;opacity:.999}.page-columns .column-page-left table{background:#fff}.page-columns .column-page-right{grid-column:body-content-start/page-end;z-index:998;opacity:.999}.page-columns .column-page-right figcaption table{background:#fff}#quarto-content.page-columns #quarto-margin-sidebar,#quarto-content.page-columns #quarto-sidebar{z-index:1}@media(max-width: 991.98px){#quarto-content.page-columns #quarto-margin-sidebar.collapse,#quarto-content.page-columns #quarto-sidebar.collapse,#quarto-content.page-columns #quarto-margin-sidebar.collapsing,#quarto-content.page-columns #quarto-sidebar.collapsing{z-index:1055}}#quarto-content.page-columns main.column-page,#quarto-content.page-columns main.column-page-right,#quarto-content.page-columns main.column-page-left{z-index:0}.page-columns .column-screen-inset{grid-column:screen-start-inset/screen-end-inset;z-index:998;opacity:.999}.page-columns .column-screen-inset table{background:#fff}.page-columns .column-screen-inset-left{grid-column:screen-start-inset/body-content-end;z-index:998;opacity:.999}.page-columns .column-screen-inset-left table{background:#fff}.page-columns .column-screen-inset-right{grid-column:body-content-start/screen-end-inset;z-index:998;opacity:.999}.page-columns .column-screen-inset-right table{background:#fff}.page-columns .column-screen{grid-column:screen-start/screen-end;z-index:998;opacity:.999}.page-columns .column-screen table{background:#fff}.page-columns .column-screen-left{grid-column:screen-start/body-content-end;z-index:998;opacity:.999}.page-columns .column-screen-left table{background:#fff}.page-columns .column-screen-right{grid-column:body-content-start/screen-end;z-index:998;opacity:.999}.page-columns .column-screen-right table{background:#fff}.page-columns .column-screen-inset-shaded{grid-column:screen-start/screen-end;padding:1em;background:#f8f9fa;z-index:998;opacity:.999;margin-bottom:1em}.zindex-content{z-index:998;opacity:.999}.zindex-modal{z-index:1055;opacity:.999}.zindex-over-content{z-index:999;opacity:.999}img.img-fluid.column-screen,img.img-fluid.column-screen-inset-shaded,img.img-fluid.column-screen-inset,img.img-fluid.column-screen-inset-left,img.img-fluid.column-screen-inset-right,img.img-fluid.column-screen-left,img.img-fluid.column-screen-right{width:100%}@media(min-width: 992px){.margin-caption,div.aside,aside:not(.footnotes):not(.sidebar),.column-margin{grid-column:body-end/page-end !important;z-index:998}.column-sidebar{grid-column:page-start/body-start !important;z-index:998}.column-leftmargin{grid-column:screen-start-inset/body-start !important;z-index:998}.no-row-height{height:1em;overflow:visible}}@media(max-width: 991.98px){.margin-caption,div.aside,aside:not(.footnotes):not(.sidebar),.column-margin{grid-column:body-end/page-end !important;z-index:998}.no-row-height{height:1em;overflow:visible}.page-columns.page-full{overflow:visible}.page-columns.toc-left .margin-caption,.page-columns.toc-left div.aside,.page-columns.toc-left aside:not(.footnotes):not(.sidebar),.page-columns.toc-left .column-margin{grid-column:body-content-start/body-content-end !important;z-index:998;opacity:.999}.page-columns.toc-left .no-row-height{height:initial;overflow:initial}}@media(max-width: 767.98px){.margin-caption,div.aside,aside:not(.footnotes):not(.sidebar),.column-margin{grid-column:body-content-start/body-content-end !important;z-index:998;opacity:.999}.no-row-height{height:initial;overflow:initial}#quarto-margin-sidebar{display:none}#quarto-sidebar-toc-left{display:none}.hidden-sm{display:none}}.panel-grid{display:grid;grid-template-rows:repeat(1, 1fr);grid-template-columns:repeat(24, 1fr);gap:1em}.panel-grid .g-col-1{grid-column:auto/span 1}.panel-grid .g-col-2{grid-column:auto/span 2}.panel-grid .g-col-3{grid-column:auto/span 3}.panel-grid .g-col-4{grid-column:auto/span 4}.panel-grid .g-col-5{grid-column:auto/span 5}.panel-grid .g-col-6{grid-column:auto/span 6}.panel-grid .g-col-7{grid-column:auto/span 7}.panel-grid .g-col-8{grid-column:auto/span 8}.panel-grid .g-col-9{grid-column:auto/span 9}.panel-grid .g-col-10{grid-column:auto/span 10}.panel-grid .g-col-11{grid-column:auto/span 11}.panel-grid .g-col-12{grid-column:auto/span 12}.panel-grid .g-col-13{grid-column:auto/span 13}.panel-grid .g-col-14{grid-column:auto/span 14}.panel-grid .g-col-15{grid-column:auto/span 15}.panel-grid .g-col-16{grid-column:auto/span 16}.panel-grid .g-col-17{grid-column:auto/span 17}.panel-grid .g-col-18{grid-column:auto/span 18}.panel-grid .g-col-19{grid-column:auto/span 19}.panel-grid .g-col-20{grid-column:auto/span 20}.panel-grid .g-col-21{grid-column:auto/span 21}.panel-grid .g-col-22{grid-column:auto/span 22}.panel-grid .g-col-23{grid-column:auto/span 23}.panel-grid .g-col-24{grid-column:auto/span 24}.panel-grid .g-start-1{grid-column-start:1}.panel-grid .g-start-2{grid-column-start:2}.panel-grid .g-start-3{grid-column-start:3}.panel-grid .g-start-4{grid-column-start:4}.panel-grid .g-start-5{grid-column-start:5}.panel-grid .g-start-6{grid-column-start:6}.panel-grid .g-start-7{grid-column-start:7}.panel-grid .g-start-8{grid-column-start:8}.panel-grid .g-start-9{grid-column-start:9}.panel-grid .g-start-10{grid-column-start:10}.panel-grid .g-start-11{grid-column-start:11}.panel-grid .g-start-12{grid-column-start:12}.panel-grid .g-start-13{grid-column-start:13}.panel-grid .g-start-14{grid-column-start:14}.panel-grid .g-start-15{grid-column-start:15}.panel-grid .g-start-16{grid-column-start:16}.panel-grid .g-start-17{grid-column-start:17}.panel-grid .g-start-18{grid-column-start:18}.panel-grid .g-start-19{grid-column-start:19}.panel-grid .g-start-20{grid-column-start:20}.panel-grid .g-start-21{grid-column-start:21}.panel-grid .g-start-22{grid-column-start:22}.panel-grid .g-start-23{grid-column-start:23}@media(min-width: 576px){.panel-grid .g-col-sm-1{grid-column:auto/span 1}.panel-grid .g-col-sm-2{grid-column:auto/span 2}.panel-grid .g-col-sm-3{grid-column:auto/span 3}.panel-grid .g-col-sm-4{grid-column:auto/span 4}.panel-grid .g-col-sm-5{grid-column:auto/span 5}.panel-grid .g-col-sm-6{grid-column:auto/span 6}.panel-grid .g-col-sm-7{grid-column:auto/span 7}.panel-grid .g-col-sm-8{grid-column:auto/span 8}.panel-grid .g-col-sm-9{grid-column:auto/span 9}.panel-grid .g-col-sm-10{grid-column:auto/span 10}.panel-grid .g-col-sm-11{grid-column:auto/span 11}.panel-grid .g-col-sm-12{grid-column:auto/span 12}.panel-grid .g-col-sm-13{grid-column:auto/span 13}.panel-grid .g-col-sm-14{grid-column:auto/span 14}.panel-grid .g-col-sm-15{grid-column:auto/span 15}.panel-grid .g-col-sm-16{grid-column:auto/span 16}.panel-grid .g-col-sm-17{grid-column:auto/span 17}.panel-grid .g-col-sm-18{grid-column:auto/span 18}.panel-grid .g-col-sm-19{grid-column:auto/span 19}.panel-grid .g-col-sm-20{grid-column:auto/span 20}.panel-grid .g-col-sm-21{grid-column:auto/span 21}.panel-grid .g-col-sm-22{grid-column:auto/span 22}.panel-grid .g-col-sm-23{grid-column:auto/span 23}.panel-grid .g-col-sm-24{grid-column:auto/span 24}.panel-grid .g-start-sm-1{grid-column-start:1}.panel-grid .g-start-sm-2{grid-column-start:2}.panel-grid .g-start-sm-3{grid-column-start:3}.panel-grid .g-start-sm-4{grid-column-start:4}.panel-grid .g-start-sm-5{grid-column-start:5}.panel-grid .g-start-sm-6{grid-column-start:6}.panel-grid .g-start-sm-7{grid-column-start:7}.panel-grid .g-start-sm-8{grid-column-start:8}.panel-grid .g-start-sm-9{grid-column-start:9}.panel-grid .g-start-sm-10{grid-column-start:10}.panel-grid .g-start-sm-11{grid-column-start:11}.panel-grid .g-start-sm-12{grid-column-start:12}.panel-grid .g-start-sm-13{grid-column-start:13}.panel-grid .g-start-sm-14{grid-column-start:14}.panel-grid .g-start-sm-15{grid-column-start:15}.panel-grid .g-start-sm-16{grid-column-start:16}.panel-grid .g-start-sm-17{grid-column-start:17}.panel-grid .g-start-sm-18{grid-column-start:18}.panel-grid .g-start-sm-19{grid-column-start:19}.panel-grid .g-start-sm-20{grid-column-start:20}.panel-grid .g-start-sm-21{grid-column-start:21}.panel-grid .g-start-sm-22{grid-column-start:22}.panel-grid .g-start-sm-23{grid-column-start:23}}@media(min-width: 768px){.panel-grid .g-col-md-1{grid-column:auto/span 1}.panel-grid .g-col-md-2{grid-column:auto/span 2}.panel-grid .g-col-md-3{grid-column:auto/span 3}.panel-grid .g-col-md-4{grid-column:auto/span 4}.panel-grid .g-col-md-5{grid-column:auto/span 5}.panel-grid .g-col-md-6{grid-column:auto/span 6}.panel-grid .g-col-md-7{grid-column:auto/span 7}.panel-grid .g-col-md-8{grid-column:auto/span 8}.panel-grid .g-col-md-9{grid-column:auto/span 9}.panel-grid .g-col-md-10{grid-column:auto/span 10}.panel-grid .g-col-md-11{grid-column:auto/span 11}.panel-grid .g-col-md-12{grid-column:auto/span 12}.panel-grid .g-col-md-13{grid-column:auto/span 13}.panel-grid .g-col-md-14{grid-column:auto/span 14}.panel-grid .g-col-md-15{grid-column:auto/span 15}.panel-grid .g-col-md-16{grid-column:auto/span 16}.panel-grid .g-col-md-17{grid-column:auto/span 17}.panel-grid .g-col-md-18{grid-column:auto/span 18}.panel-grid .g-col-md-19{grid-column:auto/span 19}.panel-grid .g-col-md-20{grid-column:auto/span 20}.panel-grid .g-col-md-21{grid-column:auto/span 21}.panel-grid .g-col-md-22{grid-column:auto/span 22}.panel-grid .g-col-md-23{grid-column:auto/span 23}.panel-grid .g-col-md-24{grid-column:auto/span 24}.panel-grid .g-start-md-1{grid-column-start:1}.panel-grid .g-start-md-2{grid-column-start:2}.panel-grid .g-start-md-3{grid-column-start:3}.panel-grid .g-start-md-4{grid-column-start:4}.panel-grid .g-start-md-5{grid-column-start:5}.panel-grid .g-start-md-6{grid-column-start:6}.panel-grid .g-start-md-7{grid-column-start:7}.panel-grid .g-start-md-8{grid-column-start:8}.panel-grid .g-start-md-9{grid-column-start:9}.panel-grid .g-start-md-10{grid-column-start:10}.panel-grid .g-start-md-11{grid-column-start:11}.panel-grid .g-start-md-12{grid-column-start:12}.panel-grid .g-start-md-13{grid-column-start:13}.panel-grid .g-start-md-14{grid-column-start:14}.panel-grid .g-start-md-15{grid-column-start:15}.panel-grid .g-start-md-16{grid-column-start:16}.panel-grid .g-start-md-17{grid-column-start:17}.panel-grid .g-start-md-18{grid-column-start:18}.panel-grid .g-start-md-19{grid-column-start:19}.panel-grid .g-start-md-20{grid-column-start:20}.panel-grid .g-start-md-21{grid-column-start:21}.panel-grid .g-start-md-22{grid-column-start:22}.panel-grid .g-start-md-23{grid-column-start:23}}@media(min-width: 992px){.panel-grid .g-col-lg-1{grid-column:auto/span 1}.panel-grid .g-col-lg-2{grid-column:auto/span 2}.panel-grid .g-col-lg-3{grid-column:auto/span 3}.panel-grid .g-col-lg-4{grid-column:auto/span 4}.panel-grid .g-col-lg-5{grid-column:auto/span 5}.panel-grid .g-col-lg-6{grid-column:auto/span 6}.panel-grid .g-col-lg-7{grid-column:auto/span 7}.panel-grid .g-col-lg-8{grid-column:auto/span 8}.panel-grid .g-col-lg-9{grid-column:auto/span 9}.panel-grid .g-col-lg-10{grid-column:auto/span 10}.panel-grid .g-col-lg-11{grid-column:auto/span 11}.panel-grid .g-col-lg-12{grid-column:auto/span 12}.panel-grid .g-col-lg-13{grid-column:auto/span 13}.panel-grid .g-col-lg-14{grid-column:auto/span 14}.panel-grid .g-col-lg-15{grid-column:auto/span 15}.panel-grid .g-col-lg-16{grid-column:auto/span 16}.panel-grid .g-col-lg-17{grid-column:auto/span 17}.panel-grid .g-col-lg-18{grid-column:auto/span 18}.panel-grid .g-col-lg-19{grid-column:auto/span 19}.panel-grid .g-col-lg-20{grid-column:auto/span 20}.panel-grid .g-col-lg-21{grid-column:auto/span 21}.panel-grid .g-col-lg-22{grid-column:auto/span 22}.panel-grid .g-col-lg-23{grid-column:auto/span 23}.panel-grid .g-col-lg-24{grid-column:auto/span 24}.panel-grid .g-start-lg-1{grid-column-start:1}.panel-grid .g-start-lg-2{grid-column-start:2}.panel-grid .g-start-lg-3{grid-column-start:3}.panel-grid .g-start-lg-4{grid-column-start:4}.panel-grid .g-start-lg-5{grid-column-start:5}.panel-grid .g-start-lg-6{grid-column-start:6}.panel-grid .g-start-lg-7{grid-column-start:7}.panel-grid .g-start-lg-8{grid-column-start:8}.panel-grid .g-start-lg-9{grid-column-start:9}.panel-grid .g-start-lg-10{grid-column-start:10}.panel-grid .g-start-lg-11{grid-column-start:11}.panel-grid .g-start-lg-12{grid-column-start:12}.panel-grid .g-start-lg-13{grid-column-start:13}.panel-grid .g-start-lg-14{grid-column-start:14}.panel-grid .g-start-lg-15{grid-column-start:15}.panel-grid .g-start-lg-16{grid-column-start:16}.panel-grid .g-start-lg-17{grid-column-start:17}.panel-grid .g-start-lg-18{grid-column-start:18}.panel-grid .g-start-lg-19{grid-column-start:19}.panel-grid .g-start-lg-20{grid-column-start:20}.panel-grid .g-start-lg-21{grid-column-start:21}.panel-grid .g-start-lg-22{grid-column-start:22}.panel-grid .g-start-lg-23{grid-column-start:23}}@media(min-width: 1200px){.panel-grid .g-col-xl-1{grid-column:auto/span 1}.panel-grid .g-col-xl-2{grid-column:auto/span 2}.panel-grid .g-col-xl-3{grid-column:auto/span 3}.panel-grid .g-col-xl-4{grid-column:auto/span 4}.panel-grid .g-col-xl-5{grid-column:auto/span 5}.panel-grid .g-col-xl-6{grid-column:auto/span 6}.panel-grid .g-col-xl-7{grid-column:auto/span 7}.panel-grid .g-col-xl-8{grid-column:auto/span 8}.panel-grid .g-col-xl-9{grid-column:auto/span 9}.panel-grid .g-col-xl-10{grid-column:auto/span 10}.panel-grid .g-col-xl-11{grid-column:auto/span 11}.panel-grid .g-col-xl-12{grid-column:auto/span 12}.panel-grid .g-col-xl-13{grid-column:auto/span 13}.panel-grid .g-col-xl-14{grid-column:auto/span 14}.panel-grid .g-col-xl-15{grid-column:auto/span 15}.panel-grid .g-col-xl-16{grid-column:auto/span 16}.panel-grid .g-col-xl-17{grid-column:auto/span 17}.panel-grid .g-col-xl-18{grid-column:auto/span 18}.panel-grid .g-col-xl-19{grid-column:auto/span 19}.panel-grid .g-col-xl-20{grid-column:auto/span 20}.panel-grid .g-col-xl-21{grid-column:auto/span 21}.panel-grid .g-col-xl-22{grid-column:auto/span 22}.panel-grid .g-col-xl-23{grid-column:auto/span 23}.panel-grid .g-col-xl-24{grid-column:auto/span 24}.panel-grid .g-start-xl-1{grid-column-start:1}.panel-grid .g-start-xl-2{grid-column-start:2}.panel-grid .g-start-xl-3{grid-column-start:3}.panel-grid .g-start-xl-4{grid-column-start:4}.panel-grid .g-start-xl-5{grid-column-start:5}.panel-grid .g-start-xl-6{grid-column-start:6}.panel-grid .g-start-xl-7{grid-column-start:7}.panel-grid .g-start-xl-8{grid-column-start:8}.panel-grid .g-start-xl-9{grid-column-start:9}.panel-grid .g-start-xl-10{grid-column-start:10}.panel-grid .g-start-xl-11{grid-column-start:11}.panel-grid .g-start-xl-12{grid-column-start:12}.panel-grid .g-start-xl-13{grid-column-start:13}.panel-grid .g-start-xl-14{grid-column-start:14}.panel-grid .g-start-xl-15{grid-column-start:15}.panel-grid .g-start-xl-16{grid-column-start:16}.panel-grid .g-start-xl-17{grid-column-start:17}.panel-grid .g-start-xl-18{grid-column-start:18}.panel-grid .g-start-xl-19{grid-column-start:19}.panel-grid .g-start-xl-20{grid-column-start:20}.panel-grid .g-start-xl-21{grid-column-start:21}.panel-grid .g-start-xl-22{grid-column-start:22}.panel-grid .g-start-xl-23{grid-column-start:23}}@media(min-width: 1400px){.panel-grid .g-col-xxl-1{grid-column:auto/span 1}.panel-grid .g-col-xxl-2{grid-column:auto/span 2}.panel-grid .g-col-xxl-3{grid-column:auto/span 3}.panel-grid .g-col-xxl-4{grid-column:auto/span 4}.panel-grid .g-col-xxl-5{grid-column:auto/span 5}.panel-grid .g-col-xxl-6{grid-column:auto/span 6}.panel-grid .g-col-xxl-7{grid-column:auto/span 7}.panel-grid .g-col-xxl-8{grid-column:auto/span 8}.panel-grid .g-col-xxl-9{grid-column:auto/span 9}.panel-grid .g-col-xxl-10{grid-column:auto/span 10}.panel-grid .g-col-xxl-11{grid-column:auto/span 11}.panel-grid .g-col-xxl-12{grid-column:auto/span 12}.panel-grid .g-col-xxl-13{grid-column:auto/span 13}.panel-grid .g-col-xxl-14{grid-column:auto/span 14}.panel-grid .g-col-xxl-15{grid-column:auto/span 15}.panel-grid .g-col-xxl-16{grid-column:auto/span 16}.panel-grid .g-col-xxl-17{grid-column:auto/span 17}.panel-grid .g-col-xxl-18{grid-column:auto/span 18}.panel-grid .g-col-xxl-19{grid-column:auto/span 19}.panel-grid .g-col-xxl-20{grid-column:auto/span 20}.panel-grid .g-col-xxl-21{grid-column:auto/span 21}.panel-grid .g-col-xxl-22{grid-column:auto/span 22}.panel-grid .g-col-xxl-23{grid-column:auto/span 23}.panel-grid .g-col-xxl-24{grid-column:auto/span 24}.panel-grid .g-start-xxl-1{grid-column-start:1}.panel-grid .g-start-xxl-2{grid-column-start:2}.panel-grid .g-start-xxl-3{grid-column-start:3}.panel-grid .g-start-xxl-4{grid-column-start:4}.panel-grid .g-start-xxl-5{grid-column-start:5}.panel-grid .g-start-xxl-6{grid-column-start:6}.panel-grid .g-start-xxl-7{grid-column-start:7}.panel-grid .g-start-xxl-8{grid-column-start:8}.panel-grid .g-start-xxl-9{grid-column-start:9}.panel-grid .g-start-xxl-10{grid-column-start:10}.panel-grid .g-start-xxl-11{grid-column-start:11}.panel-grid .g-start-xxl-12{grid-column-start:12}.panel-grid .g-start-xxl-13{grid-column-start:13}.panel-grid .g-start-xxl-14{grid-column-start:14}.panel-grid .g-start-xxl-15{grid-column-start:15}.panel-grid .g-start-xxl-16{grid-column-start:16}.panel-grid .g-start-xxl-17{grid-column-start:17}.panel-grid .g-start-xxl-18{grid-column-start:18}.panel-grid .g-start-xxl-19{grid-column-start:19}.panel-grid .g-start-xxl-20{grid-column-start:20}.panel-grid .g-start-xxl-21{grid-column-start:21}.panel-grid .g-start-xxl-22{grid-column-start:22}.panel-grid .g-start-xxl-23{grid-column-start:23}}main{margin-top:1em;margin-bottom:1em}h1,.h1,h2,.h2{color:inherit;margin-top:2rem;margin-bottom:1rem;font-weight:600}h1.title,.title.h1{margin-top:0}main.content>section:first-of-type>h2:first-child,main.content>section:first-of-type>.h2:first-child{margin-top:0}h2,.h2{border-bottom:1px solid #dee2e6;padding-bottom:.5rem}h3,.h3{font-weight:600}h3,.h3,h4,.h4{opacity:.9;margin-top:1.5rem}h5,.h5,h6,.h6{opacity:.9}.header-section-number{color:#5a6570}.nav-link.active .header-section-number{color:inherit}mark,.mark{padding:0em}.panel-caption,.figure-caption,.subfigure-caption,.table-caption,figcaption,caption{font-size:.9rem;color:#5a6570}.quarto-layout-cell[data-ref-parent] caption{color:#5a6570}.column-margin figcaption,.margin-caption,div.aside,aside,.column-margin{color:#5a6570;font-size:.825rem}.panel-caption.margin-caption{text-align:inherit}.column-margin.column-container p{margin-bottom:0}.column-margin.column-container>*:not(.collapse):first-child{padding-bottom:.5em;display:block}.column-margin.column-container>*:not(.collapse):not(:first-child){padding-top:.5em;padding-bottom:.5em;display:block}.column-margin.column-container>*.collapse:not(.show){display:none}@media(min-width: 768px){.column-margin.column-container .callout-margin-content:first-child{margin-top:4.5em}.column-margin.column-container .callout-margin-content-simple:first-child{margin-top:3.5em}}.margin-caption>*{padding-top:.5em;padding-bottom:.5em}@media(max-width: 767.98px){.quarto-layout-row{flex-direction:column}}.nav-tabs .nav-item{margin-top:1px;cursor:pointer}.tab-content{margin-top:0px;border-left:#dee2e6 1px solid;border-right:#dee2e6 1px solid;border-bottom:#dee2e6 1px solid;margin-left:0;padding:1em;margin-bottom:1em}@media(max-width: 767.98px){.layout-sidebar{margin-left:0;margin-right:0}}.panel-sidebar,.panel-sidebar .form-control,.panel-input,.panel-input .form-control,.selectize-dropdown{font-size:.9rem}.panel-sidebar .form-control,.panel-input .form-control{padding-top:.1rem}.tab-pane div.sourceCode{margin-top:0px}.tab-pane>p{padding-top:0}.tab-pane>p:nth-child(1){padding-top:0}.tab-pane>p:last-child{margin-bottom:0}.tab-pane>pre:last-child{margin-bottom:0}.tab-content>.tab-pane:not(.active){display:none !important}div.sourceCode{background-color:rgba(233,236,239,.65);border:1px solid rgba(233,236,239,.65);border-radius:.375rem}pre.sourceCode{background-color:rgba(0,0,0,0)}pre.sourceCode{border:none;font-size:.875em;overflow:visible !important;padding:.4em}.callout pre.sourceCode{padding-left:0}div.sourceCode{overflow-y:hidden}.callout div.sourceCode{margin-left:initial}.blockquote{font-size:inherit;padding-left:1rem;padding-right:1.5rem;color:#5a6570}.blockquote h1:first-child,.blockquote .h1:first-child,.blockquote h2:first-child,.blockquote .h2:first-child,.blockquote h3:first-child,.blockquote .h3:first-child,.blockquote h4:first-child,.blockquote .h4:first-child,.blockquote h5:first-child,.blockquote .h5:first-child{margin-top:0}pre{background-color:initial;padding:initial;border:initial}p pre code:not(.sourceCode),li pre code:not(.sourceCode),pre code:not(.sourceCode){background-color:initial}p code:not(.sourceCode),li code:not(.sourceCode),td code:not(.sourceCode){background-color:#f8f9fa;padding:.2em}nav p code:not(.sourceCode),nav li code:not(.sourceCode),nav td code:not(.sourceCode){background-color:rgba(0,0,0,0);padding:0}td code:not(.sourceCode){white-space:pre-wrap}#quarto-embedded-source-code-modal>.modal-dialog{max-width:1000px;padding-left:1.75rem;padding-right:1.75rem}#quarto-embedded-source-code-modal>.modal-dialog>.modal-content>.modal-body{padding:0}#quarto-embedded-source-code-modal>.modal-dialog>.modal-content>.modal-body div.sourceCode{margin:0;padding:.2rem .2rem;border-radius:0px;border:none}#quarto-embedded-source-code-modal>.modal-dialog>.modal-content>.modal-header{padding:.7rem}.code-tools-button{font-size:1rem;padding:.15rem .15rem;margin-left:5px;color:rgba(33,37,41,.75);background-color:rgba(0,0,0,0);transition:initial;cursor:pointer}.code-tools-button>.bi::before{display:inline-block;height:1rem;width:1rem;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml, ');background-repeat:no-repeat;background-size:1rem 1rem}.code-tools-button:hover>.bi::before{background-image:url('data:image/svg+xml, ')}#quarto-embedded-source-code-modal .code-copy-button>.bi::before{background-image:url('data:image/svg+xml, ')}#quarto-embedded-source-code-modal .code-copy-button-checked>.bi::before{background-image:url('data:image/svg+xml, ')}.sidebar{will-change:top;transition:top 200ms linear;position:sticky;overflow-y:auto;padding-top:1.2em;max-height:100vh}.sidebar.toc-left,.sidebar.margin-sidebar{top:0px;padding-top:1em}.sidebar.quarto-banner-title-block-sidebar>*{padding-top:1.65em}figure .quarto-notebook-link{margin-top:.5em}.quarto-notebook-link{font-size:.75em;color:rgba(33,37,41,.75);margin-bottom:1em;text-decoration:none;display:block}.quarto-notebook-link:hover{text-decoration:underline;color:#0d6efd}.quarto-notebook-link::before{display:inline-block;height:.75rem;width:.75rem;margin-bottom:0em;margin-right:.25em;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml, ');background-repeat:no-repeat;background-size:.75rem .75rem}.toc-actions i.bi,.quarto-code-links i.bi,.quarto-other-links i.bi,.quarto-alternate-notebooks i.bi,.quarto-alternate-formats i.bi{margin-right:.4em;font-size:.8rem}.quarto-other-links-text-target .quarto-code-links i.bi,.quarto-other-links-text-target .quarto-other-links i.bi{margin-right:.2em}.quarto-other-formats-text-target .quarto-alternate-formats i.bi{margin-right:.1em}.toc-actions i.bi.empty,.quarto-code-links i.bi.empty,.quarto-other-links i.bi.empty,.quarto-alternate-notebooks i.bi.empty,.quarto-alternate-formats i.bi.empty{padding-left:1em}.quarto-notebook h2,.quarto-notebook .h2{border-bottom:none}.quarto-notebook .cell-container{display:flex}.quarto-notebook .cell-container .cell{flex-grow:4}.quarto-notebook .cell-container .cell-decorator{padding-top:1.5em;padding-right:1em;text-align:right}.quarto-notebook .cell-container.code-fold .cell-decorator{padding-top:3em}.quarto-notebook .cell-code code{white-space:pre-wrap}.quarto-notebook .cell .cell-output-stderr pre code,.quarto-notebook .cell .cell-output-stdout pre code{white-space:pre-wrap;overflow-wrap:anywhere}.toc-actions,.quarto-alternate-formats,.quarto-other-links,.quarto-code-links,.quarto-alternate-notebooks{padding-left:0em}.sidebar .toc-actions a,.sidebar .quarto-alternate-formats a,.sidebar .quarto-other-links a,.sidebar .quarto-code-links a,.sidebar .quarto-alternate-notebooks a,.sidebar nav[role=doc-toc] a{text-decoration:none}.sidebar .toc-actions a:hover,.sidebar .quarto-other-links a:hover,.sidebar .quarto-code-links a:hover,.sidebar .quarto-alternate-formats a:hover,.sidebar .quarto-alternate-notebooks a:hover{color:#0d6efd}.sidebar .toc-actions h2,.sidebar .toc-actions .h2,.sidebar .quarto-code-links h2,.sidebar .quarto-code-links .h2,.sidebar .quarto-other-links h2,.sidebar .quarto-other-links .h2,.sidebar .quarto-alternate-notebooks h2,.sidebar .quarto-alternate-notebooks .h2,.sidebar .quarto-alternate-formats h2,.sidebar .quarto-alternate-formats .h2,.sidebar nav[role=doc-toc]>h2,.sidebar nav[role=doc-toc]>.h2{font-weight:500;margin-bottom:.2rem;margin-top:.3rem;font-family:inherit;border-bottom:0;padding-bottom:0;padding-top:0px}.sidebar .toc-actions>h2,.sidebar .toc-actions>.h2,.sidebar .quarto-code-links>h2,.sidebar .quarto-code-links>.h2,.sidebar .quarto-other-links>h2,.sidebar .quarto-other-links>.h2,.sidebar .quarto-alternate-notebooks>h2,.sidebar .quarto-alternate-notebooks>.h2,.sidebar .quarto-alternate-formats>h2,.sidebar .quarto-alternate-formats>.h2{font-size:.8rem}.sidebar nav[role=doc-toc]>h2,.sidebar nav[role=doc-toc]>.h2{font-size:.875rem}.sidebar nav[role=doc-toc]>ul a{border-left:1px solid #e9ecef;padding-left:.6rem}.sidebar .toc-actions h2>ul a,.sidebar .toc-actions .h2>ul a,.sidebar .quarto-code-links h2>ul a,.sidebar .quarto-code-links .h2>ul a,.sidebar .quarto-other-links h2>ul a,.sidebar .quarto-other-links .h2>ul a,.sidebar .quarto-alternate-notebooks h2>ul a,.sidebar .quarto-alternate-notebooks .h2>ul a,.sidebar .quarto-alternate-formats h2>ul a,.sidebar .quarto-alternate-formats .h2>ul a{border-left:none;padding-left:.6rem}.sidebar .toc-actions ul a:empty,.sidebar .quarto-code-links ul a:empty,.sidebar .quarto-other-links ul a:empty,.sidebar .quarto-alternate-notebooks ul a:empty,.sidebar .quarto-alternate-formats ul a:empty,.sidebar nav[role=doc-toc]>ul a:empty{display:none}.sidebar .toc-actions ul,.sidebar .quarto-code-links ul,.sidebar .quarto-other-links ul,.sidebar .quarto-alternate-notebooks ul,.sidebar .quarto-alternate-formats ul{padding-left:0;list-style:none}.sidebar nav[role=doc-toc] ul{list-style:none;padding-left:0;list-style:none}.sidebar nav[role=doc-toc]>ul{margin-left:.45em}.quarto-margin-sidebar nav[role=doc-toc]{padding-left:.5em}.sidebar .toc-actions>ul,.sidebar .quarto-code-links>ul,.sidebar .quarto-other-links>ul,.sidebar .quarto-alternate-notebooks>ul,.sidebar .quarto-alternate-formats>ul{font-size:.8rem}.sidebar nav[role=doc-toc]>ul{font-size:.875rem}.sidebar .toc-actions ul li a,.sidebar .quarto-code-links ul li a,.sidebar .quarto-other-links ul li a,.sidebar .quarto-alternate-notebooks ul li a,.sidebar .quarto-alternate-formats ul li a,.sidebar nav[role=doc-toc]>ul li a{line-height:1.1rem;padding-bottom:.2rem;padding-top:.2rem;color:inherit}.sidebar nav[role=doc-toc] ul>li>ul>li>a{padding-left:1.2em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>a{padding-left:2.4em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>ul>li>a{padding-left:3.6em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>ul>li>ul>li>a{padding-left:4.8em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>ul>li>ul>li>ul>li>a{padding-left:6em}.sidebar nav[role=doc-toc] ul>li>a.active,.sidebar nav[role=doc-toc] ul>li>ul>li>a.active{border-left:1px solid #0d6efd;color:#0d6efd !important}.sidebar nav[role=doc-toc] ul>li>a:hover,.sidebar nav[role=doc-toc] ul>li>ul>li>a:hover{color:#0d6efd !important}kbd,.kbd{color:#212529;background-color:#f8f9fa;border:1px solid;border-radius:5px;border-color:#dee2e6}.quarto-appendix-contents div.hanging-indent{margin-left:0em}.quarto-appendix-contents div.hanging-indent div.csl-entry{margin-left:1em;text-indent:-1em}.citation a,.footnote-ref{text-decoration:none}.footnotes ol{padding-left:1em}.tippy-content>*{margin-bottom:.7em}.tippy-content>*:last-child{margin-bottom:0}.callout{margin-top:1.25rem;margin-bottom:1.25rem;border-radius:.375rem;overflow-wrap:break-word}.callout .callout-title-container{overflow-wrap:anywhere}.callout.callout-style-simple{padding:.4em .7em;border-left:5px solid;border-right:1px solid #dee2e6;border-top:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.callout.callout-style-default{border-left:5px solid;border-right:1px solid #dee2e6;border-top:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.callout .callout-body-container{flex-grow:1}.callout.callout-style-simple .callout-body{font-size:.9rem;font-weight:400}.callout.callout-style-default .callout-body{font-size:.9rem;font-weight:400}.callout:not(.no-icon).callout-titled.callout-style-simple .callout-body{padding-left:1.6em}.callout.callout-titled>.callout-header{padding-top:.2em;margin-bottom:-0.2em}.callout.callout-style-simple>div.callout-header{border-bottom:none;font-size:.9rem;font-weight:600;opacity:75%}.callout.callout-style-default>div.callout-header{border-bottom:none;font-weight:600;opacity:85%;font-size:.9rem;padding-left:.5em;padding-right:.5em}.callout.callout-style-default .callout-body{padding-left:.5em;padding-right:.5em}.callout.callout-style-default .callout-body>:first-child{padding-top:.5rem;margin-top:0}.callout>div.callout-header[data-bs-toggle=collapse]{cursor:pointer}.callout.callout-style-default .callout-header[aria-expanded=false],.callout.callout-style-default .callout-header[aria-expanded=true]{padding-top:0px;margin-bottom:0px;align-items:center}.callout.callout-titled .callout-body>:last-child:not(.sourceCode),.callout.callout-titled .callout-body>div>:last-child:not(.sourceCode){padding-bottom:.5rem;margin-bottom:0}.callout:not(.callout-titled) .callout-body>:first-child,.callout:not(.callout-titled) .callout-body>div>:first-child{margin-top:.25rem}.callout:not(.callout-titled) .callout-body>:last-child,.callout:not(.callout-titled) .callout-body>div>:last-child{margin-bottom:.2rem}.callout.callout-style-simple .callout-icon::before,.callout.callout-style-simple .callout-toggle::before{height:1rem;width:1rem;display:inline-block;content:"";background-repeat:no-repeat;background-size:1rem 1rem}.callout.callout-style-default .callout-icon::before,.callout.callout-style-default .callout-toggle::before{height:.9rem;width:.9rem;display:inline-block;content:"";background-repeat:no-repeat;background-size:.9rem .9rem}.callout.callout-style-default .callout-toggle::before{margin-top:5px}.callout .callout-btn-toggle .callout-toggle::before{transition:transform .2s linear}.callout .callout-header[aria-expanded=false] .callout-toggle::before{transform:rotate(-90deg)}.callout .callout-header[aria-expanded=true] .callout-toggle::before{transform:none}.callout.callout-style-simple:not(.no-icon) div.callout-icon-container{padding-top:.2em;padding-right:.55em}.callout.callout-style-default:not(.no-icon) div.callout-icon-container{padding-top:.1em;padding-right:.35em}.callout.callout-style-default:not(.no-icon) div.callout-title-container{margin-top:-1px}.callout.callout-style-default.callout-caution:not(.no-icon) div.callout-icon-container{padding-top:.3em;padding-right:.35em}.callout>.callout-body>.callout-icon-container>.no-icon,.callout>.callout-header>.callout-icon-container>.no-icon{display:none}div.callout.callout{border-left-color:rgba(33,37,41,.75)}div.callout.callout-style-default>.callout-header{background-color:rgba(33,37,41,.75)}div.callout-note.callout{border-left-color:#0d6efd}div.callout-note.callout-style-default>.callout-header{background-color:#e7f1ff}div.callout-note:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml, ');}div.callout-note.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml, ');}div.callout-note .callout-toggle::before{background-image:url('data:image/svg+xml, ')}div.callout-tip.callout{border-left-color:#198754}div.callout-tip.callout-style-default>.callout-header{background-color:#e8f3ee}div.callout-tip:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml, ');}div.callout-tip.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml, ');}div.callout-tip .callout-toggle::before{background-image:url('data:image/svg+xml, ')}div.callout-warning.callout{border-left-color:#ffc107}div.callout-warning.callout-style-default>.callout-header{background-color:#fff9e6}div.callout-warning:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml, ');}div.callout-warning.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml, ');}div.callout-warning .callout-toggle::before{background-image:url('data:image/svg+xml, ')}div.callout-caution.callout{border-left-color:#fd7e14}div.callout-caution.callout-style-default>.callout-header{background-color:#fff2e8}div.callout-caution:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml, ');}div.callout-caution.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml, ');}div.callout-caution .callout-toggle::before{background-image:url('data:image/svg+xml, ')}div.callout-important.callout{border-left-color:#dc3545}div.callout-important.callout-style-default>.callout-header{background-color:#fcebec}div.callout-important:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml, ');}div.callout-important.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml, ');}div.callout-important .callout-toggle::before{background-image:url('data:image/svg+xml, ')}.quarto-toggle-container{display:flex;align-items:center}.quarto-reader-toggle .bi::before,.quarto-color-scheme-toggle .bi::before{display:inline-block;height:1rem;width:1rem;content:"";background-repeat:no-repeat;background-size:1rem 1rem}.sidebar-navigation{padding-left:20px}.navbar{background-color:#517699;color:#fdfefe}.navbar .quarto-color-scheme-toggle:not(.alternate) .bi::before{background-image:url('data:image/svg+xml, ')}.navbar .quarto-color-scheme-toggle.alternate .bi::before{background-image:url('data:image/svg+xml, ')}.sidebar-navigation .quarto-color-scheme-toggle:not(.alternate) .bi::before{background-image:url('data:image/svg+xml, ')}.sidebar-navigation .quarto-color-scheme-toggle.alternate .bi::before{background-image:url('data:image/svg+xml, ')}.quarto-sidebar-toggle{border-color:#dee2e6;border-bottom-left-radius:.375rem;border-bottom-right-radius:.375rem;border-style:solid;border-width:1px;overflow:hidden;border-top-width:0px;padding-top:0px !important}.quarto-sidebar-toggle-title{cursor:pointer;padding-bottom:2px;margin-left:.25em;text-align:center;font-weight:400;font-size:.775em}#quarto-content .quarto-sidebar-toggle{background:#fafafa}#quarto-content .quarto-sidebar-toggle-title{color:#212529}.quarto-sidebar-toggle-icon{color:#dee2e6;margin-right:.5em;float:right;transition:transform .2s ease}.quarto-sidebar-toggle-icon::before{padding-top:5px}.quarto-sidebar-toggle.expanded .quarto-sidebar-toggle-icon{transform:rotate(-180deg)}.quarto-sidebar-toggle.expanded .quarto-sidebar-toggle-title{border-bottom:solid #dee2e6 1px}.quarto-sidebar-toggle-contents{background-color:#fff;padding-right:10px;padding-left:10px;margin-top:0px !important;transition:max-height .5s ease}.quarto-sidebar-toggle.expanded .quarto-sidebar-toggle-contents{padding-top:1em;padding-bottom:10px}@media(max-width: 767.98px){.sidebar-menu-container{padding-bottom:5em}}.quarto-sidebar-toggle:not(.expanded) .quarto-sidebar-toggle-contents{padding-top:0px !important;padding-bottom:0px}nav[role=doc-toc]{z-index:1020}#quarto-sidebar>*,nav[role=doc-toc]>*{transition:opacity .1s ease,border .1s ease}#quarto-sidebar.slow>*,nav[role=doc-toc].slow>*{transition:opacity .4s ease,border .4s ease}.quarto-color-scheme-toggle:not(.alternate).top-right .bi::before{background-image:url('data:image/svg+xml, ')}.quarto-color-scheme-toggle.alternate.top-right .bi::before{background-image:url('data:image/svg+xml, ')}#quarto-appendix.default{border-top:1px solid #dee2e6}#quarto-appendix.default{background-color:#fff;padding-top:1.5em;margin-top:2em;z-index:998}#quarto-appendix.default .quarto-appendix-heading{margin-top:0;line-height:1.4em;font-weight:600;opacity:.9;border-bottom:none;margin-bottom:0}#quarto-appendix.default .footnotes ol,#quarto-appendix.default .footnotes ol li>p:last-of-type,#quarto-appendix.default .quarto-appendix-contents>p:last-of-type{margin-bottom:0}#quarto-appendix.default .footnotes ol{margin-left:.5em}#quarto-appendix.default .quarto-appendix-secondary-label{margin-bottom:.4em}#quarto-appendix.default .quarto-appendix-bibtex{font-size:.7em;padding:1em;border:solid 1px #dee2e6;margin-bottom:1em}#quarto-appendix.default .quarto-appendix-bibtex code.sourceCode{white-space:pre-wrap}#quarto-appendix.default .quarto-appendix-citeas{font-size:.9em;padding:1em;border:solid 1px #dee2e6;margin-bottom:1em}#quarto-appendix.default .quarto-appendix-heading{font-size:1em !important}#quarto-appendix.default *[role=doc-endnotes]>ol,#quarto-appendix.default .quarto-appendix-contents>*:not(h2):not(.h2){font-size:.9em}#quarto-appendix.default section{padding-bottom:1.5em}#quarto-appendix.default section *[role=doc-endnotes],#quarto-appendix.default section>*:not(a){opacity:.9;word-wrap:break-word}.btn.btn-quarto,div.cell-output-display .btn-quarto{--bs-btn-color: #fefefe;--bs-btn-bg: #6c757d;--bs-btn-border-color: #6c757d;--bs-btn-hover-color: #fefefe;--bs-btn-hover-bg: #828a91;--bs-btn-hover-border-color: #7b838a;--bs-btn-focus-shadow-rgb: 130, 138, 144;--bs-btn-active-color: #000;--bs-btn-active-bg: #899197;--bs-btn-active-border-color: #7b838a;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #ffffff;--bs-btn-disabled-bg: #6c757d;--bs-btn-disabled-border-color: #6c757d}nav.quarto-secondary-nav.color-navbar{background-color:#517699;color:#fdfefe}nav.quarto-secondary-nav.color-navbar h1,nav.quarto-secondary-nav.color-navbar .h1,nav.quarto-secondary-nav.color-navbar .quarto-btn-toggle{color:#fdfefe}@media(max-width: 991.98px){body.nav-sidebar .quarto-title-banner{margin-bottom:0;padding-bottom:1em}body.nav-sidebar #title-block-header{margin-block-end:0}}p.subtitle{margin-top:.25em;margin-bottom:.5em}code a:any-link{color:inherit;text-decoration-color:#6c757d}/*! light */div.observablehq table thead tr th{background-color:var(--bs-body-bg)}input,button,select,optgroup,textarea{background-color:var(--bs-body-bg)}.code-annotated .code-copy-button{margin-right:1.25em;margin-top:0;padding-bottom:0;padding-top:3px}.code-annotation-gutter-bg{background-color:#fff}.code-annotation-gutter{background-color:rgba(233,236,239,.65)}.code-annotation-gutter,.code-annotation-gutter-bg{height:100%;width:calc(20px + .5em);position:absolute;top:0;right:0}dl.code-annotation-container-grid dt{margin-right:1em;margin-top:.25rem}dl.code-annotation-container-grid dt{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;color:#383f45;border:solid #383f45 1px;border-radius:50%;height:22px;width:22px;line-height:22px;font-size:11px;text-align:center;vertical-align:middle;text-decoration:none}dl.code-annotation-container-grid dt[data-target-cell]{cursor:pointer}dl.code-annotation-container-grid dt[data-target-cell].code-annotation-active{color:#fff;border:solid #aaa 1px;background-color:#aaa}pre.code-annotation-code{padding-top:0;padding-bottom:0}pre.code-annotation-code code{z-index:3}#code-annotation-line-highlight-gutter{width:100%;border-top:solid rgba(170,170,170,.2666666667) 1px;border-bottom:solid rgba(170,170,170,.2666666667) 1px;z-index:2;background-color:rgba(170,170,170,.1333333333)}#code-annotation-line-highlight{margin-left:-4em;width:calc(100% + 4em);border-top:solid rgba(170,170,170,.2666666667) 1px;border-bottom:solid rgba(170,170,170,.2666666667) 1px;z-index:2;background-color:rgba(170,170,170,.1333333333)}code.sourceCode .code-annotation-anchor.code-annotation-active{background-color:var(--quarto-hl-normal-color, #aaaaaa);border:solid var(--quarto-hl-normal-color, #aaaaaa) 1px;color:#e9ecef;font-weight:bolder}code.sourceCode .code-annotation-anchor{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;color:var(--quarto-hl-co-color);border:solid var(--quarto-hl-co-color) 1px;border-radius:50%;height:18px;width:18px;font-size:9px;margin-top:2px}code.sourceCode button.code-annotation-anchor{padding:2px;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none}code.sourceCode a.code-annotation-anchor{line-height:18px;text-align:center;vertical-align:middle;cursor:default;text-decoration:none}@media print{.page-columns .column-screen-inset{grid-column:page-start-inset/page-end-inset;z-index:998;opacity:.999}.page-columns .column-screen-inset table{background:#fff}.page-columns .column-screen-inset-left{grid-column:page-start-inset/body-content-end;z-index:998;opacity:.999}.page-columns .column-screen-inset-left table{background:#fff}.page-columns .column-screen-inset-right{grid-column:body-content-start/page-end-inset;z-index:998;opacity:.999}.page-columns .column-screen-inset-right table{background:#fff}.page-columns .column-screen{grid-column:page-start/page-end;z-index:998;opacity:.999}.page-columns .column-screen table{background:#fff}.page-columns .column-screen-left{grid-column:page-start/body-content-end;z-index:998;opacity:.999}.page-columns .column-screen-left table{background:#fff}.page-columns .column-screen-right{grid-column:body-content-start/page-end;z-index:998;opacity:.999}.page-columns .column-screen-right table{background:#fff}.page-columns .column-screen-inset-shaded{grid-column:page-start-inset/page-end-inset;padding:1em;background:#f8f9fa;z-index:998;opacity:.999;margin-bottom:1em}}.quarto-video{margin-bottom:1em}.table{border-top:1px solid #d3d8dc;border-bottom:1px solid #d3d8dc}.table>thead{border-top-width:0;border-bottom:1px solid #9ba5ae}.table a{word-break:break-word}.table>:not(caption)>*>*{background-color:unset;color:unset}#quarto-document-content .crosstalk-input .checkbox input[type=checkbox],#quarto-document-content .crosstalk-input .checkbox-inline input[type=checkbox]{position:unset;margin-top:unset;margin-left:unset}#quarto-document-content .row{margin-left:unset;margin-right:unset}.quarto-xref{white-space:nowrap}a.external:after{content:"";background-image:url('data:image/svg+xml, ');background-size:contain;background-repeat:no-repeat;background-position:center center;margin-left:.2em;padding-right:.75em}div.sourceCode code a.external:after{content:none}a.external:after:hover{cursor:pointer}.quarto-ext-icon{display:inline-block;font-size:.75em;padding-left:.3em}.code-with-filename .code-with-filename-file{margin-bottom:0;padding-bottom:2px;padding-top:2px;padding-left:.7em;border:var(--quarto-border-width) solid var(--quarto-border-color);border-radius:var(--quarto-border-radius);border-bottom:0;border-bottom-left-radius:0%;border-bottom-right-radius:0%}.code-with-filename div.sourceCode,.reveal .code-with-filename div.sourceCode{margin-top:0;border-top-left-radius:0%;border-top-right-radius:0%}.code-with-filename .code-with-filename-file pre{margin-bottom:0}.code-with-filename .code-with-filename-file{background-color:rgba(219,219,219,.8)}.quarto-dark .code-with-filename .code-with-filename-file{background-color:#555}.code-with-filename .code-with-filename-file strong{font-weight:400}.quarto-title-banner{margin-bottom:1em;color:#fdfefe;background:#517699}.quarto-title-banner a{color:#fdfefe}.quarto-title-banner h1,.quarto-title-banner .h1,.quarto-title-banner h2,.quarto-title-banner .h2{color:#fdfefe}.quarto-title-banner .code-tools-button{color:#b9dcdc}.quarto-title-banner .code-tools-button:hover{color:#fdfefe}.quarto-title-banner .code-tools-button>.bi::before{background-image:url('data:image/svg+xml, ')}.quarto-title-banner .code-tools-button:hover>.bi::before{background-image:url('data:image/svg+xml, ')}.quarto-title-banner .quarto-title .title{font-weight:600}.quarto-title-banner .quarto-categories{margin-top:.75em}@media(min-width: 992px){.quarto-title-banner{padding-top:2.5em;padding-bottom:2.5em}}@media(max-width: 991.98px){.quarto-title-banner{padding-top:1em;padding-bottom:1em}}@media(max-width: 767.98px){body.hypothesis-enabled #title-block-header>*{padding-right:20px}}main.quarto-banner-title-block>section:first-child>h2,main.quarto-banner-title-block>section:first-child>.h2,main.quarto-banner-title-block>section:first-child>h3,main.quarto-banner-title-block>section:first-child>.h3,main.quarto-banner-title-block>section:first-child>h4,main.quarto-banner-title-block>section:first-child>.h4{margin-top:0}.quarto-title .quarto-categories{display:flex;flex-wrap:wrap;row-gap:.5em;column-gap:.4em;padding-bottom:.5em;margin-top:.75em}.quarto-title .quarto-categories .quarto-category{padding:.25em .75em;font-size:.65em;text-transform:uppercase;border:solid 1px;border-radius:.375rem;opacity:.6}.quarto-title .quarto-categories .quarto-category a{color:inherit}.quarto-title-meta-container{display:grid;grid-template-columns:1fr auto}.quarto-title-meta-column-end{display:flex;flex-direction:column;padding-left:1em}.quarto-title-meta-column-end a .bi{margin-right:.3em}#title-block-header.quarto-title-block.default .quarto-title-meta{display:grid;grid-template-columns:minmax(max-content, 1fr) 1fr;grid-column-gap:1em}#title-block-header.quarto-title-block.default .quarto-title .title{margin-bottom:0}#title-block-header.quarto-title-block.default .quarto-title-author-orcid img{margin-top:-0.2em;height:.8em;width:.8em}#title-block-header.quarto-title-block.default .quarto-title-author-email{opacity:.7}#title-block-header.quarto-title-block.default .quarto-description p:last-of-type{margin-bottom:0}#title-block-header.quarto-title-block.default .quarto-title-meta-contents p,#title-block-header.quarto-title-block.default .quarto-title-authors p,#title-block-header.quarto-title-block.default .quarto-title-affiliations p{margin-bottom:.1em}#title-block-header.quarto-title-block.default .quarto-title-meta-heading{text-transform:uppercase;margin-top:1em;font-size:.8em;opacity:.8;font-weight:400}#title-block-header.quarto-title-block.default .quarto-title-meta-contents{font-size:.9em}#title-block-header.quarto-title-block.default .quarto-title-meta-contents p.affiliation:last-of-type{margin-bottom:.1em}#title-block-header.quarto-title-block.default p.affiliation{margin-bottom:.1em}#title-block-header.quarto-title-block.default .keywords,#title-block-header.quarto-title-block.default .description,#title-block-header.quarto-title-block.default .abstract{margin-top:0}#title-block-header.quarto-title-block.default .keywords>p,#title-block-header.quarto-title-block.default .description>p,#title-block-header.quarto-title-block.default .abstract>p{font-size:.9em}#title-block-header.quarto-title-block.default .keywords>p:last-of-type,#title-block-header.quarto-title-block.default .description>p:last-of-type,#title-block-header.quarto-title-block.default .abstract>p:last-of-type{margin-bottom:0}#title-block-header.quarto-title-block.default .keywords .block-title,#title-block-header.quarto-title-block.default .description .block-title,#title-block-header.quarto-title-block.default .abstract .block-title{margin-top:1em;text-transform:uppercase;font-size:.8em;opacity:.8;font-weight:400}#title-block-header.quarto-title-block.default .quarto-title-meta-author{display:grid;grid-template-columns:minmax(max-content, 1fr) 1fr;grid-column-gap:1em}.quarto-title-tools-only{display:flex;justify-content:right}
diff --git a/1 PA Decline/article ready_files/libs/bootstrap/bootstrap.min.js b/1 PA Decline/article ready_files/libs/bootstrap/bootstrap.min.js
new file mode 100644
index 0000000..e8f21f7
--- /dev/null
+++ b/1 PA Decline/article ready_files/libs/bootstrap/bootstrap.min.js
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v5.3.1 (https://getbootstrap.com/)
+ * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ */
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t=new Map,e={set(e,i,n){t.has(e)||t.set(e,new Map);const s=t.get(e);s.has(i)||0===s.size?s.set(i,n):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(s.keys())[0]}.`)},get:(e,i)=>t.has(e)&&t.get(e).get(i)||null,remove(e,i){if(!t.has(e))return;const n=t.get(e);n.delete(i),0===n.size&&t.delete(e)}},i="transitionend",n=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),s=t=>{t.dispatchEvent(new Event(i))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(n(t)):null,a=t=>{if(!o(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},l=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),c=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?c(t.parentNode):null},h=()=>{},d=t=>{t.offsetHeight},u=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,f=[],p=()=>"rtl"===document.documentElement.dir,m=t=>{var e;e=()=>{const e=u();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(f.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of f)t()})),f.push(e)):e()},g=(t,e=[],i=t)=>"function"==typeof t?t(...e):i,_=(t,e,n=!0)=>{if(!n)return void g(t);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let r=!1;const a=({target:n})=>{n===e&&(r=!0,e.removeEventListener(i,a),g(t))};e.addEventListener(i,a),setTimeout((()=>{r||s(e)}),o)},b=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},v=/[^.]*(?=\..*)\.|.*/,y=/\..*/,w=/::\d+$/,A={};let E=1;const T={mouseenter:"mouseover",mouseleave:"mouseout"},C=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${E++}`||t.uidEvent||E++}function x(t){const e=O(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function k(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function L(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=I(t);return C.has(o)||(o=t),[n,s,o]}function S(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=L(e,i,n);if(e in T){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=x(t),c=l[a]||(l[a]={}),h=k(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=O(r,e.replace(v,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return P(s,{delegateTarget:r}),n.oneOff&&N.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return P(n,{delegateTarget:t}),i.oneOff&&N.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function D(t,e,i,n,s){const o=k(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function $(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&D(t,e,i,r.callable,r.delegationSelector)}function I(t){return t=t.replace(y,""),T[t]||t}const N={on(t,e,i,n){S(t,e,i,n,!1)},one(t,e,i,n){S(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=L(e,i,n),a=r!==e,l=x(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))$(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(w,"");a&&!e.includes(s)||D(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;D(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=u();let s=null,o=!0,r=!0,a=!1;e!==I(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());const l=P(new Event(e,{bubbles:o,cancelable:!0}),i);return a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function P(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}function M(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function j(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const F={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${j(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${j(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=M(t.dataset[n])}return e},getDataAttribute:(t,e)=>M(t.getAttribute(`data-bs-${j(e)}`))};class H{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=o(e)?F.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...o(e)?F.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[n,s]of Object.entries(e)){const e=t[n],r=o(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(r))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${r}" but expected type "${s}".`)}var i}}class W extends H{constructor(t,i){super(),(t=r(t))&&(this._element=t,this._config=this._getConfig(i),e.set(this._element,this.constructor.DATA_KEY,this))}dispose(){e.remove(this._element,this.constructor.DATA_KEY),N.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){_(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return e.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.1"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const B=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return n(e)},z={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!l(t)&&a(t)))},getSelectorFromElement(t){const e=B(t);return e&&z.findOne(e)?e:null},getElementFromSelector(t){const e=B(t);return e?z.findOne(e):null},getMultipleElementsFromSelector(t){const e=B(t);return e?z.find(e):[]}},R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;N.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),l(this))return;const s=z.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))},q=".bs.alert",V=`close${q}`,K=`closed${q}`;class Q extends W{static get NAME(){return"alert"}close(){if(N.trigger(this._element,V).defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),N.trigger(this._element,K),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(Q,"close"),m(Q);const X='[data-bs-toggle="button"]';class Y extends W{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=Y.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}N.on(document,"click.bs.button.data-api",X,(t=>{t.preventDefault();const e=t.target.closest(X);Y.getOrCreateInstance(e).toggle()})),m(Y);const U=".bs.swipe",G=`touchstart${U}`,J=`touchmove${U}`,Z=`touchend${U}`,tt=`pointerdown${U}`,et=`pointerup${U}`,it={endCallback:null,leftCallback:null,rightCallback:null},nt={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class st extends H{constructor(t,e){super(),this._element=t,t&&st.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return it}static get DefaultType(){return nt}static get NAME(){return"swipe"}dispose(){N.off(this._element,U)}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),g(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&g(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(N.on(this._element,tt,(t=>this._start(t))),N.on(this._element,et,(t=>this._end(t))),this._element.classList.add("pointer-event")):(N.on(this._element,G,(t=>this._start(t))),N.on(this._element,J,(t=>this._move(t))),N.on(this._element,Z,(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const ot=".bs.carousel",rt=".data-api",at="next",lt="prev",ct="left",ht="right",dt=`slide${ot}`,ut=`slid${ot}`,ft=`keydown${ot}`,pt=`mouseenter${ot}`,mt=`mouseleave${ot}`,gt=`dragstart${ot}`,_t=`load${ot}${rt}`,bt=`click${ot}${rt}`,vt="carousel",yt="active",wt=".active",At=".carousel-item",Et=wt+At,Tt={ArrowLeft:ht,ArrowRight:ct},Ct={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},Ot={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class xt extends W{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=z.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===vt&&this.cycle()}static get Default(){return Ct}static get DefaultType(){return Ot}static get NAME(){return"carousel"}next(){this._slide(at)}nextWhenVisible(){!document.hidden&&a(this._element)&&this.next()}prev(){this._slide(lt)}pause(){this._isSliding&&s(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?N.one(this._element,ut,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void N.one(this._element,ut,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?at:lt;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&N.on(this._element,ft,(t=>this._keydown(t))),"hover"===this._config.pause&&(N.on(this._element,pt,(()=>this.pause())),N.on(this._element,mt,(()=>this._maybeEnableCycle()))),this._config.touch&&st.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of z.find(".carousel-item img",this._element))N.on(t,gt,(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(ct)),rightCallback:()=>this._slide(this._directionToOrder(ht)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new st(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=Tt[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=z.findOne(wt,this._indicatorsElement);e.classList.remove(yt),e.removeAttribute("aria-current");const i=z.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(yt),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===at,s=e||b(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>N.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r(dt).defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),d(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(yt),i.classList.remove(yt,c,l),this._isSliding=!1,r(ut)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return z.findOne(Et,this._element)}_getItems(){return z.find(At,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return p()?t===ct?lt:at:t===ct?at:lt}_orderToDirection(t){return p()?t===lt?ct:ht:t===lt?ht:ct}static jQueryInterface(t){return this.each((function(){const e=xt.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}N.on(document,bt,"[data-bs-slide], [data-bs-slide-to]",(function(t){const e=z.getElementFromSelector(this);if(!e||!e.classList.contains(vt))return;t.preventDefault();const i=xt.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===F.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),N.on(window,_t,(()=>{const t=z.find('[data-bs-ride="carousel"]');for(const e of t)xt.getOrCreateInstance(e)})),m(xt);const kt=".bs.collapse",Lt=`show${kt}`,St=`shown${kt}`,Dt=`hide${kt}`,$t=`hidden${kt}`,It=`click${kt}.data-api`,Nt="show",Pt="collapse",Mt="collapsing",jt=`:scope .${Pt} .${Pt}`,Ft='[data-bs-toggle="collapse"]',Ht={parent:null,toggle:!0},Wt={parent:"(null|element)",toggle:"boolean"};class Bt extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=z.find(Ft);for(const t of i){const e=z.getSelectorFromElement(t),i=z.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return Ht}static get DefaultType(){return Wt}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>Bt.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(N.trigger(this._element,Lt).defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(Pt),this._element.classList.add(Mt),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Mt),this._element.classList.add(Pt,Nt),this._element.style[e]="",N.trigger(this._element,St)}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(N.trigger(this._element,Dt).defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,d(this._element),this._element.classList.add(Mt),this._element.classList.remove(Pt,Nt);for(const t of this._triggerArray){const e=z.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Mt),this._element.classList.add(Pt),N.trigger(this._element,$t)}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(Nt)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=r(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(Ft);for(const e of t){const t=z.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=z.find(jt,this._config.parent);return z.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=Bt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}N.on(document,It,Ft,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of z.getMultipleElementsFromSelector(this))Bt.getOrCreateInstance(t,{toggle:!1}).toggle()})),m(Bt);var zt="top",Rt="bottom",qt="right",Vt="left",Kt="auto",Qt=[zt,Rt,qt,Vt],Xt="start",Yt="end",Ut="clippingParents",Gt="viewport",Jt="popper",Zt="reference",te=Qt.reduce((function(t,e){return t.concat([e+"-"+Xt,e+"-"+Yt])}),[]),ee=[].concat(Qt,[Kt]).reduce((function(t,e){return t.concat([e,e+"-"+Xt,e+"-"+Yt])}),[]),ie="beforeRead",ne="read",se="afterRead",oe="beforeMain",re="main",ae="afterMain",le="beforeWrite",ce="write",he="afterWrite",de=[ie,ne,se,oe,re,ae,le,ce,he];function ue(t){return t?(t.nodeName||"").toLowerCase():null}function fe(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function pe(t){return t instanceof fe(t).Element||t instanceof Element}function me(t){return t instanceof fe(t).HTMLElement||t instanceof HTMLElement}function ge(t){return"undefined"!=typeof ShadowRoot&&(t instanceof fe(t).ShadowRoot||t instanceof ShadowRoot)}const _e={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];me(s)&&ue(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});me(n)&&ue(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function be(t){return t.split("-")[0]}var ve=Math.max,ye=Math.min,we=Math.round;function Ae(){var t=navigator.userAgentData;return null!=t&&t.brands&&Array.isArray(t.brands)?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function Ee(){return!/^((?!chrome|android).)*safari/i.test(Ae())}function Te(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&me(t)&&(s=t.offsetWidth>0&&we(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&we(n.height)/t.offsetHeight||1);var r=(pe(t)?fe(t):window).visualViewport,a=!Ee()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function Ce(t){var e=Te(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Oe(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&ge(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function xe(t){return fe(t).getComputedStyle(t)}function ke(t){return["table","td","th"].indexOf(ue(t))>=0}function Le(t){return((pe(t)?t.ownerDocument:t.document)||window.document).documentElement}function Se(t){return"html"===ue(t)?t:t.assignedSlot||t.parentNode||(ge(t)?t.host:null)||Le(t)}function De(t){return me(t)&&"fixed"!==xe(t).position?t.offsetParent:null}function $e(t){for(var e=fe(t),i=De(t);i&&ke(i)&&"static"===xe(i).position;)i=De(i);return i&&("html"===ue(i)||"body"===ue(i)&&"static"===xe(i).position)?e:i||function(t){var e=/firefox/i.test(Ae());if(/Trident/i.test(Ae())&&me(t)&&"fixed"===xe(t).position)return null;var i=Se(t);for(ge(i)&&(i=i.host);me(i)&&["html","body"].indexOf(ue(i))<0;){var n=xe(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function Ie(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function Ne(t,e,i){return ve(t,ye(e,i))}function Pe(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function Me(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const je={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=be(i.placement),l=Ie(a),c=[Vt,qt].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return Pe("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:Me(t,Qt))}(s.padding,i),d=Ce(o),u="y"===l?zt:Vt,f="y"===l?Rt:qt,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=$e(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,A=Ne(v,w,y),E=l;i.modifiersData[n]=((e={})[E]=A,e.centerOffset=A-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Oe(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function Fe(t){return t.split("-")[1]}var He={top:"auto",right:"auto",bottom:"auto",left:"auto"};function We(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=t.isFixed,u=r.x,f=void 0===u?0:u,p=r.y,m=void 0===p?0:p,g="function"==typeof h?h({x:f,y:m}):{x:f,y:m};f=g.x,m=g.y;var _=r.hasOwnProperty("x"),b=r.hasOwnProperty("y"),v=Vt,y=zt,w=window;if(c){var A=$e(i),E="clientHeight",T="clientWidth";A===fe(i)&&"static"!==xe(A=Le(i)).position&&"absolute"===a&&(E="scrollHeight",T="scrollWidth"),(s===zt||(s===Vt||s===qt)&&o===Yt)&&(y=Rt,m-=(d&&A===w&&w.visualViewport?w.visualViewport.height:A[E])-n.height,m*=l?1:-1),s!==Vt&&(s!==zt&&s!==Rt||o!==Yt)||(v=qt,f-=(d&&A===w&&w.visualViewport?w.visualViewport.width:A[T])-n.width,f*=l?1:-1)}var C,O=Object.assign({position:a},c&&He),x=!0===h?function(t,e){var i=t.x,n=t.y,s=e.devicePixelRatio||1;return{x:we(i*s)/s||0,y:we(n*s)/s||0}}({x:f,y:m},fe(i)):{x:f,y:m};return f=x.x,m=x.y,l?Object.assign({},O,((C={})[y]=b?"0":"",C[v]=_?"0":"",C.transform=(w.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",C)):Object.assign({},O,((e={})[y]=b?m+"px":"",e[v]=_?f+"px":"",e.transform="",e))}const Be={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:be(e.placement),variation:Fe(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,We(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,We(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var ze={passive:!0};const Re={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=fe(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,ze)})),a&&l.addEventListener("resize",i.update,ze),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,ze)})),a&&l.removeEventListener("resize",i.update,ze)}},data:{}};var qe={left:"right",right:"left",bottom:"top",top:"bottom"};function Ve(t){return t.replace(/left|right|bottom|top/g,(function(t){return qe[t]}))}var Ke={start:"end",end:"start"};function Qe(t){return t.replace(/start|end/g,(function(t){return Ke[t]}))}function Xe(t){var e=fe(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function Ye(t){return Te(Le(t)).left+Xe(t).scrollLeft}function Ue(t){var e=xe(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ge(t){return["html","body","#document"].indexOf(ue(t))>=0?t.ownerDocument.body:me(t)&&Ue(t)?t:Ge(Se(t))}function Je(t,e){var i;void 0===e&&(e=[]);var n=Ge(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=fe(n),r=s?[o].concat(o.visualViewport||[],Ue(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Je(Se(r)))}function Ze(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function ti(t,e,i){return e===Gt?Ze(function(t,e){var i=fe(t),n=Le(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=Ee();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+Ye(t),y:l}}(t,i)):pe(e)?function(t,e){var i=Te(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):Ze(function(t){var e,i=Le(t),n=Xe(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=ve(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=ve(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+Ye(t),l=-n.scrollTop;return"rtl"===xe(s||i).direction&&(a+=ve(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(Le(t)))}function ei(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?be(s):null,r=s?Fe(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case zt:e={x:a,y:i.y-n.height};break;case Rt:e={x:a,y:i.y+i.height};break;case qt:e={x:i.x+i.width,y:l};break;case Vt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?Ie(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case Xt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Yt:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function ii(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.strategy,r=void 0===o?t.strategy:o,a=i.boundary,l=void 0===a?Ut:a,c=i.rootBoundary,h=void 0===c?Gt:c,d=i.elementContext,u=void 0===d?Jt:d,f=i.altBoundary,p=void 0!==f&&f,m=i.padding,g=void 0===m?0:m,_=Pe("number"!=typeof g?g:Me(g,Qt)),b=u===Jt?Zt:Jt,v=t.rects.popper,y=t.elements[p?b:u],w=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=Je(Se(t)),i=["absolute","fixed"].indexOf(xe(t).position)>=0&&me(t)?$e(t):t;return pe(i)?e.filter((function(t){return pe(t)&&Oe(t,i)&&"body"!==ue(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=ti(t,i,n);return e.top=ve(s.top,e.top),e.right=ye(s.right,e.right),e.bottom=ye(s.bottom,e.bottom),e.left=ve(s.left,e.left),e}),ti(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(pe(y)?y:y.contextElement||Le(t.elements.popper),l,h,r),A=Te(t.elements.reference),E=ei({reference:A,element:v,strategy:"absolute",placement:s}),T=Ze(Object.assign({},v,E)),C=u===Jt?T:A,O={top:w.top-C.top+_.top,bottom:C.bottom-w.bottom+_.bottom,left:w.left-C.left+_.left,right:C.right-w.right+_.right},x=t.modifiersData.offset;if(u===Jt&&x){var k=x[s];Object.keys(O).forEach((function(t){var e=[qt,Rt].indexOf(t)>=0?1:-1,i=[zt,Rt].indexOf(t)>=0?"y":"x";O[t]+=k[i]*e}))}return O}function ni(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?ee:l,h=Fe(n),d=h?a?te:te.filter((function(t){return Fe(t)===h})):Qt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=ii(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[be(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const si={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=be(g),b=l||(_!==g&&p?function(t){if(be(t)===Kt)return[];var e=Ve(t);return[Qe(t),e,Qe(e)]}(g):[Ve(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(be(i)===Kt?ni(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,A=new Map,E=!0,T=v[0],C=0;C=0,S=L?"width":"height",D=ii(e,{placement:O,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),$=L?k?qt:Vt:k?Rt:zt;y[S]>w[S]&&($=Ve($));var I=Ve($),N=[];if(o&&N.push(D[x]<=0),a&&N.push(D[$]<=0,D[I]<=0),N.every((function(t){return t}))){T=O,E=!1;break}A.set(O,N)}if(E)for(var P=function(t){var e=v.find((function(e){var i=A.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==P(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function oi(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function ri(t){return[zt,qt,Rt,Vt].some((function(e){return t[e]>=0}))}const ai={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=ii(e,{elementContext:"reference"}),a=ii(e,{altBoundary:!0}),l=oi(r,n),c=oi(a,s,o),h=ri(l),d=ri(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},li={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=ee.reduce((function(t,i){return t[i]=function(t,e,i){var n=be(t),s=[Vt,zt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[Vt,qt].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},ci={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=ei({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},hi={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=ii(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=be(e.placement),b=Fe(e.placement),v=!b,y=Ie(_),w="x"===y?"y":"x",A=e.modifiersData.popperOffsets,E=e.rects.reference,T=e.rects.popper,C="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,O="number"==typeof C?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),x=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,k={x:0,y:0};if(A){if(o){var L,S="y"===y?zt:Vt,D="y"===y?Rt:qt,$="y"===y?"height":"width",I=A[y],N=I+g[S],P=I-g[D],M=f?-T[$]/2:0,j=b===Xt?E[$]:T[$],F=b===Xt?-T[$]:-E[$],H=e.elements.arrow,W=f&&H?Ce(H):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},z=B[S],R=B[D],q=Ne(0,E[$],W[$]),V=v?E[$]/2-M-q-z-O.mainAxis:j-q-z-O.mainAxis,K=v?-E[$]/2+M+q+R+O.mainAxis:F+q+R+O.mainAxis,Q=e.elements.arrow&&$e(e.elements.arrow),X=Q?"y"===y?Q.clientTop||0:Q.clientLeft||0:0,Y=null!=(L=null==x?void 0:x[y])?L:0,U=I+K-Y,G=Ne(f?ye(N,I+V-Y-X):N,I,f?ve(P,U):P);A[y]=G,k[y]=G-I}if(a){var J,Z="x"===y?zt:Vt,tt="x"===y?Rt:qt,et=A[w],it="y"===w?"height":"width",nt=et+g[Z],st=et-g[tt],ot=-1!==[zt,Vt].indexOf(_),rt=null!=(J=null==x?void 0:x[w])?J:0,at=ot?nt:et-E[it]-T[it]-rt+O.altAxis,lt=ot?et+E[it]+T[it]-rt-O.altAxis:st,ct=f&&ot?function(t,e,i){var n=Ne(t,e,i);return n>i?i:n}(at,et,lt):Ne(f?at:nt,et,f?lt:st);A[w]=ct,k[w]=ct-et}e.modifiersData[n]=k}},requiresIfExists:["offset"]};function di(t,e,i){void 0===i&&(i=!1);var n,s,o=me(e),r=me(e)&&function(t){var e=t.getBoundingClientRect(),i=we(e.width)/t.offsetWidth||1,n=we(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=Le(e),l=Te(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==ue(e)||Ue(a))&&(c=(n=e)!==fe(n)&&me(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:Xe(n)),me(e)?((h=Te(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=Ye(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function ui(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var fi={placement:"bottom",modifiers:[],strategy:"absolute"};function pi(){for(var t=arguments.length,e=new Array(t),i=0;iNumber.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(F.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...g(this._config.popperConfig,[t])}}_selectMenuItem({key:t,target:e}){const i=z.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>a(t)));i.length&&b(i,e,t===Ti,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=qi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=z.find(Ni);for(const i of e){const e=qi.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Ei,Ti].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Ii)?this:z.prev(this,Ii)[0]||z.next(this,Ii)[0]||z.findOne(Ii,t.delegateTarget.parentNode),o=qi.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}N.on(document,Si,Ii,qi.dataApiKeydownHandler),N.on(document,Si,Pi,qi.dataApiKeydownHandler),N.on(document,Li,qi.clearMenus),N.on(document,Di,qi.clearMenus),N.on(document,Li,Ii,(function(t){t.preventDefault(),qi.getOrCreateInstance(this).toggle()})),m(qi);const Vi="backdrop",Ki="show",Qi=`mousedown.bs.${Vi}`,Xi={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Yi={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class Ui extends H{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return Xi}static get DefaultType(){return Yi}static get NAME(){return Vi}show(t){if(!this._config.isVisible)return void g(t);this._append();const e=this._getElement();this._config.isAnimated&&d(e),e.classList.add(Ki),this._emulateAnimation((()=>{g(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(Ki),this._emulateAnimation((()=>{this.dispose(),g(t)}))):g(t)}dispose(){this._isAppended&&(N.off(this._element,Qi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=r(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),N.on(t,Qi,(()=>{g(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){_(t,this._getElement(),this._config.isAnimated)}}const Gi=".bs.focustrap",Ji=`focusin${Gi}`,Zi=`keydown.tab${Gi}`,tn="backward",en={autofocus:!0,trapElement:null},nn={autofocus:"boolean",trapElement:"element"};class sn extends H{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return en}static get DefaultType(){return nn}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),N.off(document,Gi),N.on(document,Ji,(t=>this._handleFocusin(t))),N.on(document,Zi,(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,N.off(document,Gi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=z.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===tn?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?tn:"forward")}}const on=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",rn=".sticky-top",an="padding-right",ln="margin-right";class cn{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,an,(e=>e+t)),this._setElementAttributes(on,an,(e=>e+t)),this._setElementAttributes(rn,ln,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,an),this._resetElementAttributes(on,an),this._resetElementAttributes(rn,ln)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&F.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=F.getDataAttribute(t,e);null!==i?(F.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(o(t))e(t);else for(const i of z.find(t,this._element))e(i)}}const hn=".bs.modal",dn=`hide${hn}`,un=`hidePrevented${hn}`,fn=`hidden${hn}`,pn=`show${hn}`,mn=`shown${hn}`,gn=`resize${hn}`,_n=`click.dismiss${hn}`,bn=`mousedown.dismiss${hn}`,vn=`keydown.dismiss${hn}`,yn=`click${hn}.data-api`,wn="modal-open",An="show",En="modal-static",Tn={backdrop:!0,focus:!0,keyboard:!0},Cn={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class On extends W{constructor(t,e){super(t,e),this._dialog=z.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new cn,this._addEventListeners()}static get Default(){return Tn}static get DefaultType(){return Cn}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||N.trigger(this._element,pn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(wn),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(N.trigger(this._element,dn).defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(An),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){N.off(window,hn),N.off(this._dialog,hn),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Ui({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new sn({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=z.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),d(this._element),this._element.classList.add(An),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,N.trigger(this._element,mn,{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){N.on(this._element,vn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),N.on(window,gn,(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),N.on(this._element,bn,(t=>{N.one(this._element,_n,(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(wn),this._resetAdjustments(),this._scrollBar.reset(),N.trigger(this._element,fn)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(N.trigger(this._element,un).defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(En)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(En),this._queueCallback((()=>{this._element.classList.remove(En),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=p()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=p()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=On.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}N.on(document,yn,'[data-bs-toggle="modal"]',(function(t){const e=z.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),N.one(e,pn,(t=>{t.defaultPrevented||N.one(e,fn,(()=>{a(this)&&this.focus()}))}));const i=z.findOne(".modal.show");i&&On.getInstance(i).hide(),On.getOrCreateInstance(e).toggle(this)})),R(On),m(On);const xn=".bs.offcanvas",kn=".data-api",Ln=`load${xn}${kn}`,Sn="show",Dn="showing",$n="hiding",In=".offcanvas.show",Nn=`show${xn}`,Pn=`shown${xn}`,Mn=`hide${xn}`,jn=`hidePrevented${xn}`,Fn=`hidden${xn}`,Hn=`resize${xn}`,Wn=`click${xn}${kn}`,Bn=`keydown.dismiss${xn}`,zn={backdrop:!0,keyboard:!0,scroll:!1},Rn={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class qn extends W{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return zn}static get DefaultType(){return Rn}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||N.trigger(this._element,Nn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new cn).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(Dn),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(Sn),this._element.classList.remove(Dn),N.trigger(this._element,Pn,{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(N.trigger(this._element,Mn).defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add($n),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(Sn,$n),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new cn).reset(),N.trigger(this._element,Fn)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new Ui({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():N.trigger(this._element,jn)}:null})}_initializeFocusTrap(){return new sn({trapElement:this._element})}_addEventListeners(){N.on(this._element,Bn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():N.trigger(this._element,jn))}))}static jQueryInterface(t){return this.each((function(){const e=qn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}N.on(document,Wn,'[data-bs-toggle="offcanvas"]',(function(t){const e=z.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this))return;N.one(e,Fn,(()=>{a(this)&&this.focus()}));const i=z.findOne(In);i&&i!==e&&qn.getInstance(i).hide(),qn.getOrCreateInstance(e).toggle(this)})),N.on(window,Ln,(()=>{for(const t of z.find(In))qn.getOrCreateInstance(t).show()})),N.on(window,Hn,(()=>{for(const t of z.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&qn.getOrCreateInstance(t).hide()})),R(qn),m(qn);const Vn={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Kn=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Qn=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,Xn=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!Kn.has(i)||Boolean(Qn.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Yn={allowList:Vn,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Un={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Gn={entry:"(string|element|function|null)",selector:"(string|element)"};class Jn extends H{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Yn}static get DefaultType(){return Un}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Gn)}_setContent(t,e,i){const n=z.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?o(e)?this._putElementInTemplate(r(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Xn(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return g(t,[this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const Zn=new Set(["sanitize","allowList","sanitizeFn"]),ts="fade",es="show",is=".modal",ns="hide.bs.modal",ss="hover",os="focus",rs={AUTO:"auto",TOP:"top",RIGHT:p()?"left":"right",BOTTOM:"bottom",LEFT:p()?"right":"left"},as={allowList:Vn,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},ls={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class cs extends W{constructor(t,e){if(void 0===vi)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return as}static get DefaultType(){return ls}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),N.off(this._element.closest(is),ns,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=N.trigger(this._element,this.constructor.eventName("show")),e=(c(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),N.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(es),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.on(t,"mouseover",h);this._queueCallback((()=>{N.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!N.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(es),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.off(t,"mouseover",h);this._activeTrigger.click=!1,this._activeTrigger[os]=!1,this._activeTrigger[ss]=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),N.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(ts,es),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(ts),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Jn({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(ts)}_isShown(){return this.tip&&this.tip.classList.contains(es)}_createPopper(t){const e=g(this._config.placement,[this,t,this._element]),i=rs[e.toUpperCase()];return bi(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return g(t,[this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...g(this._config.popperConfig,[e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)N.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===ss?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===ss?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");N.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?os:ss]=!0,e._enter()})),N.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?os:ss]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},N.on(this._element.closest(is),ns,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=F.getDataAttributes(this._element);for(const t of Object.keys(e))Zn.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=cs.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(cs);const hs={...cs.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},ds={...cs.DefaultType,content:"(null|string|element|function)"};class us extends cs{static get Default(){return hs}static get DefaultType(){return ds}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=us.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(us);const fs=".bs.scrollspy",ps=`activate${fs}`,ms=`click${fs}`,gs=`load${fs}.data-api`,_s="active",bs="[href]",vs=".nav-link",ys=`${vs}, .nav-item > ${vs}, .list-group-item`,ws={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},As={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class Es extends W{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return ws}static get DefaultType(){return As}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=r(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(N.off(this._config.target,ms),N.on(this._config.target,ms,bs,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=z.find(bs,this._config.target);for(const e of t){if(!e.hash||l(e))continue;const t=z.findOne(decodeURI(e.hash),this._element);a(t)&&(this._targetLinks.set(decodeURI(e.hash),e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(_s),this._activateParents(t),N.trigger(this._element,ps,{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))z.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(_s);else for(const e of z.parents(t,".nav, .list-group"))for(const t of z.prev(e,ys))t.classList.add(_s)}_clearActiveClass(t){t.classList.remove(_s);const e=z.find(`${bs}.${_s}`,t);for(const t of e)t.classList.remove(_s)}static jQueryInterface(t){return this.each((function(){const e=Es.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(window,gs,(()=>{for(const t of z.find('[data-bs-spy="scroll"]'))Es.getOrCreateInstance(t)})),m(Es);const Ts=".bs.tab",Cs=`hide${Ts}`,Os=`hidden${Ts}`,xs=`show${Ts}`,ks=`shown${Ts}`,Ls=`click${Ts}`,Ss=`keydown${Ts}`,Ds=`load${Ts}`,$s="ArrowLeft",Is="ArrowRight",Ns="ArrowUp",Ps="ArrowDown",Ms="Home",js="End",Fs="active",Hs="fade",Ws="show",Bs=":not(.dropdown-toggle)",zs='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Rs=`.nav-link${Bs}, .list-group-item${Bs}, [role="tab"]${Bs}, ${zs}`,qs=`.${Fs}[data-bs-toggle="tab"], .${Fs}[data-bs-toggle="pill"], .${Fs}[data-bs-toggle="list"]`;class Vs extends W{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),N.on(this._element,Ss,(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?N.trigger(e,Cs,{relatedTarget:t}):null;N.trigger(t,xs,{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Fs),this._activate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),N.trigger(t,ks,{relatedTarget:e})):t.classList.add(Ws)}),t,t.classList.contains(Hs)))}_deactivate(t,e){t&&(t.classList.remove(Fs),t.blur(),this._deactivate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),N.trigger(t,Os,{relatedTarget:e})):t.classList.remove(Ws)}),t,t.classList.contains(Hs)))}_keydown(t){if(![$s,Is,Ns,Ps,Ms,js].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=this._getChildren().filter((t=>!l(t)));let i;if([Ms,js].includes(t.key))i=e[t.key===Ms?0:e.length-1];else{const n=[Is,Ps].includes(t.key);i=b(e,t.target,n,!0)}i&&(i.focus({preventScroll:!0}),Vs.getOrCreateInstance(i).show())}_getChildren(){return z.find(Rs,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=z.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=z.findOne(t,i);s&&s.classList.toggle(n,e)};n(".dropdown-toggle",Fs),n(".dropdown-menu",Ws),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(Fs)}_getInnerElement(t){return t.matches(Rs)?t:z.findOne(Rs,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Vs.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(document,Ls,zs,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this)||Vs.getOrCreateInstance(this).show()})),N.on(window,Ds,(()=>{for(const t of z.find(qs))Vs.getOrCreateInstance(t)})),m(Vs);const Ks=".bs.toast",Qs=`mouseover${Ks}`,Xs=`mouseout${Ks}`,Ys=`focusin${Ks}`,Us=`focusout${Ks}`,Gs=`hide${Ks}`,Js=`hidden${Ks}`,Zs=`show${Ks}`,to=`shown${Ks}`,eo="hide",io="show",no="showing",so={animation:"boolean",autohide:"boolean",delay:"number"},oo={animation:!0,autohide:!0,delay:5e3};class ro extends W{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return oo}static get DefaultType(){return so}static get NAME(){return"toast"}show(){N.trigger(this._element,Zs).defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(eo),d(this._element),this._element.classList.add(io,no),this._queueCallback((()=>{this._element.classList.remove(no),N.trigger(this._element,to),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(N.trigger(this._element,Gs).defaultPrevented||(this._element.classList.add(no),this._queueCallback((()=>{this._element.classList.add(eo),this._element.classList.remove(no,io),N.trigger(this._element,Js)}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(io),super.dispose()}isShown(){return this._element.classList.contains(io)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){N.on(this._element,Qs,(t=>this._onInteraction(t,!0))),N.on(this._element,Xs,(t=>this._onInteraction(t,!1))),N.on(this._element,Ys,(t=>this._onInteraction(t,!0))),N.on(this._element,Us,(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=ro.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(ro),m(ro),{Alert:Q,Button:Y,Carousel:xt,Collapse:Bt,Dropdown:qi,Modal:On,Offcanvas:qn,Popover:us,ScrollSpy:Es,Tab:Vs,Toast:ro,Tooltip:cs}}));
+//# sourceMappingURL=bootstrap.bundle.min.js.map
\ No newline at end of file
diff --git a/1 PA Decline/article ready_files/libs/clipboard/clipboard.min.js b/1 PA Decline/article ready_files/libs/clipboard/clipboard.min.js
new file mode 100644
index 0000000..1103f81
--- /dev/null
+++ b/1 PA Decline/article ready_files/libs/clipboard/clipboard.min.js
@@ -0,0 +1,7 @@
+/*!
+ * clipboard.js v2.0.11
+ * https://clipboardjs.com/
+ *
+ * Licensed MIT © Zeno Rocha
+ */
+!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return b}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),r=n.n(e);function c(t){try{return document.execCommand(t)}catch(t){return}}var a=function(t){t=r()(t);return c("cut"),t};function o(t,e){var n,o,t=(n=t,o="rtl"===document.documentElement.getAttribute("dir"),(t=document.createElement("textarea")).style.fontSize="12pt",t.style.border="0",t.style.padding="0",t.style.margin="0",t.style.position="absolute",t.style[o?"right":"left"]="-9999px",o=window.pageYOffset||document.documentElement.scrollTop,t.style.top="".concat(o,"px"),t.setAttribute("readonly",""),t.value=n,t);return e.container.appendChild(t),e=r()(t),c("copy"),t.remove(),e}var f=function(t){var e=1.anchorjs-link,.anchorjs-link:focus{opacity:1}",A.sheet.cssRules.length),A.sheet.insertRule("[data-anchorjs-icon]::after{content:attr(data-anchorjs-icon)}",A.sheet.cssRules.length),A.sheet.insertRule('@font-face{font-family:anchorjs-icons;src:url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype")}',A.sheet.cssRules.length)),h=document.querySelectorAll("[id]"),t=[].map.call(h,function(A){return A.id}),i=0;i\]./()*\\\n\t\b\v\u00A0]/g,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(A){var e=A.firstChild&&-1<(" "+A.firstChild.className+" ").indexOf(" anchorjs-link "),A=A.lastChild&&-1<(" "+A.lastChild.className+" ").indexOf(" anchorjs-link ");return e||A||!1}}});
+// @license-end
\ No newline at end of file
diff --git a/1 PA Decline/article ready_files/libs/quarto-html/popper.min.js b/1 PA Decline/article ready_files/libs/quarto-html/popper.min.js
new file mode 100644
index 0000000..e3726d7
--- /dev/null
+++ b/1 PA Decline/article ready_files/libs/quarto-html/popper.min.js
@@ -0,0 +1,6 @@
+/**
+ * @popperjs/core v2.11.7 - MIT License
+ */
+
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Popper={})}(this,(function(e){"use strict";function t(e){if(null==e)return window;if("[object Window]"!==e.toString()){var t=e.ownerDocument;return t&&t.defaultView||window}return e}function n(e){return e instanceof t(e).Element||e instanceof Element}function r(e){return e instanceof t(e).HTMLElement||e instanceof HTMLElement}function o(e){return"undefined"!=typeof ShadowRoot&&(e instanceof t(e).ShadowRoot||e instanceof ShadowRoot)}var i=Math.max,a=Math.min,s=Math.round;function f(){var e=navigator.userAgentData;return null!=e&&e.brands&&Array.isArray(e.brands)?e.brands.map((function(e){return e.brand+"/"+e.version})).join(" "):navigator.userAgent}function c(){return!/^((?!chrome|android).)*safari/i.test(f())}function p(e,o,i){void 0===o&&(o=!1),void 0===i&&(i=!1);var a=e.getBoundingClientRect(),f=1,p=1;o&&r(e)&&(f=e.offsetWidth>0&&s(a.width)/e.offsetWidth||1,p=e.offsetHeight>0&&s(a.height)/e.offsetHeight||1);var u=(n(e)?t(e):window).visualViewport,l=!c()&&i,d=(a.left+(l&&u?u.offsetLeft:0))/f,h=(a.top+(l&&u?u.offsetTop:0))/p,m=a.width/f,v=a.height/p;return{width:m,height:v,top:h,right:d+m,bottom:h+v,left:d,x:d,y:h}}function u(e){var n=t(e);return{scrollLeft:n.pageXOffset,scrollTop:n.pageYOffset}}function l(e){return e?(e.nodeName||"").toLowerCase():null}function d(e){return((n(e)?e.ownerDocument:e.document)||window.document).documentElement}function h(e){return p(d(e)).left+u(e).scrollLeft}function m(e){return t(e).getComputedStyle(e)}function v(e){var t=m(e),n=t.overflow,r=t.overflowX,o=t.overflowY;return/auto|scroll|overlay|hidden/.test(n+o+r)}function y(e,n,o){void 0===o&&(o=!1);var i,a,f=r(n),c=r(n)&&function(e){var t=e.getBoundingClientRect(),n=s(t.width)/e.offsetWidth||1,r=s(t.height)/e.offsetHeight||1;return 1!==n||1!==r}(n),m=d(n),y=p(e,c,o),g={scrollLeft:0,scrollTop:0},b={x:0,y:0};return(f||!f&&!o)&&(("body"!==l(n)||v(m))&&(g=(i=n)!==t(i)&&r(i)?{scrollLeft:(a=i).scrollLeft,scrollTop:a.scrollTop}:u(i)),r(n)?((b=p(n,!0)).x+=n.clientLeft,b.y+=n.clientTop):m&&(b.x=h(m))),{x:y.left+g.scrollLeft-b.x,y:y.top+g.scrollTop-b.y,width:y.width,height:y.height}}function g(e){var t=p(e),n=e.offsetWidth,r=e.offsetHeight;return Math.abs(t.width-n)<=1&&(n=t.width),Math.abs(t.height-r)<=1&&(r=t.height),{x:e.offsetLeft,y:e.offsetTop,width:n,height:r}}function b(e){return"html"===l(e)?e:e.assignedSlot||e.parentNode||(o(e)?e.host:null)||d(e)}function x(e){return["html","body","#document"].indexOf(l(e))>=0?e.ownerDocument.body:r(e)&&v(e)?e:x(b(e))}function w(e,n){var r;void 0===n&&(n=[]);var o=x(e),i=o===(null==(r=e.ownerDocument)?void 0:r.body),a=t(o),s=i?[a].concat(a.visualViewport||[],v(o)?o:[]):o,f=n.concat(s);return i?f:f.concat(w(b(s)))}function O(e){return["table","td","th"].indexOf(l(e))>=0}function j(e){return r(e)&&"fixed"!==m(e).position?e.offsetParent:null}function E(e){for(var n=t(e),i=j(e);i&&O(i)&&"static"===m(i).position;)i=j(i);return i&&("html"===l(i)||"body"===l(i)&&"static"===m(i).position)?n:i||function(e){var t=/firefox/i.test(f());if(/Trident/i.test(f())&&r(e)&&"fixed"===m(e).position)return null;var n=b(e);for(o(n)&&(n=n.host);r(n)&&["html","body"].indexOf(l(n))<0;){var i=m(n);if("none"!==i.transform||"none"!==i.perspective||"paint"===i.contain||-1!==["transform","perspective"].indexOf(i.willChange)||t&&"filter"===i.willChange||t&&i.filter&&"none"!==i.filter)return n;n=n.parentNode}return null}(e)||n}var D="top",A="bottom",L="right",P="left",M="auto",k=[D,A,L,P],W="start",B="end",H="viewport",T="popper",R=k.reduce((function(e,t){return e.concat([t+"-"+W,t+"-"+B])}),[]),S=[].concat(k,[M]).reduce((function(e,t){return e.concat([t,t+"-"+W,t+"-"+B])}),[]),V=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function q(e){var t=new Map,n=new Set,r=[];function o(e){n.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){if(!n.has(e)){var r=t.get(e);r&&o(r)}})),r.push(e)}return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){n.has(e.name)||o(e)})),r}function C(e){return e.split("-")[0]}function N(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&o(n)){var r=t;do{if(r&&e.isSameNode(r))return!0;r=r.parentNode||r.host}while(r)}return!1}function I(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function _(e,r,o){return r===H?I(function(e,n){var r=t(e),o=d(e),i=r.visualViewport,a=o.clientWidth,s=o.clientHeight,f=0,p=0;if(i){a=i.width,s=i.height;var u=c();(u||!u&&"fixed"===n)&&(f=i.offsetLeft,p=i.offsetTop)}return{width:a,height:s,x:f+h(e),y:p}}(e,o)):n(r)?function(e,t){var n=p(e,!1,"fixed"===t);return n.top=n.top+e.clientTop,n.left=n.left+e.clientLeft,n.bottom=n.top+e.clientHeight,n.right=n.left+e.clientWidth,n.width=e.clientWidth,n.height=e.clientHeight,n.x=n.left,n.y=n.top,n}(r,o):I(function(e){var t,n=d(e),r=u(e),o=null==(t=e.ownerDocument)?void 0:t.body,a=i(n.scrollWidth,n.clientWidth,o?o.scrollWidth:0,o?o.clientWidth:0),s=i(n.scrollHeight,n.clientHeight,o?o.scrollHeight:0,o?o.clientHeight:0),f=-r.scrollLeft+h(e),c=-r.scrollTop;return"rtl"===m(o||n).direction&&(f+=i(n.clientWidth,o?o.clientWidth:0)-a),{width:a,height:s,x:f,y:c}}(d(e)))}function F(e,t,o,s){var f="clippingParents"===t?function(e){var t=w(b(e)),o=["absolute","fixed"].indexOf(m(e).position)>=0&&r(e)?E(e):e;return n(o)?t.filter((function(e){return n(e)&&N(e,o)&&"body"!==l(e)})):[]}(e):[].concat(t),c=[].concat(f,[o]),p=c[0],u=c.reduce((function(t,n){var r=_(e,n,s);return t.top=i(r.top,t.top),t.right=a(r.right,t.right),t.bottom=a(r.bottom,t.bottom),t.left=i(r.left,t.left),t}),_(e,p,s));return u.width=u.right-u.left,u.height=u.bottom-u.top,u.x=u.left,u.y=u.top,u}function U(e){return e.split("-")[1]}function z(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}function X(e){var t,n=e.reference,r=e.element,o=e.placement,i=o?C(o):null,a=o?U(o):null,s=n.x+n.width/2-r.width/2,f=n.y+n.height/2-r.height/2;switch(i){case D:t={x:s,y:n.y-r.height};break;case A:t={x:s,y:n.y+n.height};break;case L:t={x:n.x+n.width,y:f};break;case P:t={x:n.x-r.width,y:f};break;default:t={x:n.x,y:n.y}}var c=i?z(i):null;if(null!=c){var p="y"===c?"height":"width";switch(a){case W:t[c]=t[c]-(n[p]/2-r[p]/2);break;case B:t[c]=t[c]+(n[p]/2-r[p]/2)}}return t}function Y(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function G(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function J(e,t){void 0===t&&(t={});var r=t,o=r.placement,i=void 0===o?e.placement:o,a=r.strategy,s=void 0===a?e.strategy:a,f=r.boundary,c=void 0===f?"clippingParents":f,u=r.rootBoundary,l=void 0===u?H:u,h=r.elementContext,m=void 0===h?T:h,v=r.altBoundary,y=void 0!==v&&v,g=r.padding,b=void 0===g?0:g,x=Y("number"!=typeof b?b:G(b,k)),w=m===T?"reference":T,O=e.rects.popper,j=e.elements[y?w:m],E=F(n(j)?j:j.contextElement||d(e.elements.popper),c,l,s),P=p(e.elements.reference),M=X({reference:P,element:O,strategy:"absolute",placement:i}),W=I(Object.assign({},O,M)),B=m===T?W:P,R={top:E.top-B.top+x.top,bottom:B.bottom-E.bottom+x.bottom,left:E.left-B.left+x.left,right:B.right-E.right+x.right},S=e.modifiersData.offset;if(m===T&&S){var V=S[i];Object.keys(R).forEach((function(e){var t=[L,A].indexOf(e)>=0?1:-1,n=[D,A].indexOf(e)>=0?"y":"x";R[e]+=V[n]*t}))}return R}var K={placement:"bottom",modifiers:[],strategy:"absolute"};function Q(){for(var e=arguments.length,t=new Array(e),n=0;n=0?-1:1,i="function"==typeof n?n(Object.assign({},t,{placement:e})):n,a=i[0],s=i[1];return a=a||0,s=(s||0)*o,[P,L].indexOf(r)>=0?{x:s,y:a}:{x:a,y:s}}(n,t.rects,i),e}),{}),s=a[t.placement],f=s.x,c=s.y;null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=f,t.modifiersData.popperOffsets.y+=c),t.modifiersData[r]=a}},se={left:"right",right:"left",bottom:"top",top:"bottom"};function fe(e){return e.replace(/left|right|bottom|top/g,(function(e){return se[e]}))}var ce={start:"end",end:"start"};function pe(e){return e.replace(/start|end/g,(function(e){return ce[e]}))}function ue(e,t){void 0===t&&(t={});var n=t,r=n.placement,o=n.boundary,i=n.rootBoundary,a=n.padding,s=n.flipVariations,f=n.allowedAutoPlacements,c=void 0===f?S:f,p=U(r),u=p?s?R:R.filter((function(e){return U(e)===p})):k,l=u.filter((function(e){return c.indexOf(e)>=0}));0===l.length&&(l=u);var d=l.reduce((function(t,n){return t[n]=J(e,{placement:n,boundary:o,rootBoundary:i,padding:a})[C(n)],t}),{});return Object.keys(d).sort((function(e,t){return d[e]-d[t]}))}var le={name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name;if(!t.modifiersData[r]._skip){for(var o=n.mainAxis,i=void 0===o||o,a=n.altAxis,s=void 0===a||a,f=n.fallbackPlacements,c=n.padding,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.flipVariations,h=void 0===d||d,m=n.allowedAutoPlacements,v=t.options.placement,y=C(v),g=f||(y===v||!h?[fe(v)]:function(e){if(C(e)===M)return[];var t=fe(e);return[pe(e),t,pe(t)]}(v)),b=[v].concat(g).reduce((function(e,n){return e.concat(C(n)===M?ue(t,{placement:n,boundary:p,rootBoundary:u,padding:c,flipVariations:h,allowedAutoPlacements:m}):n)}),[]),x=t.rects.reference,w=t.rects.popper,O=new Map,j=!0,E=b[0],k=0;k=0,S=R?"width":"height",V=J(t,{placement:B,boundary:p,rootBoundary:u,altBoundary:l,padding:c}),q=R?T?L:P:T?A:D;x[S]>w[S]&&(q=fe(q));var N=fe(q),I=[];if(i&&I.push(V[H]<=0),s&&I.push(V[q]<=0,V[N]<=0),I.every((function(e){return e}))){E=B,j=!1;break}O.set(B,I)}if(j)for(var _=function(e){var t=b.find((function(t){var n=O.get(t);if(n)return n.slice(0,e).every((function(e){return e}))}));if(t)return E=t,"break"},F=h?3:1;F>0;F--){if("break"===_(F))break}t.placement!==E&&(t.modifiersData[r]._skip=!0,t.placement=E,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function de(e,t,n){return i(e,a(t,n))}var he={name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name,o=n.mainAxis,s=void 0===o||o,f=n.altAxis,c=void 0!==f&&f,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.padding,h=n.tether,m=void 0===h||h,v=n.tetherOffset,y=void 0===v?0:v,b=J(t,{boundary:p,rootBoundary:u,padding:d,altBoundary:l}),x=C(t.placement),w=U(t.placement),O=!w,j=z(x),M="x"===j?"y":"x",k=t.modifiersData.popperOffsets,B=t.rects.reference,H=t.rects.popper,T="function"==typeof y?y(Object.assign({},t.rects,{placement:t.placement})):y,R="number"==typeof T?{mainAxis:T,altAxis:T}:Object.assign({mainAxis:0,altAxis:0},T),S=t.modifiersData.offset?t.modifiersData.offset[t.placement]:null,V={x:0,y:0};if(k){if(s){var q,N="y"===j?D:P,I="y"===j?A:L,_="y"===j?"height":"width",F=k[j],X=F+b[N],Y=F-b[I],G=m?-H[_]/2:0,K=w===W?B[_]:H[_],Q=w===W?-H[_]:-B[_],Z=t.elements.arrow,$=m&&Z?g(Z):{width:0,height:0},ee=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},te=ee[N],ne=ee[I],re=de(0,B[_],$[_]),oe=O?B[_]/2-G-re-te-R.mainAxis:K-re-te-R.mainAxis,ie=O?-B[_]/2+G+re+ne+R.mainAxis:Q+re+ne+R.mainAxis,ae=t.elements.arrow&&E(t.elements.arrow),se=ae?"y"===j?ae.clientTop||0:ae.clientLeft||0:0,fe=null!=(q=null==S?void 0:S[j])?q:0,ce=F+ie-fe,pe=de(m?a(X,F+oe-fe-se):X,F,m?i(Y,ce):Y);k[j]=pe,V[j]=pe-F}if(c){var ue,le="x"===j?D:P,he="x"===j?A:L,me=k[M],ve="y"===M?"height":"width",ye=me+b[le],ge=me-b[he],be=-1!==[D,P].indexOf(x),xe=null!=(ue=null==S?void 0:S[M])?ue:0,we=be?ye:me-B[ve]-H[ve]-xe+R.altAxis,Oe=be?me+B[ve]+H[ve]-xe-R.altAxis:ge,je=m&&be?function(e,t,n){var r=de(e,t,n);return r>n?n:r}(we,me,Oe):de(m?we:ye,me,m?Oe:ge);k[M]=je,V[M]=je-me}t.modifiersData[r]=V}},requiresIfExists:["offset"]};var me={name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state,r=e.name,o=e.options,i=n.elements.arrow,a=n.modifiersData.popperOffsets,s=C(n.placement),f=z(s),c=[P,L].indexOf(s)>=0?"height":"width";if(i&&a){var p=function(e,t){return Y("number"!=typeof(e="function"==typeof e?e(Object.assign({},t.rects,{placement:t.placement})):e)?e:G(e,k))}(o.padding,n),u=g(i),l="y"===f?D:P,d="y"===f?A:L,h=n.rects.reference[c]+n.rects.reference[f]-a[f]-n.rects.popper[c],m=a[f]-n.rects.reference[f],v=E(i),y=v?"y"===f?v.clientHeight||0:v.clientWidth||0:0,b=h/2-m/2,x=p[l],w=y-u[c]-p[d],O=y/2-u[c]/2+b,j=de(x,O,w),M=f;n.modifiersData[r]=((t={})[M]=j,t.centerOffset=j-O,t)}},effect:function(e){var t=e.state,n=e.options.element,r=void 0===n?"[data-popper-arrow]":n;null!=r&&("string"!=typeof r||(r=t.elements.popper.querySelector(r)))&&N(t.elements.popper,r)&&(t.elements.arrow=r)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function ve(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function ye(e){return[D,L,A,P].some((function(t){return e[t]>=0}))}var ge={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state,n=e.name,r=t.rects.reference,o=t.rects.popper,i=t.modifiersData.preventOverflow,a=J(t,{elementContext:"reference"}),s=J(t,{altBoundary:!0}),f=ve(a,r),c=ve(s,o,i),p=ye(f),u=ye(c);t.modifiersData[n]={referenceClippingOffsets:f,popperEscapeOffsets:c,isReferenceHidden:p,hasPopperEscaped:u},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":p,"data-popper-escaped":u})}},be=Z({defaultModifiers:[ee,te,oe,ie]}),xe=[ee,te,oe,ie,ae,le,he,me,ge],we=Z({defaultModifiers:xe});e.applyStyles=ie,e.arrow=me,e.computeStyles=oe,e.createPopper=we,e.createPopperLite=be,e.defaultModifiers=xe,e.detectOverflow=J,e.eventListeners=ee,e.flip=le,e.hide=ge,e.offset=ae,e.popperGenerator=Z,e.popperOffsets=te,e.preventOverflow=he,Object.defineProperty(e,"__esModule",{value:!0})}));
+
diff --git a/1 PA Decline/article ready_files/libs/quarto-html/quarto-syntax-highlighting.css b/1 PA Decline/article ready_files/libs/quarto-html/quarto-syntax-highlighting.css
new file mode 100644
index 0000000..d9fd98f
--- /dev/null
+++ b/1 PA Decline/article ready_files/libs/quarto-html/quarto-syntax-highlighting.css
@@ -0,0 +1,203 @@
+/* quarto syntax highlight colors */
+:root {
+ --quarto-hl-ot-color: #003B4F;
+ --quarto-hl-at-color: #657422;
+ --quarto-hl-ss-color: #20794D;
+ --quarto-hl-an-color: #5E5E5E;
+ --quarto-hl-fu-color: #4758AB;
+ --quarto-hl-st-color: #20794D;
+ --quarto-hl-cf-color: #003B4F;
+ --quarto-hl-op-color: #5E5E5E;
+ --quarto-hl-er-color: #AD0000;
+ --quarto-hl-bn-color: #AD0000;
+ --quarto-hl-al-color: #AD0000;
+ --quarto-hl-va-color: #111111;
+ --quarto-hl-bu-color: inherit;
+ --quarto-hl-ex-color: inherit;
+ --quarto-hl-pp-color: #AD0000;
+ --quarto-hl-in-color: #5E5E5E;
+ --quarto-hl-vs-color: #20794D;
+ --quarto-hl-wa-color: #5E5E5E;
+ --quarto-hl-do-color: #5E5E5E;
+ --quarto-hl-im-color: #00769E;
+ --quarto-hl-ch-color: #20794D;
+ --quarto-hl-dt-color: #AD0000;
+ --quarto-hl-fl-color: #AD0000;
+ --quarto-hl-co-color: #5E5E5E;
+ --quarto-hl-cv-color: #5E5E5E;
+ --quarto-hl-cn-color: #8f5902;
+ --quarto-hl-sc-color: #5E5E5E;
+ --quarto-hl-dv-color: #AD0000;
+ --quarto-hl-kw-color: #003B4F;
+}
+
+/* other quarto variables */
+:root {
+ --quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+}
+
+pre > code.sourceCode > span {
+ color: #003B4F;
+}
+
+code span {
+ color: #003B4F;
+}
+
+code.sourceCode > span {
+ color: #003B4F;
+}
+
+div.sourceCode,
+div.sourceCode pre.sourceCode {
+ color: #003B4F;
+}
+
+code span.ot {
+ color: #003B4F;
+ font-style: inherit;
+}
+
+code span.at {
+ color: #657422;
+ font-style: inherit;
+}
+
+code span.ss {
+ color: #20794D;
+ font-style: inherit;
+}
+
+code span.an {
+ color: #5E5E5E;
+ font-style: inherit;
+}
+
+code span.fu {
+ color: #4758AB;
+ font-style: inherit;
+}
+
+code span.st {
+ color: #20794D;
+ font-style: inherit;
+}
+
+code span.cf {
+ color: #003B4F;
+ font-style: inherit;
+}
+
+code span.op {
+ color: #5E5E5E;
+ font-style: inherit;
+}
+
+code span.er {
+ color: #AD0000;
+ font-style: inherit;
+}
+
+code span.bn {
+ color: #AD0000;
+ font-style: inherit;
+}
+
+code span.al {
+ color: #AD0000;
+ font-style: inherit;
+}
+
+code span.va {
+ color: #111111;
+ font-style: inherit;
+}
+
+code span.bu {
+ font-style: inherit;
+}
+
+code span.ex {
+ font-style: inherit;
+}
+
+code span.pp {
+ color: #AD0000;
+ font-style: inherit;
+}
+
+code span.in {
+ color: #5E5E5E;
+ font-style: inherit;
+}
+
+code span.vs {
+ color: #20794D;
+ font-style: inherit;
+}
+
+code span.wa {
+ color: #5E5E5E;
+ font-style: italic;
+}
+
+code span.do {
+ color: #5E5E5E;
+ font-style: italic;
+}
+
+code span.im {
+ color: #00769E;
+ font-style: inherit;
+}
+
+code span.ch {
+ color: #20794D;
+ font-style: inherit;
+}
+
+code span.dt {
+ color: #AD0000;
+ font-style: inherit;
+}
+
+code span.fl {
+ color: #AD0000;
+ font-style: inherit;
+}
+
+code span.co {
+ color: #5E5E5E;
+ font-style: inherit;
+}
+
+code span.cv {
+ color: #5E5E5E;
+ font-style: italic;
+}
+
+code span.cn {
+ color: #8f5902;
+ font-style: inherit;
+}
+
+code span.sc {
+ color: #5E5E5E;
+ font-style: inherit;
+}
+
+code span.dv {
+ color: #AD0000;
+ font-style: inherit;
+}
+
+code span.kw {
+ color: #003B4F;
+ font-style: inherit;
+}
+
+.prevent-inlining {
+ content: "";
+}
+
+/*# sourceMappingURL=debc5d5d77c3f9108843748ff7464032.css.map */
diff --git a/1 PA Decline/article ready_files/libs/quarto-html/quarto.js b/1 PA Decline/article ready_files/libs/quarto-html/quarto.js
new file mode 100644
index 0000000..3ebd49c
--- /dev/null
+++ b/1 PA Decline/article ready_files/libs/quarto-html/quarto.js
@@ -0,0 +1,899 @@
+const sectionChanged = new CustomEvent("quarto-sectionChanged", {
+ detail: {},
+ bubbles: true,
+ cancelable: false,
+ composed: false,
+});
+
+const layoutMarginEls = () => {
+ // Find any conflicting margin elements and add margins to the
+ // top to prevent overlap
+ const marginChildren = window.document.querySelectorAll(
+ ".column-margin.column-container > *, .margin-caption, .aside"
+ );
+
+ let lastBottom = 0;
+ for (const marginChild of marginChildren) {
+ if (marginChild.offsetParent !== null) {
+ // clear the top margin so we recompute it
+ marginChild.style.marginTop = null;
+ const top = marginChild.getBoundingClientRect().top + window.scrollY;
+ if (top < lastBottom) {
+ const marginChildStyle = window.getComputedStyle(marginChild);
+ const marginBottom = parseFloat(marginChildStyle["marginBottom"]);
+ const margin = lastBottom - top + marginBottom;
+ marginChild.style.marginTop = `${margin}px`;
+ }
+ const styles = window.getComputedStyle(marginChild);
+ const marginTop = parseFloat(styles["marginTop"]);
+ lastBottom = top + marginChild.getBoundingClientRect().height + marginTop;
+ }
+ }
+};
+
+window.document.addEventListener("DOMContentLoaded", function (_event) {
+ // Recompute the position of margin elements anytime the body size changes
+ if (window.ResizeObserver) {
+ const resizeObserver = new window.ResizeObserver(
+ throttle(() => {
+ layoutMarginEls();
+ if (
+ window.document.body.getBoundingClientRect().width < 990 &&
+ isReaderMode()
+ ) {
+ quartoToggleReader();
+ }
+ }, 50)
+ );
+ resizeObserver.observe(window.document.body);
+ }
+
+ const tocEl = window.document.querySelector('nav.toc-active[role="doc-toc"]');
+ const sidebarEl = window.document.getElementById("quarto-sidebar");
+ const leftTocEl = window.document.getElementById("quarto-sidebar-toc-left");
+ const marginSidebarEl = window.document.getElementById(
+ "quarto-margin-sidebar"
+ );
+ // function to determine whether the element has a previous sibling that is active
+ const prevSiblingIsActiveLink = (el) => {
+ const sibling = el.previousElementSibling;
+ if (sibling && sibling.tagName === "A") {
+ return sibling.classList.contains("active");
+ } else {
+ return false;
+ }
+ };
+
+ // fire slideEnter for bootstrap tab activations (for htmlwidget resize behavior)
+ function fireSlideEnter(e) {
+ const event = window.document.createEvent("Event");
+ event.initEvent("slideenter", true, true);
+ window.document.dispatchEvent(event);
+ }
+ const tabs = window.document.querySelectorAll('a[data-bs-toggle="tab"]');
+ tabs.forEach((tab) => {
+ tab.addEventListener("shown.bs.tab", fireSlideEnter);
+ });
+
+ // fire slideEnter for tabby tab activations (for htmlwidget resize behavior)
+ document.addEventListener("tabby", fireSlideEnter, false);
+
+ // Track scrolling and mark TOC links as active
+ // get table of contents and sidebar (bail if we don't have at least one)
+ const tocLinks = tocEl
+ ? [...tocEl.querySelectorAll("a[data-scroll-target]")]
+ : [];
+ const makeActive = (link) => tocLinks[link].classList.add("active");
+ const removeActive = (link) => tocLinks[link].classList.remove("active");
+ const removeAllActive = () =>
+ [...Array(tocLinks.length).keys()].forEach((link) => removeActive(link));
+
+ // activate the anchor for a section associated with this TOC entry
+ tocLinks.forEach((link) => {
+ link.addEventListener("click", () => {
+ if (link.href.indexOf("#") !== -1) {
+ const anchor = link.href.split("#")[1];
+ const heading = window.document.querySelector(
+ `[data-anchor-id=${anchor}]`
+ );
+ if (heading) {
+ // Add the class
+ heading.classList.add("reveal-anchorjs-link");
+
+ // function to show the anchor
+ const handleMouseout = () => {
+ heading.classList.remove("reveal-anchorjs-link");
+ heading.removeEventListener("mouseout", handleMouseout);
+ };
+
+ // add a function to clear the anchor when the user mouses out of it
+ heading.addEventListener("mouseout", handleMouseout);
+ }
+ }
+ });
+ });
+
+ const sections = tocLinks.map((link) => {
+ const target = link.getAttribute("data-scroll-target");
+ if (target.startsWith("#")) {
+ return window.document.getElementById(decodeURI(`${target.slice(1)}`));
+ } else {
+ return window.document.querySelector(decodeURI(`${target}`));
+ }
+ });
+
+ const sectionMargin = 200;
+ let currentActive = 0;
+ // track whether we've initialized state the first time
+ let init = false;
+
+ const updateActiveLink = () => {
+ // The index from bottom to top (e.g. reversed list)
+ let sectionIndex = -1;
+ if (
+ window.innerHeight + window.pageYOffset >=
+ window.document.body.offsetHeight
+ ) {
+ sectionIndex = 0;
+ } else {
+ sectionIndex = [...sections].reverse().findIndex((section) => {
+ if (section) {
+ return window.pageYOffset >= section.offsetTop - sectionMargin;
+ } else {
+ return false;
+ }
+ });
+ }
+ if (sectionIndex > -1) {
+ const current = sections.length - sectionIndex - 1;
+ if (current !== currentActive) {
+ removeAllActive();
+ currentActive = current;
+ makeActive(current);
+ if (init) {
+ window.dispatchEvent(sectionChanged);
+ }
+ init = true;
+ }
+ }
+ };
+
+ const inHiddenRegion = (top, bottom, hiddenRegions) => {
+ for (const region of hiddenRegions) {
+ if (top <= region.bottom && bottom >= region.top) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ const categorySelector = "header.quarto-title-block .quarto-category";
+ const activateCategories = (href) => {
+ // Find any categories
+ // Surround them with a link pointing back to:
+ // #category=Authoring
+ try {
+ const categoryEls = window.document.querySelectorAll(categorySelector);
+ for (const categoryEl of categoryEls) {
+ const categoryText = categoryEl.textContent;
+ if (categoryText) {
+ const link = `${href}#category=${encodeURIComponent(categoryText)}`;
+ const linkEl = window.document.createElement("a");
+ linkEl.setAttribute("href", link);
+ for (const child of categoryEl.childNodes) {
+ linkEl.append(child);
+ }
+ categoryEl.appendChild(linkEl);
+ }
+ }
+ } catch {
+ // Ignore errors
+ }
+ };
+ function hasTitleCategories() {
+ return window.document.querySelector(categorySelector) !== null;
+ }
+
+ function offsetRelativeUrl(url) {
+ const offset = getMeta("quarto:offset");
+ return offset ? offset + url : url;
+ }
+
+ function offsetAbsoluteUrl(url) {
+ const offset = getMeta("quarto:offset");
+ const baseUrl = new URL(offset, window.location);
+
+ const projRelativeUrl = url.replace(baseUrl, "");
+ if (projRelativeUrl.startsWith("/")) {
+ return projRelativeUrl;
+ } else {
+ return "/" + projRelativeUrl;
+ }
+ }
+
+ // read a meta tag value
+ function getMeta(metaName) {
+ const metas = window.document.getElementsByTagName("meta");
+ for (let i = 0; i < metas.length; i++) {
+ if (metas[i].getAttribute("name") === metaName) {
+ return metas[i].getAttribute("content");
+ }
+ }
+ return "";
+ }
+
+ async function findAndActivateCategories() {
+ const currentPagePath = offsetAbsoluteUrl(window.location.href);
+ const response = await fetch(offsetRelativeUrl("listings.json"));
+ if (response.status == 200) {
+ return response.json().then(function (listingPaths) {
+ const listingHrefs = [];
+ for (const listingPath of listingPaths) {
+ const pathWithoutLeadingSlash = listingPath.listing.substring(1);
+ for (const item of listingPath.items) {
+ if (
+ item === currentPagePath ||
+ item === currentPagePath + "index.html"
+ ) {
+ // Resolve this path against the offset to be sure
+ // we already are using the correct path to the listing
+ // (this adjusts the listing urls to be rooted against
+ // whatever root the page is actually running against)
+ const relative = offsetRelativeUrl(pathWithoutLeadingSlash);
+ const baseUrl = window.location;
+ const resolvedPath = new URL(relative, baseUrl);
+ listingHrefs.push(resolvedPath.pathname);
+ break;
+ }
+ }
+ }
+
+ // Look up the tree for a nearby linting and use that if we find one
+ const nearestListing = findNearestParentListing(
+ offsetAbsoluteUrl(window.location.pathname),
+ listingHrefs
+ );
+ if (nearestListing) {
+ activateCategories(nearestListing);
+ } else {
+ // See if the referrer is a listing page for this item
+ const referredRelativePath = offsetAbsoluteUrl(document.referrer);
+ const referrerListing = listingHrefs.find((listingHref) => {
+ const isListingReferrer =
+ listingHref === referredRelativePath ||
+ listingHref === referredRelativePath + "index.html";
+ return isListingReferrer;
+ });
+
+ if (referrerListing) {
+ // Try to use the referrer if possible
+ activateCategories(referrerListing);
+ } else if (listingHrefs.length > 0) {
+ // Otherwise, just fall back to the first listing
+ activateCategories(listingHrefs[0]);
+ }
+ }
+ });
+ }
+ }
+ if (hasTitleCategories()) {
+ findAndActivateCategories();
+ }
+
+ const findNearestParentListing = (href, listingHrefs) => {
+ if (!href || !listingHrefs) {
+ return undefined;
+ }
+ // Look up the tree for a nearby linting and use that if we find one
+ const relativeParts = href.substring(1).split("/");
+ while (relativeParts.length > 0) {
+ const path = relativeParts.join("/");
+ for (const listingHref of listingHrefs) {
+ if (listingHref.startsWith(path)) {
+ return listingHref;
+ }
+ }
+ relativeParts.pop();
+ }
+
+ return undefined;
+ };
+
+ const manageSidebarVisiblity = (el, placeholderDescriptor) => {
+ let isVisible = true;
+ let elRect;
+
+ return (hiddenRegions) => {
+ if (el === null) {
+ return;
+ }
+
+ // Find the last element of the TOC
+ const lastChildEl = el.lastElementChild;
+
+ if (lastChildEl) {
+ // Converts the sidebar to a menu
+ const convertToMenu = () => {
+ for (const child of el.children) {
+ child.style.opacity = 0;
+ child.style.overflow = "hidden";
+ }
+
+ nexttick(() => {
+ const toggleContainer = window.document.createElement("div");
+ toggleContainer.style.width = "100%";
+ toggleContainer.classList.add("zindex-over-content");
+ toggleContainer.classList.add("quarto-sidebar-toggle");
+ toggleContainer.classList.add("headroom-target"); // Marks this to be managed by headeroom
+ toggleContainer.id = placeholderDescriptor.id;
+ toggleContainer.style.position = "fixed";
+
+ const toggleIcon = window.document.createElement("i");
+ toggleIcon.classList.add("quarto-sidebar-toggle-icon");
+ toggleIcon.classList.add("bi");
+ toggleIcon.classList.add("bi-caret-down-fill");
+
+ const toggleTitle = window.document.createElement("div");
+ const titleEl = window.document.body.querySelector(
+ placeholderDescriptor.titleSelector
+ );
+ if (titleEl) {
+ toggleTitle.append(
+ titleEl.textContent || titleEl.innerText,
+ toggleIcon
+ );
+ }
+ toggleTitle.classList.add("zindex-over-content");
+ toggleTitle.classList.add("quarto-sidebar-toggle-title");
+ toggleContainer.append(toggleTitle);
+
+ const toggleContents = window.document.createElement("div");
+ toggleContents.classList = el.classList;
+ toggleContents.classList.add("zindex-over-content");
+ toggleContents.classList.add("quarto-sidebar-toggle-contents");
+ for (const child of el.children) {
+ if (child.id === "toc-title") {
+ continue;
+ }
+
+ const clone = child.cloneNode(true);
+ clone.style.opacity = 1;
+ clone.style.display = null;
+ toggleContents.append(clone);
+ }
+ toggleContents.style.height = "0px";
+ const positionToggle = () => {
+ // position the element (top left of parent, same width as parent)
+ if (!elRect) {
+ elRect = el.getBoundingClientRect();
+ }
+ toggleContainer.style.left = `${elRect.left}px`;
+ toggleContainer.style.top = `${elRect.top}px`;
+ toggleContainer.style.width = `${elRect.width}px`;
+ };
+ positionToggle();
+
+ toggleContainer.append(toggleContents);
+ el.parentElement.prepend(toggleContainer);
+
+ // Process clicks
+ let tocShowing = false;
+ // Allow the caller to control whether this is dismissed
+ // when it is clicked (e.g. sidebar navigation supports
+ // opening and closing the nav tree, so don't dismiss on click)
+ const clickEl = placeholderDescriptor.dismissOnClick
+ ? toggleContainer
+ : toggleTitle;
+
+ const closeToggle = () => {
+ if (tocShowing) {
+ toggleContainer.classList.remove("expanded");
+ toggleContents.style.height = "0px";
+ tocShowing = false;
+ }
+ };
+
+ // Get rid of any expanded toggle if the user scrolls
+ window.document.addEventListener(
+ "scroll",
+ throttle(() => {
+ closeToggle();
+ }, 50)
+ );
+
+ // Handle positioning of the toggle
+ window.addEventListener(
+ "resize",
+ throttle(() => {
+ elRect = undefined;
+ positionToggle();
+ }, 50)
+ );
+
+ window.addEventListener("quarto-hrChanged", () => {
+ elRect = undefined;
+ });
+
+ // Process the click
+ clickEl.onclick = () => {
+ if (!tocShowing) {
+ toggleContainer.classList.add("expanded");
+ toggleContents.style.height = null;
+ tocShowing = true;
+ } else {
+ closeToggle();
+ }
+ };
+ });
+ };
+
+ // Converts a sidebar from a menu back to a sidebar
+ const convertToSidebar = () => {
+ for (const child of el.children) {
+ child.style.opacity = 1;
+ child.style.overflow = null;
+ }
+
+ const placeholderEl = window.document.getElementById(
+ placeholderDescriptor.id
+ );
+ if (placeholderEl) {
+ placeholderEl.remove();
+ }
+
+ el.classList.remove("rollup");
+ };
+
+ if (isReaderMode()) {
+ convertToMenu();
+ isVisible = false;
+ } else {
+ // Find the top and bottom o the element that is being managed
+ const elTop = el.offsetTop;
+ const elBottom =
+ elTop + lastChildEl.offsetTop + lastChildEl.offsetHeight;
+
+ if (!isVisible) {
+ // If the element is current not visible reveal if there are
+ // no conflicts with overlay regions
+ if (!inHiddenRegion(elTop, elBottom, hiddenRegions)) {
+ convertToSidebar();
+ isVisible = true;
+ }
+ } else {
+ // If the element is visible, hide it if it conflicts with overlay regions
+ // and insert a placeholder toggle (or if we're in reader mode)
+ if (inHiddenRegion(elTop, elBottom, hiddenRegions)) {
+ convertToMenu();
+ isVisible = false;
+ }
+ }
+ }
+ }
+ };
+ };
+
+ const tabEls = document.querySelectorAll('a[data-bs-toggle="tab"]');
+ for (const tabEl of tabEls) {
+ const id = tabEl.getAttribute("data-bs-target");
+ if (id) {
+ const columnEl = document.querySelector(
+ `${id} .column-margin, .tabset-margin-content`
+ );
+ if (columnEl)
+ tabEl.addEventListener("shown.bs.tab", function (event) {
+ const el = event.srcElement;
+ if (el) {
+ const visibleCls = `${el.id}-margin-content`;
+ // walk up until we find a parent tabset
+ let panelTabsetEl = el.parentElement;
+ while (panelTabsetEl) {
+ if (panelTabsetEl.classList.contains("panel-tabset")) {
+ break;
+ }
+ panelTabsetEl = panelTabsetEl.parentElement;
+ }
+
+ if (panelTabsetEl) {
+ const prevSib = panelTabsetEl.previousElementSibling;
+ if (
+ prevSib &&
+ prevSib.classList.contains("tabset-margin-container")
+ ) {
+ const childNodes = prevSib.querySelectorAll(
+ ".tabset-margin-content"
+ );
+ for (const childEl of childNodes) {
+ if (childEl.classList.contains(visibleCls)) {
+ childEl.classList.remove("collapse");
+ } else {
+ childEl.classList.add("collapse");
+ }
+ }
+ }
+ }
+ }
+
+ layoutMarginEls();
+ });
+ }
+ }
+
+ // Manage the visibility of the toc and the sidebar
+ const marginScrollVisibility = manageSidebarVisiblity(marginSidebarEl, {
+ id: "quarto-toc-toggle",
+ titleSelector: "#toc-title",
+ dismissOnClick: true,
+ });
+ const sidebarScrollVisiblity = manageSidebarVisiblity(sidebarEl, {
+ id: "quarto-sidebarnav-toggle",
+ titleSelector: ".title",
+ dismissOnClick: false,
+ });
+ let tocLeftScrollVisibility;
+ if (leftTocEl) {
+ tocLeftScrollVisibility = manageSidebarVisiblity(leftTocEl, {
+ id: "quarto-lefttoc-toggle",
+ titleSelector: "#toc-title",
+ dismissOnClick: true,
+ });
+ }
+
+ // Find the first element that uses formatting in special columns
+ const conflictingEls = window.document.body.querySelectorAll(
+ '[class^="column-"], [class*=" column-"], aside, [class*="margin-caption"], [class*=" margin-caption"], [class*="margin-ref"], [class*=" margin-ref"]'
+ );
+
+ // Filter all the possibly conflicting elements into ones
+ // the do conflict on the left or ride side
+ const arrConflictingEls = Array.from(conflictingEls);
+ const leftSideConflictEls = arrConflictingEls.filter((el) => {
+ if (el.tagName === "ASIDE") {
+ return false;
+ }
+ return Array.from(el.classList).find((className) => {
+ return (
+ className !== "column-body" &&
+ className.startsWith("column-") &&
+ !className.endsWith("right") &&
+ !className.endsWith("container") &&
+ className !== "column-margin"
+ );
+ });
+ });
+ const rightSideConflictEls = arrConflictingEls.filter((el) => {
+ if (el.tagName === "ASIDE") {
+ return true;
+ }
+
+ const hasMarginCaption = Array.from(el.classList).find((className) => {
+ return className == "margin-caption";
+ });
+ if (hasMarginCaption) {
+ return true;
+ }
+
+ return Array.from(el.classList).find((className) => {
+ return (
+ className !== "column-body" &&
+ !className.endsWith("container") &&
+ className.startsWith("column-") &&
+ !className.endsWith("left")
+ );
+ });
+ });
+
+ const kOverlapPaddingSize = 10;
+ function toRegions(els) {
+ return els.map((el) => {
+ const boundRect = el.getBoundingClientRect();
+ const top =
+ boundRect.top +
+ document.documentElement.scrollTop -
+ kOverlapPaddingSize;
+ return {
+ top,
+ bottom: top + el.scrollHeight + 2 * kOverlapPaddingSize,
+ };
+ });
+ }
+
+ let hasObserved = false;
+ const visibleItemObserver = (els) => {
+ let visibleElements = [...els];
+ const intersectionObserver = new IntersectionObserver(
+ (entries, _observer) => {
+ entries.forEach((entry) => {
+ if (entry.isIntersecting) {
+ if (visibleElements.indexOf(entry.target) === -1) {
+ visibleElements.push(entry.target);
+ }
+ } else {
+ visibleElements = visibleElements.filter((visibleEntry) => {
+ return visibleEntry !== entry;
+ });
+ }
+ });
+
+ if (!hasObserved) {
+ hideOverlappedSidebars();
+ }
+ hasObserved = true;
+ },
+ {}
+ );
+ els.forEach((el) => {
+ intersectionObserver.observe(el);
+ });
+
+ return {
+ getVisibleEntries: () => {
+ return visibleElements;
+ },
+ };
+ };
+
+ const rightElementObserver = visibleItemObserver(rightSideConflictEls);
+ const leftElementObserver = visibleItemObserver(leftSideConflictEls);
+
+ const hideOverlappedSidebars = () => {
+ marginScrollVisibility(toRegions(rightElementObserver.getVisibleEntries()));
+ sidebarScrollVisiblity(toRegions(leftElementObserver.getVisibleEntries()));
+ if (tocLeftScrollVisibility) {
+ tocLeftScrollVisibility(
+ toRegions(leftElementObserver.getVisibleEntries())
+ );
+ }
+ };
+
+ window.quartoToggleReader = () => {
+ // Applies a slow class (or removes it)
+ // to update the transition speed
+ const slowTransition = (slow) => {
+ const manageTransition = (id, slow) => {
+ const el = document.getElementById(id);
+ if (el) {
+ if (slow) {
+ el.classList.add("slow");
+ } else {
+ el.classList.remove("slow");
+ }
+ }
+ };
+
+ manageTransition("TOC", slow);
+ manageTransition("quarto-sidebar", slow);
+ };
+ const readerMode = !isReaderMode();
+ setReaderModeValue(readerMode);
+
+ // If we're entering reader mode, slow the transition
+ if (readerMode) {
+ slowTransition(readerMode);
+ }
+ highlightReaderToggle(readerMode);
+ hideOverlappedSidebars();
+
+ // If we're exiting reader mode, restore the non-slow transition
+ if (!readerMode) {
+ slowTransition(!readerMode);
+ }
+ };
+
+ const highlightReaderToggle = (readerMode) => {
+ const els = document.querySelectorAll(".quarto-reader-toggle");
+ if (els) {
+ els.forEach((el) => {
+ if (readerMode) {
+ el.classList.add("reader");
+ } else {
+ el.classList.remove("reader");
+ }
+ });
+ }
+ };
+
+ const setReaderModeValue = (val) => {
+ if (window.location.protocol !== "file:") {
+ window.localStorage.setItem("quarto-reader-mode", val);
+ } else {
+ localReaderMode = val;
+ }
+ };
+
+ const isReaderMode = () => {
+ if (window.location.protocol !== "file:") {
+ return window.localStorage.getItem("quarto-reader-mode") === "true";
+ } else {
+ return localReaderMode;
+ }
+ };
+ let localReaderMode = null;
+
+ const tocOpenDepthStr = tocEl?.getAttribute("data-toc-expanded");
+ const tocOpenDepth = tocOpenDepthStr ? Number(tocOpenDepthStr) : 1;
+
+ // Walk the TOC and collapse/expand nodes
+ // Nodes are expanded if:
+ // - they are top level
+ // - they have children that are 'active' links
+ // - they are directly below an link that is 'active'
+ const walk = (el, depth) => {
+ // Tick depth when we enter a UL
+ if (el.tagName === "UL") {
+ depth = depth + 1;
+ }
+
+ // It this is active link
+ let isActiveNode = false;
+ if (el.tagName === "A" && el.classList.contains("active")) {
+ isActiveNode = true;
+ }
+
+ // See if there is an active child to this element
+ let hasActiveChild = false;
+ for (child of el.children) {
+ hasActiveChild = walk(child, depth) || hasActiveChild;
+ }
+
+ // Process the collapse state if this is an UL
+ if (el.tagName === "UL") {
+ if (tocOpenDepth === -1 && depth > 1) {
+ el.classList.add("collapse");
+ } else if (
+ depth <= tocOpenDepth ||
+ hasActiveChild ||
+ prevSiblingIsActiveLink(el)
+ ) {
+ el.classList.remove("collapse");
+ } else {
+ el.classList.add("collapse");
+ }
+
+ // untick depth when we leave a UL
+ depth = depth - 1;
+ }
+ return hasActiveChild || isActiveNode;
+ };
+
+ // walk the TOC and expand / collapse any items that should be shown
+
+ if (tocEl) {
+ walk(tocEl, 0);
+ updateActiveLink();
+ }
+
+ // Throttle the scroll event and walk peridiocally
+ window.document.addEventListener(
+ "scroll",
+ throttle(() => {
+ if (tocEl) {
+ updateActiveLink();
+ walk(tocEl, 0);
+ }
+ if (!isReaderMode()) {
+ hideOverlappedSidebars();
+ }
+ }, 5)
+ );
+ window.addEventListener(
+ "resize",
+ throttle(() => {
+ if (!isReaderMode()) {
+ hideOverlappedSidebars();
+ }
+ }, 10)
+ );
+ hideOverlappedSidebars();
+ highlightReaderToggle(isReaderMode());
+});
+
+// grouped tabsets
+window.addEventListener("pageshow", (_event) => {
+ function getTabSettings() {
+ const data = localStorage.getItem("quarto-persistent-tabsets-data");
+ if (!data) {
+ localStorage.setItem("quarto-persistent-tabsets-data", "{}");
+ return {};
+ }
+ if (data) {
+ return JSON.parse(data);
+ }
+ }
+
+ function setTabSettings(data) {
+ localStorage.setItem(
+ "quarto-persistent-tabsets-data",
+ JSON.stringify(data)
+ );
+ }
+
+ function setTabState(groupName, groupValue) {
+ const data = getTabSettings();
+ data[groupName] = groupValue;
+ setTabSettings(data);
+ }
+
+ function toggleTab(tab, active) {
+ const tabPanelId = tab.getAttribute("aria-controls");
+ const tabPanel = document.getElementById(tabPanelId);
+ if (active) {
+ tab.classList.add("active");
+ tabPanel.classList.add("active");
+ } else {
+ tab.classList.remove("active");
+ tabPanel.classList.remove("active");
+ }
+ }
+
+ function toggleAll(selectedGroup, selectorsToSync) {
+ for (const [thisGroup, tabs] of Object.entries(selectorsToSync)) {
+ const active = selectedGroup === thisGroup;
+ for (const tab of tabs) {
+ toggleTab(tab, active);
+ }
+ }
+ }
+
+ function findSelectorsToSyncByLanguage() {
+ const result = {};
+ const tabs = Array.from(
+ document.querySelectorAll(`div[data-group] a[id^='tabset-']`)
+ );
+ for (const item of tabs) {
+ const div = item.parentElement.parentElement.parentElement;
+ const group = div.getAttribute("data-group");
+ if (!result[group]) {
+ result[group] = {};
+ }
+ const selectorsToSync = result[group];
+ const value = item.innerHTML;
+ if (!selectorsToSync[value]) {
+ selectorsToSync[value] = [];
+ }
+ selectorsToSync[value].push(item);
+ }
+ return result;
+ }
+
+ function setupSelectorSync() {
+ const selectorsToSync = findSelectorsToSyncByLanguage();
+ Object.entries(selectorsToSync).forEach(([group, tabSetsByValue]) => {
+ Object.entries(tabSetsByValue).forEach(([value, items]) => {
+ items.forEach((item) => {
+ item.addEventListener("click", (_event) => {
+ setTabState(group, value);
+ toggleAll(value, selectorsToSync[group]);
+ });
+ });
+ });
+ });
+ return selectorsToSync;
+ }
+
+ const selectorsToSync = setupSelectorSync();
+ for (const [group, selectedName] of Object.entries(getTabSettings())) {
+ const selectors = selectorsToSync[group];
+ // it's possible that stale state gives us empty selections, so we explicitly check here.
+ if (selectors) {
+ toggleAll(selectedName, selectors);
+ }
+ }
+});
+
+function throttle(func, wait) {
+ let waiting = false;
+ return function () {
+ if (!waiting) {
+ func.apply(this, arguments);
+ waiting = true;
+ setTimeout(function () {
+ waiting = false;
+ }, wait);
+ }
+ };
+}
+
+function nexttick(func) {
+ return setTimeout(func, 0);
+}
diff --git a/1 PA Decline/article ready_files/libs/quarto-html/tippy.css b/1 PA Decline/article ready_files/libs/quarto-html/tippy.css
new file mode 100644
index 0000000..e6ae635
--- /dev/null
+++ b/1 PA Decline/article ready_files/libs/quarto-html/tippy.css
@@ -0,0 +1 @@
+.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}
\ No newline at end of file
diff --git a/1 PA Decline/article ready_files/libs/quarto-html/tippy.umd.min.js b/1 PA Decline/article ready_files/libs/quarto-html/tippy.umd.min.js
new file mode 100644
index 0000000..ca292be
--- /dev/null
+++ b/1 PA Decline/article ready_files/libs/quarto-html/tippy.umd.min.js
@@ -0,0 +1,2 @@
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@popperjs/core")):"function"==typeof define&&define.amd?define(["@popperjs/core"],t):(e=e||self).tippy=t(e.Popper)}(this,(function(e){"use strict";var t={passive:!0,capture:!0},n=function(){return document.body};function r(e,t,n){if(Array.isArray(e)){var r=e[t];return null==r?Array.isArray(n)?n[t]:n:r}return e}function o(e,t){var n={}.toString.call(e);return 0===n.indexOf("[object")&&n.indexOf(t+"]")>-1}function i(e,t){return"function"==typeof e?e.apply(void 0,t):e}function a(e,t){return 0===t?e:function(r){clearTimeout(n),n=setTimeout((function(){e(r)}),t)};var n}function s(e,t){var n=Object.assign({},e);return t.forEach((function(e){delete n[e]})),n}function u(e){return[].concat(e)}function c(e,t){-1===e.indexOf(t)&&e.push(t)}function p(e){return e.split("-")[0]}function f(e){return[].slice.call(e)}function l(e){return Object.keys(e).reduce((function(t,n){return void 0!==e[n]&&(t[n]=e[n]),t}),{})}function d(){return document.createElement("div")}function v(e){return["Element","Fragment"].some((function(t){return o(e,t)}))}function m(e){return o(e,"MouseEvent")}function g(e){return!(!e||!e._tippy||e._tippy.reference!==e)}function h(e){return v(e)?[e]:function(e){return o(e,"NodeList")}(e)?f(e):Array.isArray(e)?e:f(document.querySelectorAll(e))}function b(e,t){e.forEach((function(e){e&&(e.style.transitionDuration=t+"ms")}))}function y(e,t){e.forEach((function(e){e&&e.setAttribute("data-state",t)}))}function w(e){var t,n=u(e)[0];return null!=n&&null!=(t=n.ownerDocument)&&t.body?n.ownerDocument:document}function E(e,t,n){var r=t+"EventListener";["transitionend","webkitTransitionEnd"].forEach((function(t){e[r](t,n)}))}function O(e,t){for(var n=t;n;){var r;if(e.contains(n))return!0;n=null==n.getRootNode||null==(r=n.getRootNode())?void 0:r.host}return!1}var x={isTouch:!1},C=0;function T(){x.isTouch||(x.isTouch=!0,window.performance&&document.addEventListener("mousemove",A))}function A(){var e=performance.now();e-C<20&&(x.isTouch=!1,document.removeEventListener("mousemove",A)),C=e}function L(){var e=document.activeElement;if(g(e)){var t=e._tippy;e.blur&&!t.state.isVisible&&e.blur()}}var D=!!("undefined"!=typeof window&&"undefined"!=typeof document)&&!!window.msCrypto,R=Object.assign({appendTo:n,aria:{content:"auto",expanded:"auto"},delay:0,duration:[300,250],getReferenceClientRect:null,hideOnClick:!0,ignoreAttributes:!1,interactive:!1,interactiveBorder:2,interactiveDebounce:0,moveTransition:"",offset:[0,10],onAfterUpdate:function(){},onBeforeUpdate:function(){},onCreate:function(){},onDestroy:function(){},onHidden:function(){},onHide:function(){},onMount:function(){},onShow:function(){},onShown:function(){},onTrigger:function(){},onUntrigger:function(){},onClickOutside:function(){},placement:"top",plugins:[],popperOptions:{},render:null,showOnCreate:!1,touch:!0,trigger:"mouseenter focus",triggerTarget:null},{animateFill:!1,followCursor:!1,inlinePositioning:!1,sticky:!1},{allowHTML:!1,animation:"fade",arrow:!0,content:"",inertia:!1,maxWidth:350,role:"tooltip",theme:"",zIndex:9999}),k=Object.keys(R);function P(e){var t=(e.plugins||[]).reduce((function(t,n){var r,o=n.name,i=n.defaultValue;o&&(t[o]=void 0!==e[o]?e[o]:null!=(r=R[o])?r:i);return t}),{});return Object.assign({},e,t)}function j(e,t){var n=Object.assign({},t,{content:i(t.content,[e])},t.ignoreAttributes?{}:function(e,t){return(t?Object.keys(P(Object.assign({},R,{plugins:t}))):k).reduce((function(t,n){var r=(e.getAttribute("data-tippy-"+n)||"").trim();if(!r)return t;if("content"===n)t[n]=r;else try{t[n]=JSON.parse(r)}catch(e){t[n]=r}return t}),{})}(e,t.plugins));return n.aria=Object.assign({},R.aria,n.aria),n.aria={expanded:"auto"===n.aria.expanded?t.interactive:n.aria.expanded,content:"auto"===n.aria.content?t.interactive?null:"describedby":n.aria.content},n}function M(e,t){e.innerHTML=t}function V(e){var t=d();return!0===e?t.className="tippy-arrow":(t.className="tippy-svg-arrow",v(e)?t.appendChild(e):M(t,e)),t}function I(e,t){v(t.content)?(M(e,""),e.appendChild(t.content)):"function"!=typeof t.content&&(t.allowHTML?M(e,t.content):e.textContent=t.content)}function S(e){var t=e.firstElementChild,n=f(t.children);return{box:t,content:n.find((function(e){return e.classList.contains("tippy-content")})),arrow:n.find((function(e){return e.classList.contains("tippy-arrow")||e.classList.contains("tippy-svg-arrow")})),backdrop:n.find((function(e){return e.classList.contains("tippy-backdrop")}))}}function N(e){var t=d(),n=d();n.className="tippy-box",n.setAttribute("data-state","hidden"),n.setAttribute("tabindex","-1");var r=d();function o(n,r){var o=S(t),i=o.box,a=o.content,s=o.arrow;r.theme?i.setAttribute("data-theme",r.theme):i.removeAttribute("data-theme"),"string"==typeof r.animation?i.setAttribute("data-animation",r.animation):i.removeAttribute("data-animation"),r.inertia?i.setAttribute("data-inertia",""):i.removeAttribute("data-inertia"),i.style.maxWidth="number"==typeof r.maxWidth?r.maxWidth+"px":r.maxWidth,r.role?i.setAttribute("role",r.role):i.removeAttribute("role"),n.content===r.content&&n.allowHTML===r.allowHTML||I(a,e.props),r.arrow?s?n.arrow!==r.arrow&&(i.removeChild(s),i.appendChild(V(r.arrow))):i.appendChild(V(r.arrow)):s&&i.removeChild(s)}return r.className="tippy-content",r.setAttribute("data-state","hidden"),I(r,e.props),t.appendChild(n),n.appendChild(r),o(e.props,e.props),{popper:t,onUpdate:o}}N.$$tippy=!0;var B=1,H=[],U=[];function _(o,s){var v,g,h,C,T,A,L,k,M=j(o,Object.assign({},R,P(l(s)))),V=!1,I=!1,N=!1,_=!1,F=[],W=a(we,M.interactiveDebounce),X=B++,Y=(k=M.plugins).filter((function(e,t){return k.indexOf(e)===t})),$={id:X,reference:o,popper:d(),popperInstance:null,props:M,state:{isEnabled:!0,isVisible:!1,isDestroyed:!1,isMounted:!1,isShown:!1},plugins:Y,clearDelayTimeouts:function(){clearTimeout(v),clearTimeout(g),cancelAnimationFrame(h)},setProps:function(e){if($.state.isDestroyed)return;ae("onBeforeUpdate",[$,e]),be();var t=$.props,n=j(o,Object.assign({},t,l(e),{ignoreAttributes:!0}));$.props=n,he(),t.interactiveDebounce!==n.interactiveDebounce&&(ce(),W=a(we,n.interactiveDebounce));t.triggerTarget&&!n.triggerTarget?u(t.triggerTarget).forEach((function(e){e.removeAttribute("aria-expanded")})):n.triggerTarget&&o.removeAttribute("aria-expanded");ue(),ie(),J&&J(t,n);$.popperInstance&&(Ce(),Ae().forEach((function(e){requestAnimationFrame(e._tippy.popperInstance.forceUpdate)})));ae("onAfterUpdate",[$,e])},setContent:function(e){$.setProps({content:e})},show:function(){var e=$.state.isVisible,t=$.state.isDestroyed,o=!$.state.isEnabled,a=x.isTouch&&!$.props.touch,s=r($.props.duration,0,R.duration);if(e||t||o||a)return;if(te().hasAttribute("disabled"))return;if(ae("onShow",[$],!1),!1===$.props.onShow($))return;$.state.isVisible=!0,ee()&&(z.style.visibility="visible");ie(),de(),$.state.isMounted||(z.style.transition="none");if(ee()){var u=re(),p=u.box,f=u.content;b([p,f],0)}A=function(){var e;if($.state.isVisible&&!_){if(_=!0,z.offsetHeight,z.style.transition=$.props.moveTransition,ee()&&$.props.animation){var t=re(),n=t.box,r=t.content;b([n,r],s),y([n,r],"visible")}se(),ue(),c(U,$),null==(e=$.popperInstance)||e.forceUpdate(),ae("onMount",[$]),$.props.animation&&ee()&&function(e,t){me(e,t)}(s,(function(){$.state.isShown=!0,ae("onShown",[$])}))}},function(){var e,t=$.props.appendTo,r=te();e=$.props.interactive&&t===n||"parent"===t?r.parentNode:i(t,[r]);e.contains(z)||e.appendChild(z);$.state.isMounted=!0,Ce()}()},hide:function(){var e=!$.state.isVisible,t=$.state.isDestroyed,n=!$.state.isEnabled,o=r($.props.duration,1,R.duration);if(e||t||n)return;if(ae("onHide",[$],!1),!1===$.props.onHide($))return;$.state.isVisible=!1,$.state.isShown=!1,_=!1,V=!1,ee()&&(z.style.visibility="hidden");if(ce(),ve(),ie(!0),ee()){var i=re(),a=i.box,s=i.content;$.props.animation&&(b([a,s],o),y([a,s],"hidden"))}se(),ue(),$.props.animation?ee()&&function(e,t){me(e,(function(){!$.state.isVisible&&z.parentNode&&z.parentNode.contains(z)&&t()}))}(o,$.unmount):$.unmount()},hideWithInteractivity:function(e){ne().addEventListener("mousemove",W),c(H,W),W(e)},enable:function(){$.state.isEnabled=!0},disable:function(){$.hide(),$.state.isEnabled=!1},unmount:function(){$.state.isVisible&&$.hide();if(!$.state.isMounted)return;Te(),Ae().forEach((function(e){e._tippy.unmount()})),z.parentNode&&z.parentNode.removeChild(z);U=U.filter((function(e){return e!==$})),$.state.isMounted=!1,ae("onHidden",[$])},destroy:function(){if($.state.isDestroyed)return;$.clearDelayTimeouts(),$.unmount(),be(),delete o._tippy,$.state.isDestroyed=!0,ae("onDestroy",[$])}};if(!M.render)return $;var q=M.render($),z=q.popper,J=q.onUpdate;z.setAttribute("data-tippy-root",""),z.id="tippy-"+$.id,$.popper=z,o._tippy=$,z._tippy=$;var G=Y.map((function(e){return e.fn($)})),K=o.hasAttribute("aria-expanded");return he(),ue(),ie(),ae("onCreate",[$]),M.showOnCreate&&Le(),z.addEventListener("mouseenter",(function(){$.props.interactive&&$.state.isVisible&&$.clearDelayTimeouts()})),z.addEventListener("mouseleave",(function(){$.props.interactive&&$.props.trigger.indexOf("mouseenter")>=0&&ne().addEventListener("mousemove",W)})),$;function Q(){var e=$.props.touch;return Array.isArray(e)?e:[e,0]}function Z(){return"hold"===Q()[0]}function ee(){var e;return!(null==(e=$.props.render)||!e.$$tippy)}function te(){return L||o}function ne(){var e=te().parentNode;return e?w(e):document}function re(){return S(z)}function oe(e){return $.state.isMounted&&!$.state.isVisible||x.isTouch||C&&"focus"===C.type?0:r($.props.delay,e?0:1,R.delay)}function ie(e){void 0===e&&(e=!1),z.style.pointerEvents=$.props.interactive&&!e?"":"none",z.style.zIndex=""+$.props.zIndex}function ae(e,t,n){var r;(void 0===n&&(n=!0),G.forEach((function(n){n[e]&&n[e].apply(n,t)})),n)&&(r=$.props)[e].apply(r,t)}function se(){var e=$.props.aria;if(e.content){var t="aria-"+e.content,n=z.id;u($.props.triggerTarget||o).forEach((function(e){var r=e.getAttribute(t);if($.state.isVisible)e.setAttribute(t,r?r+" "+n:n);else{var o=r&&r.replace(n,"").trim();o?e.setAttribute(t,o):e.removeAttribute(t)}}))}}function ue(){!K&&$.props.aria.expanded&&u($.props.triggerTarget||o).forEach((function(e){$.props.interactive?e.setAttribute("aria-expanded",$.state.isVisible&&e===te()?"true":"false"):e.removeAttribute("aria-expanded")}))}function ce(){ne().removeEventListener("mousemove",W),H=H.filter((function(e){return e!==W}))}function pe(e){if(!x.isTouch||!N&&"mousedown"!==e.type){var t=e.composedPath&&e.composedPath()[0]||e.target;if(!$.props.interactive||!O(z,t)){if(u($.props.triggerTarget||o).some((function(e){return O(e,t)}))){if(x.isTouch)return;if($.state.isVisible&&$.props.trigger.indexOf("click")>=0)return}else ae("onClickOutside",[$,e]);!0===$.props.hideOnClick&&($.clearDelayTimeouts(),$.hide(),I=!0,setTimeout((function(){I=!1})),$.state.isMounted||ve())}}}function fe(){N=!0}function le(){N=!1}function de(){var e=ne();e.addEventListener("mousedown",pe,!0),e.addEventListener("touchend",pe,t),e.addEventListener("touchstart",le,t),e.addEventListener("touchmove",fe,t)}function ve(){var e=ne();e.removeEventListener("mousedown",pe,!0),e.removeEventListener("touchend",pe,t),e.removeEventListener("touchstart",le,t),e.removeEventListener("touchmove",fe,t)}function me(e,t){var n=re().box;function r(e){e.target===n&&(E(n,"remove",r),t())}if(0===e)return t();E(n,"remove",T),E(n,"add",r),T=r}function ge(e,t,n){void 0===n&&(n=!1),u($.props.triggerTarget||o).forEach((function(r){r.addEventListener(e,t,n),F.push({node:r,eventType:e,handler:t,options:n})}))}function he(){var e;Z()&&(ge("touchstart",ye,{passive:!0}),ge("touchend",Ee,{passive:!0})),(e=$.props.trigger,e.split(/\s+/).filter(Boolean)).forEach((function(e){if("manual"!==e)switch(ge(e,ye),e){case"mouseenter":ge("mouseleave",Ee);break;case"focus":ge(D?"focusout":"blur",Oe);break;case"focusin":ge("focusout",Oe)}}))}function be(){F.forEach((function(e){var t=e.node,n=e.eventType,r=e.handler,o=e.options;t.removeEventListener(n,r,o)})),F=[]}function ye(e){var t,n=!1;if($.state.isEnabled&&!xe(e)&&!I){var r="focus"===(null==(t=C)?void 0:t.type);C=e,L=e.currentTarget,ue(),!$.state.isVisible&&m(e)&&H.forEach((function(t){return t(e)})),"click"===e.type&&($.props.trigger.indexOf("mouseenter")<0||V)&&!1!==$.props.hideOnClick&&$.state.isVisible?n=!0:Le(e),"click"===e.type&&(V=!n),n&&!r&&De(e)}}function we(e){var t=e.target,n=te().contains(t)||z.contains(t);"mousemove"===e.type&&n||function(e,t){var n=t.clientX,r=t.clientY;return e.every((function(e){var t=e.popperRect,o=e.popperState,i=e.props.interactiveBorder,a=p(o.placement),s=o.modifiersData.offset;if(!s)return!0;var u="bottom"===a?s.top.y:0,c="top"===a?s.bottom.y:0,f="right"===a?s.left.x:0,l="left"===a?s.right.x:0,d=t.top-r+u>i,v=r-t.bottom-c>i,m=t.left-n+f>i,g=n-t.right-l>i;return d||v||m||g}))}(Ae().concat(z).map((function(e){var t,n=null==(t=e._tippy.popperInstance)?void 0:t.state;return n?{popperRect:e.getBoundingClientRect(),popperState:n,props:M}:null})).filter(Boolean),e)&&(ce(),De(e))}function Ee(e){xe(e)||$.props.trigger.indexOf("click")>=0&&V||($.props.interactive?$.hideWithInteractivity(e):De(e))}function Oe(e){$.props.trigger.indexOf("focusin")<0&&e.target!==te()||$.props.interactive&&e.relatedTarget&&z.contains(e.relatedTarget)||De(e)}function xe(e){return!!x.isTouch&&Z()!==e.type.indexOf("touch")>=0}function Ce(){Te();var t=$.props,n=t.popperOptions,r=t.placement,i=t.offset,a=t.getReferenceClientRect,s=t.moveTransition,u=ee()?S(z).arrow:null,c=a?{getBoundingClientRect:a,contextElement:a.contextElement||te()}:o,p=[{name:"offset",options:{offset:i}},{name:"preventOverflow",options:{padding:{top:2,bottom:2,left:5,right:5}}},{name:"flip",options:{padding:5}},{name:"computeStyles",options:{adaptive:!s}},{name:"$$tippy",enabled:!0,phase:"beforeWrite",requires:["computeStyles"],fn:function(e){var t=e.state;if(ee()){var n=re().box;["placement","reference-hidden","escaped"].forEach((function(e){"placement"===e?n.setAttribute("data-placement",t.placement):t.attributes.popper["data-popper-"+e]?n.setAttribute("data-"+e,""):n.removeAttribute("data-"+e)})),t.attributes.popper={}}}}];ee()&&u&&p.push({name:"arrow",options:{element:u,padding:3}}),p.push.apply(p,(null==n?void 0:n.modifiers)||[]),$.popperInstance=e.createPopper(c,z,Object.assign({},n,{placement:r,onFirstUpdate:A,modifiers:p}))}function Te(){$.popperInstance&&($.popperInstance.destroy(),$.popperInstance=null)}function Ae(){return f(z.querySelectorAll("[data-tippy-root]"))}function Le(e){$.clearDelayTimeouts(),e&&ae("onTrigger",[$,e]),de();var t=oe(!0),n=Q(),r=n[0],o=n[1];x.isTouch&&"hold"===r&&o&&(t=o),t?v=setTimeout((function(){$.show()}),t):$.show()}function De(e){if($.clearDelayTimeouts(),ae("onUntrigger",[$,e]),$.state.isVisible){if(!($.props.trigger.indexOf("mouseenter")>=0&&$.props.trigger.indexOf("click")>=0&&["mouseleave","mousemove"].indexOf(e.type)>=0&&V)){var t=oe(!1);t?g=setTimeout((function(){$.state.isVisible&&$.hide()}),t):h=requestAnimationFrame((function(){$.hide()}))}}else ve()}}function F(e,n){void 0===n&&(n={});var r=R.plugins.concat(n.plugins||[]);document.addEventListener("touchstart",T,t),window.addEventListener("blur",L);var o=Object.assign({},n,{plugins:r}),i=h(e).reduce((function(e,t){var n=t&&_(t,o);return n&&e.push(n),e}),[]);return v(e)?i[0]:i}F.defaultProps=R,F.setDefaultProps=function(e){Object.keys(e).forEach((function(t){R[t]=e[t]}))},F.currentInput=x;var W=Object.assign({},e.applyStyles,{effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow)}}),X={mouseover:"mouseenter",focusin:"focus",click:"click"};var Y={name:"animateFill",defaultValue:!1,fn:function(e){var t;if(null==(t=e.props.render)||!t.$$tippy)return{};var n=S(e.popper),r=n.box,o=n.content,i=e.props.animateFill?function(){var e=d();return e.className="tippy-backdrop",y([e],"hidden"),e}():null;return{onCreate:function(){i&&(r.insertBefore(i,r.firstElementChild),r.setAttribute("data-animatefill",""),r.style.overflow="hidden",e.setProps({arrow:!1,animation:"shift-away"}))},onMount:function(){if(i){var e=r.style.transitionDuration,t=Number(e.replace("ms",""));o.style.transitionDelay=Math.round(t/10)+"ms",i.style.transitionDuration=e,y([i],"visible")}},onShow:function(){i&&(i.style.transitionDuration="0ms")},onHide:function(){i&&y([i],"hidden")}}}};var $={clientX:0,clientY:0},q=[];function z(e){var t=e.clientX,n=e.clientY;$={clientX:t,clientY:n}}var J={name:"followCursor",defaultValue:!1,fn:function(e){var t=e.reference,n=w(e.props.triggerTarget||t),r=!1,o=!1,i=!0,a=e.props;function s(){return"initial"===e.props.followCursor&&e.state.isVisible}function u(){n.addEventListener("mousemove",f)}function c(){n.removeEventListener("mousemove",f)}function p(){r=!0,e.setProps({getReferenceClientRect:null}),r=!1}function f(n){var r=!n.target||t.contains(n.target),o=e.props.followCursor,i=n.clientX,a=n.clientY,s=t.getBoundingClientRect(),u=i-s.left,c=a-s.top;!r&&e.props.interactive||e.setProps({getReferenceClientRect:function(){var e=t.getBoundingClientRect(),n=i,r=a;"initial"===o&&(n=e.left+u,r=e.top+c);var s="horizontal"===o?e.top:r,p="vertical"===o?e.right:n,f="horizontal"===o?e.bottom:r,l="vertical"===o?e.left:n;return{width:p-l,height:f-s,top:s,right:p,bottom:f,left:l}}})}function l(){e.props.followCursor&&(q.push({instance:e,doc:n}),function(e){e.addEventListener("mousemove",z)}(n))}function d(){0===(q=q.filter((function(t){return t.instance!==e}))).filter((function(e){return e.doc===n})).length&&function(e){e.removeEventListener("mousemove",z)}(n)}return{onCreate:l,onDestroy:d,onBeforeUpdate:function(){a=e.props},onAfterUpdate:function(t,n){var i=n.followCursor;r||void 0!==i&&a.followCursor!==i&&(d(),i?(l(),!e.state.isMounted||o||s()||u()):(c(),p()))},onMount:function(){e.props.followCursor&&!o&&(i&&(f($),i=!1),s()||u())},onTrigger:function(e,t){m(t)&&($={clientX:t.clientX,clientY:t.clientY}),o="focus"===t.type},onHidden:function(){e.props.followCursor&&(p(),c(),i=!0)}}}};var G={name:"inlinePositioning",defaultValue:!1,fn:function(e){var t,n=e.reference;var r=-1,o=!1,i=[],a={name:"tippyInlinePositioning",enabled:!0,phase:"afterWrite",fn:function(o){var a=o.state;e.props.inlinePositioning&&(-1!==i.indexOf(a.placement)&&(i=[]),t!==a.placement&&-1===i.indexOf(a.placement)&&(i.push(a.placement),e.setProps({getReferenceClientRect:function(){return function(e){return function(e,t,n,r){if(n.length<2||null===e)return t;if(2===n.length&&r>=0&&n[0].left>n[1].right)return n[r]||t;switch(e){case"top":case"bottom":var o=n[0],i=n[n.length-1],a="top"===e,s=o.top,u=i.bottom,c=a?o.left:i.left,p=a?o.right:i.right;return{top:s,bottom:u,left:c,right:p,width:p-c,height:u-s};case"left":case"right":var f=Math.min.apply(Math,n.map((function(e){return e.left}))),l=Math.max.apply(Math,n.map((function(e){return e.right}))),d=n.filter((function(t){return"left"===e?t.left===f:t.right===l})),v=d[0].top,m=d[d.length-1].bottom;return{top:v,bottom:m,left:f,right:l,width:l-f,height:m-v};default:return t}}(p(e),n.getBoundingClientRect(),f(n.getClientRects()),r)}(a.placement)}})),t=a.placement)}};function s(){var t;o||(t=function(e,t){var n;return{popperOptions:Object.assign({},e.popperOptions,{modifiers:[].concat(((null==(n=e.popperOptions)?void 0:n.modifiers)||[]).filter((function(e){return e.name!==t.name})),[t])})}}(e.props,a),o=!0,e.setProps(t),o=!1)}return{onCreate:s,onAfterUpdate:s,onTrigger:function(t,n){if(m(n)){var o=f(e.reference.getClientRects()),i=o.find((function(e){return e.left-2<=n.clientX&&e.right+2>=n.clientX&&e.top-2<=n.clientY&&e.bottom+2>=n.clientY})),a=o.indexOf(i);r=a>-1?a:r}},onHidden:function(){r=-1}}}};var K={name:"sticky",defaultValue:!1,fn:function(e){var t=e.reference,n=e.popper;function r(t){return!0===e.props.sticky||e.props.sticky===t}var o=null,i=null;function a(){var s=r("reference")?(e.popperInstance?e.popperInstance.state.elements.reference:t).getBoundingClientRect():null,u=r("popper")?n.getBoundingClientRect():null;(s&&Q(o,s)||u&&Q(i,u))&&e.popperInstance&&e.popperInstance.update(),o=s,i=u,e.state.isMounted&&requestAnimationFrame(a)}return{onMount:function(){e.props.sticky&&a()}}}};function Q(e,t){return!e||!t||(e.top!==t.top||e.right!==t.right||e.bottom!==t.bottom||e.left!==t.left)}return F.setDefaultProps({plugins:[Y,J,G,K],render:N}),F.createSingleton=function(e,t){var n;void 0===t&&(t={});var r,o=e,i=[],a=[],c=t.overrides,p=[],f=!1;function l(){a=o.map((function(e){return u(e.props.triggerTarget||e.reference)})).reduce((function(e,t){return e.concat(t)}),[])}function v(){i=o.map((function(e){return e.reference}))}function m(e){o.forEach((function(t){e?t.enable():t.disable()}))}function g(e){return o.map((function(t){var n=t.setProps;return t.setProps=function(o){n(o),t.reference===r&&e.setProps(o)},function(){t.setProps=n}}))}function h(e,t){var n=a.indexOf(t);if(t!==r){r=t;var s=(c||[]).concat("content").reduce((function(e,t){return e[t]=o[n].props[t],e}),{});e.setProps(Object.assign({},s,{getReferenceClientRect:"function"==typeof s.getReferenceClientRect?s.getReferenceClientRect:function(){var e;return null==(e=i[n])?void 0:e.getBoundingClientRect()}}))}}m(!1),v(),l();var b={fn:function(){return{onDestroy:function(){m(!0)},onHidden:function(){r=null},onClickOutside:function(e){e.props.showOnCreate&&!f&&(f=!0,r=null)},onShow:function(e){e.props.showOnCreate&&!f&&(f=!0,h(e,i[0]))},onTrigger:function(e,t){h(e,t.currentTarget)}}}},y=F(d(),Object.assign({},s(t,["overrides"]),{plugins:[b].concat(t.plugins||[]),triggerTarget:a,popperOptions:Object.assign({},t.popperOptions,{modifiers:[].concat((null==(n=t.popperOptions)?void 0:n.modifiers)||[],[W])})})),w=y.show;y.show=function(e){if(w(),!r&&null==e)return h(y,i[0]);if(!r||null!=e){if("number"==typeof e)return i[e]&&h(y,i[e]);if(o.indexOf(e)>=0){var t=e.reference;return h(y,t)}return i.indexOf(e)>=0?h(y,e):void 0}},y.showNext=function(){var e=i[0];if(!r)return y.show(0);var t=i.indexOf(r);y.show(i[t+1]||e)},y.showPrevious=function(){var e=i[i.length-1];if(!r)return y.show(e);var t=i.indexOf(r),n=i[t-1]||e;y.show(n)};var E=y.setProps;return y.setProps=function(e){c=e.overrides||c,E(e)},y.setInstances=function(e){m(!0),p.forEach((function(e){return e()})),o=e,m(!1),v(),l(),p=g(y),y.setProps({triggerTarget:a})},p=g(y),y},F.delegate=function(e,n){var r=[],o=[],i=!1,a=n.target,c=s(n,["target"]),p=Object.assign({},c,{trigger:"manual",touch:!1}),f=Object.assign({touch:R.touch},c,{showOnCreate:!0}),l=F(e,p);function d(e){if(e.target&&!i){var t=e.target.closest(a);if(t){var r=t.getAttribute("data-tippy-trigger")||n.trigger||R.trigger;if(!t._tippy&&!("touchstart"===e.type&&"boolean"==typeof f.touch||"touchstart"!==e.type&&r.indexOf(X[e.type])<0)){var s=F(t,f);s&&(o=o.concat(s))}}}}function v(e,t,n,o){void 0===o&&(o=!1),e.addEventListener(t,n,o),r.push({node:e,eventType:t,handler:n,options:o})}return u(l).forEach((function(e){var n=e.destroy,a=e.enable,s=e.disable;e.destroy=function(e){void 0===e&&(e=!0),e&&o.forEach((function(e){e.destroy()})),o=[],r.forEach((function(e){var t=e.node,n=e.eventType,r=e.handler,o=e.options;t.removeEventListener(n,r,o)})),r=[],n()},e.enable=function(){a(),o.forEach((function(e){return e.enable()})),i=!1},e.disable=function(){s(),o.forEach((function(e){return e.disable()})),i=!0},function(e){var n=e.reference;v(n,"touchstart",d,t),v(n,"mouseover",d),v(n,"focusin",d),v(n,"click",d)}(e)})),l},F.hideAll=function(e){var t=void 0===e?{}:e,n=t.exclude,r=t.duration;U.forEach((function(e){var t=!1;if(n&&(t=g(n)?e.reference===n:e.popper===n.popper),!t){var o=e.props.duration;e.setProps({duration:r}),e.hide(),e.state.isDestroyed||e.setProps({duration:o})}}))},F.roundArrow=' ',F}));
+
diff --git a/1 PA Decline/article sankey.R b/1 PA Decline/article sankey.R
new file mode 100644
index 0000000..7bcf1b4
--- /dev/null
+++ b/1 PA Decline/article sankey.R
@@ -0,0 +1,325 @@
+# source("1 PA Decline/data_format.R")
+
+# NEW QUARTILES
+
+ds <- readr::read_csv(here::here("/Volumes/Data/REDCap/DDV/talos_ddv.csv"))
+
+df_raw <- ds |>
+ dplyr::filter(!pase_score_missings_0, !pase_score_missings_4) |>
+ dplyr::transmute(
+ pase_0_cut = as.numeric(stRoke::quantile_cut(x = pase_score_sum_0,
+ groups = 4,
+ group.names = paste0(1:4))),
+ pase_6_cut = as.numeric(stRoke::quantile_cut(x = pase_score_sum_4,
+ y = pase_score_sum_0,
+ groups = 4,
+ inc.outs = TRUE,
+ group.names = paste0(1:4))),
+ change = dplyr::case_when(
+ pase_0_cut %in% 2:4 & pase_6_cut == 1 ~ "drop",
+ pase_6_cut %in% 2:4 & pase_0_cut == 1 ~ "hop",
+ pase_0_cut %in% 2:4 & pase_6_cut %in% 2:4 ~ "hh",
+ pase_0_cut %in% 1 & pase_6_cut == 1 ~ "ll"
+ )
+ ,
+ change_any = factor(dplyr::case_when(
+ pase_6_cut > pase_0_cut ~ "hop",
+ pase_6_cut < pase_0_cut ~ "drop",
+ pase_0_cut %in% 2:4 & pase_6_cut %in% 2:4 ~ "hh",
+ pase_0_cut %in% 1 & pase_6_cut == 1 ~ "ll"
+ )
+ )
+ )
+
+
+# Visuals - sankey
+# https://stackoverflow.com/questions/50395027/beautifying-sankey-alluvial-visualization-using-r
+
+
+## Painting
+
+sankey_ready <- function(data,change.var="change"){
+df <- data |>
+ dplyr::count(dplyr::across(dplyr::all_of(c("pase_0_cut", "pase_6_cut",change.var)))) |>
+ dplyr::mutate(dplyr::across(dplyr::starts_with("pase_"),\(.x) factor(.x))) |>
+ setNames(c("pase_0_cut", "pase_6_cut","change","n"))
+
+lbs0 <-
+ c(
+ paste0("1st \n(n=", sum(df$n[df$pase_0_cut == "1"]), ")"),
+ paste0("2nd \n(n=", sum(df$n[df$pase_0_cut == "2"]), ")"),
+ paste0("3rd \n(n=", sum(df$n[df$pase_0_cut == "3"]), ")"),
+ paste0("4th \n(n=", sum(df$n[df$pase_0_cut == "4"]), ")")
+ )
+
+
+lbs6 <-
+ c(
+ paste0("1st \n(n=", sum(df$n[df$pase_6_cut == "1"]), ")"),
+ paste0("2nd \n(n=", sum(df$n[df$pase_6_cut == "2"]), ")"),
+ paste0("3rd \n(n=", sum(df$n[df$pase_6_cut == "3"]), ")"),
+ paste0("4th \n(n=", sum(df$n[df$pase_6_cut == "4"]), ")")
+ )
+
+
+levels(df$pase_0_cut) <- lbs0[1:length(levels(df$pase_0_cut))]
+levels(df$pase_6_cut) <- lbs6[1:length(levels(df$pase_6_cut))]
+
+df$pase_0_cut <- factor(df$pase_0_cut, levels = rev(levels(df$pase_0_cut)))
+df$pase_6_cut <- factor(df$pase_6_cut, levels = rev(levels(df$pase_6_cut)))
+
+df$change <- factor(df$change, levels = c("hh","hop", "drop", "ll"))
+
+if (change.var=="change"){
+ df |> dplyr::mutate(first_grp=ifelse(substr(pase_0_cut,1,1)==1,"low","higher"))
+} else if (change.var=="change_any"){
+ df |> dplyr::mutate(first_grp=dplyr::case_when(
+ substr(pase_0_cut,1,1)==1 ~ "low",
+ substr(pase_0_cut,1,1) %in% 2:3 ~ "mid",
+ substr(pase_0_cut,1,1)==4 ~ "high"))
+}
+}
+
+# hops <- "#66c1a3" # grey
+# # drops <- "#990033" # Midtrød
+# drops <- "#CE0045" # Lighter Midtrød
+# nos <- "grey80" # Light grey
+#
+# # border <- "#00596B"
+# # box <- "#008099"
+#
+# border <- "#EA571D"
+# box <- "#1E4B66"
+#
+# higher <- "yellow"
+# low <- "purple"
+
+library(ggalluvial)
+
+library(ggplot2)
+
+# stRoke::color_plot(viridisLite::turbo (4))
+
+plot_sankey <- function(data,
+ # palette=viridisLite::turbo(4),
+ hops = "#66c1a3",
+ drops = "#CE0045",
+ hh = "#fcdc9c",
+ ll = "#fcdc9c",
+ border = "#EA571D",
+ box = "#1E4B66",
+ higher = "#2986cc",
+ mid = "#b4a7d6",
+ low = "#590075",
+ alpha = 0.8,
+ a1=pase_0_cut,
+ a2=pase_6_cut,
+ a1.grp=first_grp,
+ text.size = 4
+ ){
+
+ if (length(unique(data[[ncol(data)]]))>2) {
+ fills <- c(higher,low,mid)
+ } else {
+ fills <- c(higher,low)
+ }
+
+ cls <- c(hh, hops, drops, ll)
+ # stratum.grp <- c(df[["first_grp"]],df[["last_grp"]])
+
+ # cls <- palette
+ # browser()
+ ggplot(data, aes(y = n, axis1 = {{a1}}, axis2 = {{a2}})) +
+ geom_alluvium(
+ aes(fill = change, color = change),
+ width = 1 / 16,
+ alpha = alpha,
+ knot.pos = 0.4,
+ curve_type ="sigmoid"
+ ) +
+ geom_stratum(aes(fill={{a1.grp}}),
+ # geom_stratum(aes(fill=stratum_grp),
+ size = 2,
+ width = 1 / 3.4,
+ # fill = box,
+ color = border
+ ) +
+ geom_text(stat = "stratum",
+ aes(label = after_stat(stratum)),
+ colour = "white",
+ size = text.size,
+ lineheight = 1) +
+ scale_x_continuous(
+ breaks = 1:2,
+ labels = c("Pre-stroke\nPASE quartile", "Six months\nPASE quartile")
+ ) +
+ scale_fill_manual(values = c(cls,fills),na.value = box) +
+ scale_color_manual(values = cls) +
+ ggtitle("PA level changes from \npre-stroke to post-stroke")
+}
+
+## Changes to left colum coloring is needed.
+
+c("change","change_any") |> purrr::map(\(.x){
+ df_raw |>
+ sankey_ready(change.var = .x)
+}) |>
+ purrr::map(\(.x){
+ .x |> plot_sankey(text.size=4.5)
+ }) |>
+ patchwork::wrap_plots()
+
+
+
+p_delta <- df_raw |>
+ sankey_ready() |>
+ plot_sankey(text.size=4.5)
+
+
+# plotly::ggplotly(p_delta)
+
+# png(
+# filename = "sankey_change_ARTICLEA.png",
+# units = "mm",
+# width = 500,
+# height = 600,
+# pointsize = 60,
+# res = 300
+# )
+ggplot2::ggsave(filename = "1 PA Decline/sankey_change_ARTICLEA_ejn.png",
+ p_delta +
+ theme_void() +
+ theme(
+ legend.position = "none",
+ # panel.grid.major = element_blank(),
+ # panel.grid.minor = element_blank(),
+ # axis.text.y = element_blank(),
+ # axis.title.y = element_blank(),
+ axis.text.x = element_text(),
+ # text = element_text(size = 5),
+ plot.title = element_blank(),
+ # panel.background = element_rect(fill = "white"),
+ plot.background = element_rect(fill="white"),
+ panel.border = element_blank()
+ ),
+ units = "mm",
+ width = 84,
+ height = 70,
+ # pointsize = 30,
+ dpi = 600)
+#
+#
+ggplot2::ggsave(filename = "1 PA Decline/sankey_change_ARTICLEA.png",
+ p_delta +
+ theme_void() +
+ theme(
+ legend.position = "none",
+ # panel.grid.major = element_blank(),
+ # panel.grid.minor = element_blank(),
+ # axis.text.y = element_blank(),
+ # axis.title.y = element_blank(),
+ axis.text.x = element_text(),
+ text = element_text(size = 20),
+ plot.title = element_blank(),
+ # panel.background = element_rect(fill = "white"),
+ plot.background = element_rect(fill="white"),
+ panel.border = element_blank()
+ ),
+ units = "mm",
+ width = 200,
+ height = 220,
+ # pointsize = 30,
+ dpi = 600)
+
+ggplot2::ggsave(filename = "1 PA Decline/sankey_change_ARTICLEA.pdf",
+ p_delta +
+ theme_void() +
+ theme(
+ legend.position = "none",
+ # panel.grid.major = element_blank(),
+ # panel.grid.minor = element_blank(),
+ # axis.text.y = element_blank(),
+ # axis.title.y = element_blank(),
+ axis.text.x = element_text(),
+ text = element_text(size = 20),
+ plot.title = element_blank(),
+ # panel.background = element_rect(fill = "white"),
+ plot.background = element_rect(fill="white"),
+ panel.border = element_blank()
+ ),
+ units = "mm",
+ width = 200,
+ height = 220,
+ # pointsize = 30,
+ dpi = 1200)
+
+# png(
+# filename = "sankey_change_PhDDay.png",
+# units = "mm",
+# width = 100,
+# height = 200,
+# pointsize = 15,
+# res = 300
+# )
+# p_delta +
+# theme_minimal() +
+# theme(
+# legend.position = "none",
+# panel.grid.major = element_blank(),
+# panel.grid.minor = element_blank(),
+# axis.text.y = element_blank(),
+# axis.title.y = element_blank(),
+# axis.text.x = element_text(size = 14, face = "bold"),
+# plot.title = element_text(hjust = 0.5, vjust = 1, size = 30, face = "bold")
+# )
+# dev.off()
+
+
+# png(
+# filename = "sankey_change_PhDDay_min.png",
+# units = "mm",
+# width = 500,
+# height = 500,
+# pointsize = 15,
+# res = 300
+# )
+# p_delta +
+# theme_minimal() +
+# theme(
+# legend.position = "none",
+# panel.grid.major = element_blank(),
+# panel.grid.minor = element_blank(),
+# axis.text.y = element_blank(),
+# axis.title.y = element_blank(),
+# axis.text.x = element_blank(),
+# plot.title = element_blank(),
+# panel.background = element_rect(fill = "transparent"),
+# plot.background = element_rect(fill = "transparent", color = NA)
+# )
+# dev.off()
+
+
+
+# png(
+# filename = "sankey_change_ESOC23.png",
+# units = "mm",
+# width = 500,
+# height = 500,
+# pointsize = 60,
+# res = 300
+# )
+# p_delta +
+# theme_minimal() +
+# theme(
+# legend.position = "none",
+# panel.grid.major = element_blank(),
+# panel.grid.minor = element_blank(),
+# axis.text.y = element_blank(),
+# axis.title.y = element_blank(),
+# axis.text.x = element_blank(),
+# plot.title = element_blank(),
+# panel.background = element_rect(fill = "transparent"),
+# plot.background = element_rect(fill = "transparent", color = NA)
+# )
+# dev.off()
+
diff --git a/1 PA Decline/calibration plot.R b/1 PA Decline/calibration plot.R
new file mode 100644
index 0000000..8c78cc0
--- /dev/null
+++ b/1 PA Decline/calibration plot.R
@@ -0,0 +1,24 @@
+# calibration plot
+
+
+ds <- openxlsx2::read_xlsx("1 PA Decline/Fra DDV/calibration_imp.xlsx")
+
+p <- ds |> split(ds$model) |>
+ purrr::imap(\(.x,.i){
+ .x |> predtools::calibration_plot(obs="y",pred="pred")|>
+ purrr::pluck("calibration_plot")+
+ ggplot2::ggtitle(.i)+
+ ggplot2::scale_x_continuous(breaks=seq(0,1,.25),limits=c(0,1))+
+ ggplot2::scale_y_continuous(breaks=seq(0,1,.25),limits=c(-.1,1.1))
+ }) |>
+ patchwork::wrap_plots(ncol=2)
+
+
+ggplot2::ggsave(filename = "1 PA Decline/calibration_imp.pdf",
+ plot=p,
+ units = "mm",
+ width = 200,
+ height = 100,
+ # pointsize = 30,
+ dpi = 1200)
+
\ No newline at end of file
diff --git a/1 PA Decline/calibration_imp.pdf b/1 PA Decline/calibration_imp.pdf
new file mode 100644
index 0000000..d4338ee
Binary files /dev/null and b/1 PA Decline/calibration_imp.pdf differ
diff --git a/1 PA Decline/coef plot.R b/1 PA Decline/coef plot.R
new file mode 100644
index 0000000..6a96342
--- /dev/null
+++ b/1 PA Decline/coef plot.R
@@ -0,0 +1,335 @@
+## Examples
+
+# stRoke::talos |>
+# dplyr::mutate(across(tidyselect::starts_with("mrs"), as.numeric)) |>
+# stRoke::generic_stroke(group = "rtreat", score = "mrs_6", variables = c("hypertension", "diabetes", "civil")) |>
+# purrr::pluck(3)
+#
+# stRoke::talos |>
+# dplyr::mutate(mrs_6_bin = as.numeric(mrs_6 < 1)) |>
+# finalfit::or_plot(dependent = "mrs_6_bin", explanatory = c("hypertension", "diabetes", "civil"))
+
+
+# Consider utilising plotting like finalfit::or_plot
+
+
+## Sample data
+# df_coefs <- list(
+# mrs_6 = stRoke::talos |>
+# dplyr::select(tidyselect::all_of(c("mrs_6", "rtreat", "hypertension", "diabetes", "civil"))) |>
+# lm(data = _, mrs_6 ~ .),
+# mrs_1 = stRoke::talos |>
+# dplyr::select(tidyselect::all_of(c("mrs_1", "rtreat", "hypertension", "diabetes", "civil"))) |>
+# lm(data = _, mrs_1 ~ .)
+# ) |>
+# lapply(gtsummary::tbl_regression) |>
+# purrr::map(function(.x) {
+# .x |> purrr::pluck("table_body") |>
+# dplyr::select(tidyselect::all_of(c("variable","estimate"))) |>
+# na.omit()
+# }) |> purrr::reduce(dplyr::full_join,by="variable") |>
+# setNames(c("variable","increase","decrease"))
+
+get_coefs(path = here::here("1 PA Decline/Fra DDV/240624/pa_change_analyses.docx"),index.table = 2)
+
+
+source(here::here("1 PA Decline/dst import.R"))
+df_coefs_raw <- get_coefs(path = here::here("1 PA Decline/Fra DDV/240624/pa_change_analyses.docx"),index.table = 2) |>
+ dplyr::filter(variable != "(Intercept)") |>
+ dplyr::select(variable, hop_median, drop_median) |>
+ setNames(c("variable", "INCREASE", "DECREASE"))
+
+## Real work
+df_coefs <- df_coefs_raw |>
+ dplyr::mutate(dplyr::across(
+ tidyselect::all_of(c("INCREASE", "DECREASE")),
+ function(.x) {
+ # signif(
+ as.numeric(.x)#,
+ # 3
+ # )
+ }
+ )) |>
+ dplyr::mutate(variable = dplyr::if_else(variable == "Alcohol consumption above recommendations",
+ "High alcohol consumption", variable
+ ))|>
+ ## Important step to keep the data ordered for ggplot
+ (function(.y) {
+ .y |> dplyr::mutate(variable = factor(variable, levels = rev(.y$variable)))
+ })()
+
+## Highest ORs
+list(df_coefs[c(1,2)],df_coefs[c(1,3)]) |>
+ setNames(names(df_coefs)[2:3]) |>
+ purrr::map(function(.x){
+ .x |>
+ setNames(c("var","val"))|>
+ dplyr::mutate(sorting=abs(log(val))) |>
+ dplyr::arrange(1-sorting) |>
+ dplyr::mutate(dplyr::across(dplyr::where(is.numeric),~signif(.x,2))) |>
+ head(5)
+})
+
+
+df_long <- df_coefs |>
+ tidyr::pivot_longer(cols = !tidyselect::matches("variable")) |>
+ dplyr::mutate(name = factor(name, levels = rev(unique(name))))
+
+
+cols <- c(
+ "#CE0045",
+ "#66c1a3"
+) # Lighter Midtrød
+
+
+create_log_tics <- function(data){
+ sort(round(unique(c(1/data,data)),2))
+}
+
+x.tics <- create_log_tics(c(.25, .4, .6, .8, 1))
+
+legend.title=""
+
+levels(df_long$name) <- c("OR for decrease",
+ "OR for increase")
+
+p1 <- df_long |>
+ # dplyr::filter(name=="decrease") |>
+ ggplot2::ggplot(ggplot2::aes(x = log(value), y = variable, color = name, fill = name)) +
+ ggplot2::geom_vline(ggplot2::aes(xintercept = 0), linewidth = .5, linetype = "dashed") +
+ # ggplot2::geom_errorbarh(ggplot2::aes(xmax = boxCIHigh, xmin = boxCILow), size = .5, height =
+ # .2, color = "gray50") +
+ ggplot2::geom_point(ggplot2::aes(shape = name), size = 6) +
+ # ggplot2::coord_trans(x = scales:::exp_trans(10)) +
+ ggplot2::scale_x_continuous(
+ breaks = log(x.tics),
+ labels = x.tics,
+ limits = log(range(x.tics))
+ ) +
+ ggplot2::scale_color_manual(values = cols) +
+ ggplot2::scale_fill_manual(values = cols) +
+ ggplot2::scale_shape_manual(values=c(25,24)) +
+ ggplot2::theme_bw() +
+ ggplot2::theme(panel.grid.minor = ggplot2::element_blank(),
+ # legend.title = ggplot2::element_text(""),
+ legend.position = "bottom") +
+ ggplot2::ylab("") +
+ ggplot2::xlab("Odds ratio (log)") +
+ ggplot2::labs(shape=legend.title,
+ color=legend.title,
+ fill=legend.title)
+
+#
+# png(
+# filename = here::here("1 PA Decline/coef_plot_change_ARTICLEA.png"),
+# units = "mm",
+# width = 300,
+# height = 300,
+# pointsize = 5,
+# res = 300
+# )
+# p1 +
+# # ggplot2::theme_minimal() +
+# ggplot2::theme(
+# # legend.position = "none",
+# # panel.grid.major = ggplot2::element_blank(),
+# # panel.grid.minor = ggplot2::element_blank(),
+# # axis.text.y = ggplot2::element_blank(),
+# # axis.title.y = ggplot2::element_blank(),
+# # axis.text.x = element_blank(),
+# text = ggplot2::element_text(size = 25)#,
+# # plot.title = element_text(),
+# # panel.background = ggplot2::element_rect(fill = "transparent")#,
+# # plot.background = ggplot2::element_rect(fill = "transparent", color = NA)
+# )
+# dev.off()
+
+
+x.tics <- create_log_tics(c(.25, .6, 1))
+
+ggplot2::ggsave(
+ filename = here::here("1 PA Decline/coef_plot_change_ARTICLEA_facet.png"),
+ plot = p1 +
+ ggplot2::scale_x_continuous(
+ breaks = log(x.tics),
+ labels = x.tics,
+ limits = log(range(x.tics))
+ ) +
+ ggplot2::facet_wrap(facets = ggplot2::vars(name),ncol=2) +
+ # ggplot2::theme_minimal() +
+ ggplot2::theme(
+ legend.position = "none",
+ # panel.grid.major = ggplot2::element_blank(),
+ # panel.grid.minor = ggplot2::element_blank(),
+ # axis.text.y = ggplot2::element_blank(),
+ # axis.title.y = ggplot2::element_blank(),
+ # axis.text.x = element_blank(),
+ text = ggplot2::element_text(size = 16)#,
+ # plot.title = element_text(),
+ # panel.background = ggplot2::element_rect(fill = "transparent")#,
+ # plot.background = ggplot2::element_rect(fill = "transparent", color = NA)
+ ),
+ units = "mm",
+ width = 200,
+ height = 200,
+ pointsize = 5,
+ dpi = 600
+)
+
+ggplot2::ggsave(
+ filename = here::here("1 PA Decline/coef_plot_change_ARTICLEA_facet.pdf"),
+ plot = p1 +
+ ggplot2::scale_x_continuous(
+ breaks = log(x.tics),
+ labels = x.tics,
+ limits = log(range(x.tics))
+ ) +
+ ggplot2::facet_wrap(facets = ggplot2::vars(name),ncol=2) +
+ # ggplot2::theme_minimal() +
+ ggplot2::theme(
+ legend.position = "none",
+ # panel.grid.major = ggplot2::element_blank(),
+ # panel.grid.minor = ggplot2::element_blank(),
+ # axis.text.y = ggplot2::element_blank(),
+ # axis.title.y = ggplot2::element_blank(),
+ # axis.text.x = element_blank(),
+ text = ggplot2::element_text(size = 16)#,
+ # plot.title = element_text(),
+ # panel.background = ggplot2::element_rect(fill = "transparent")#,
+ # plot.background = ggplot2::element_rect(fill = "transparent", color = NA)
+ ),
+ units = "mm",
+ width = 200,
+ height = 200,
+ pointsize = 5,
+ dpi = 1200
+)
+
+
+
+# p1 <- df_long |>
+# # dplyr::mutate(value=log10(value)
+# # ) |>
+# ggplot2::ggplot(ggplot2::aes(x = variable, y = log(value), fill = name)) +
+# ggplot2::geom_bar(stat = "identity", position = ggplot2::position_dodge()) +
+# ggplot2::coord_trans(y = scales:::exp_trans(10)) +
+# ggplot2::scale_y_continuous(
+# breaks = log10(c(.2, .4, .5, 1, 1.2, 1.4, 1.6, 2, 2.5)),
+# labels = c(.2, .4, .5, 1, 1.2, 1.4, 1.6, 2, 2.5),
+# limits = log10(c(0.09, 2.5))
+# ) +
+# ggplot2::geom_hline(yintercept = 0) +
+# ggplot2::coord_flip() +
+# ggplot2::scale_fill_manual(values = cols) +
+# # REF: https://stackoverflow.com/a/22517219/21019325
+# ggplot2::guides(fill = ggplot2::guide_legend(reverse = TRUE)) +
+# ggplot2::ylab("OR (log))") +
+# ggplot2::labs(
+# fill = "Model" # ,
+# # title = "Prediction models: increase and decrease after stroke",
+# # subtitle = "Median coeficient after cross validation"
+# ) +
+# ggplot2::theme_classic(11) +
+# ggplot2::theme(
+# axis.title.x = ggplot2::element_text(),
+# axis.title.y = ggplot2::element_blank(),
+# axis.text.y = ggplot2::element_blank(),
+# axis.line.y = ggplot2::element_blank(),
+# axis.ticks.y = ggplot2::element_blank() # ,
+# # legend.position = "none"
+# )
+# p1
+
+# df_plot <- df_long |>
+# dplyr::mutate(
+# id = seq_len(dplyr::n()),
+# dplyr::across(where(is.numeric), \(.i) signif(.i, digits = 2))
+# ) |>
+# (function(.x) {
+# split(.x, .x[["variable"]]) |>
+# purrr::map(function(.y) {
+# .y |> dplyr::mutate(id = rev(id))
+# }) |>
+# dplyr::bind_rows()
+# })() |>
+# dplyr::mutate(id = rev(id)) |>
+# (function(.z) {
+# .z |> dplyr::mutate(var_label = variable |> (function(.x) {
+# split(.z, .x) |>
+# purrr::map(function(.y) {
+# c("", unique(as.character(.y[[1]])))
+# }) |>
+# purrr::list_c()
+# })())
+# })() |>
+# dplyr::mutate(val_label = paste("OR:", value))
+
+
+
+# df_plot <- df_long |>
+# dplyr::mutate(
+# id = seq_len(dplyr::n()),
+# dplyr::across(where(is.numeric), \(.i) signif(.i, digits = 2))
+# ) |>
+# (function(.x) {
+# split(.x, .x[["variable"]]) |>
+# purrr::map(function(.y) {
+# .y |> dplyr::mutate(id = rev(id))
+# }) |>
+# dplyr::bind_rows()
+# })() |>
+# dplyr::mutate(id = rev(id)) |>
+# (function(.z) {
+# .z |> dplyr::mutate(var_label = variable |> (function(.x) {
+# split(.z, .x) |>
+# purrr::map(function(.y) {
+# c("", unique(as.character(.y[[1]])))
+# }) |>
+# purrr::list_c()
+# })())
+# })() |>
+# dplyr::mutate(val_label = paste("OR:", value))
+#
+# table_text_size <- 5
+# title_text_size <- 20
+# column_space <- c(0, .6)
+#
+# t1 <- df_plot |> ggplot2::ggplot(ggplot2::aes(x = var, y = variable)) +
+# ggplot2::annotate("text",
+# x = column_space[1], y = df_plot$variable,
+# label = df_plot[[5]], hjust = 0, size = table_text_size
+# ) +
+# # ggplot2::annotate("text",
+# # x = column_space[2], y = df_plot$id,
+# # label = df_plot[[2]], hjust = 0, size = table_text_size
+# # ) +
+# ggplot2::annotate("text",
+# x = column_space[2], y = df_plot$variable,
+# label = df_plot[[6]], hjust = 0, size = table_text_size
+# ) +
+# ggplot2::xlim(0, .8) +
+# ggplot2::theme_classic(14) +
+# ggplot2::theme(
+# axis.title.x = ggplot2::element_text(colour = "white"),
+# axis.text.x = ggplot2::element_text(colour = "white"),
+# axis.title.y = ggplot2::element_blank(),
+# axis.text.y = ggplot2::element_blank(),
+# axis.ticks.y = ggplot2::element_blank(),
+# line = ggplot2::element_blank()
+# )
+#
+# patchwork::wrap_plots(t1,
+# p1,
+# ncol = 2, widths = c(1, 1.5)
+# ) + patchwork::plot_annotation(title = "Prediction models: decrease and increase PA")
+#
+#
+# gridExtra::grid.arrange(t1,
+# p1,
+# ncol = 2,
+# widths = c(1, 1.5),
+# top = grid::textGrob("Prediction models: decrease and increase PA",
+# x = 0.02, y = 0.2, gp = grid::gpar(fontsize = title_text_size),
+# just = "left"
+# )
+# )
diff --git a/1 PA Decline/coef_plot_change_ARTICLEA.png b/1 PA Decline/coef_plot_change_ARTICLEA.png
new file mode 100644
index 0000000..6a1419c
Binary files /dev/null and b/1 PA Decline/coef_plot_change_ARTICLEA.png differ
diff --git a/1 PA Decline/coef_plot_change_ARTICLEA_facet.pdf b/1 PA Decline/coef_plot_change_ARTICLEA_facet.pdf
new file mode 100644
index 0000000..bb2f1a8
Binary files /dev/null and b/1 PA Decline/coef_plot_change_ARTICLEA_facet.pdf differ
diff --git a/1 PA Decline/coef_plot_change_ARTICLEA_facet.png b/1 PA Decline/coef_plot_change_ARTICLEA_facet.png
new file mode 100644
index 0000000..fe10eb4
Binary files /dev/null and b/1 PA Decline/coef_plot_change_ARTICLEA_facet.png differ
diff --git a/1 PA Decline/data_format.R b/1 PA Decline/data_format.R
new file mode 100644
index 0000000..e3f500e
--- /dev/null
+++ b/1 PA Decline/data_format.R
@@ -0,0 +1,50 @@
+## Article 1 outcome group definition script
+## To be enriched from Statistics Denmark
+##
+## Based on the ItMLiHSmar2022 course
+
+library(Hmisc)
+library(dplyr)
+# library(daDoctoR)
+library(tidyselect)
+
+# Setting final primary output from "pout"
+if (pout=="drop"){
+ X_tbl <- X_tbl|>
+ mutate(group=pase_drop_fac)
+
+ # print(quantile(as.numeric(X_tbl$pase_0)))
+ # print(quantile(as.numeric(X_tbl$pase_6)))
+ # print(summary(X_tbl$pase_0_cut))
+
+ X_tbl_f <- X_tbl|>
+ filter(pase_0_cut!=1)|>
+ select(-starts_with("pase_"))
+}
+
+if (pout=="hop"){
+ X_tbl <- X_tbl|>
+ mutate(group=pase_hop_fac)
+
+ # print(quantile(as.numeric(X_tbl$pase_0)))
+ # print(quantile(as.numeric(X_tbl$pase_6)))
+ # print(summary(X_tbl$pase_0_cut))
+
+ X_tbl_f <- X_tbl|>
+ filter(pase_6_cut!=1)|>
+ select(-starts_with("pase_"))
+}
+
+# Dropping non-complete for analysis
+Xy <- X_tbl_f|>
+ na.omit()|> # Keeping only complete observations
+ select(-c(tci) # Left out of model as no present in drop-group
+ )|>
+ mutate(mrs_0=factor(ifelse(mrs_0==1,1,2))) # Sets binary mRS 0 to include in glmnet, 0 or above
+
+label(Xy) = as.list(var.labels[match(names(Xy), names(var.labels))])
+
+X<-dplyr::select(Xy,-c(group, -starts_with("pase_")) # Exclude primary outcome
+ )
+y<-Xy$group
+
diff --git a/1 PA Decline/data_set.R b/1 PA Decline/data_set.R
new file mode 100644
index 0000000..7211a59
--- /dev/null
+++ b/1 PA Decline/data_set.R
@@ -0,0 +1,216 @@
+## Article 1 data set definition
+## To be enriched from Statistics Denmark
+##
+## Based on the ItMLiHSmar2022 course
+
+require(Hmisc)
+require(dplyr)
+# library(daDoctoR)
+require(tidyverse)
+require(patchwork)
+require(caret)
+require(glmnet)
+require(leaps)
+require(pROC)
+require(gt)
+require(gtsummary)
+require(glue)
+# library(ggdendro)
+require(corrplot)
+require(stRoke)
+
+## ====================================================================
+# Step 1: Import
+## ====================================================================
+
+if ("try-error" %in% class(t <- try(read.csv("/Volumes/Data/exercise/source/background.csv")))) {
+ export <-
+ read.csv(
+ "/Volumes/Data 1/exercise/source/background.csv",
+ colClasses = "character",
+ na.strings = c("NA", "", "unknown")
+ )
+} else if (!"try-error" %in% class(t)) {
+ export <-
+ read.csv(
+ "/Volumes/Data/exercise/source/background.csv",
+ colClasses = "character",
+ na.strings = c("NA", "", "unknown")
+ )
+}
+
+## ====================================================================
+# Step 2: Selection
+## ====================================================================
+
+
+export<-export[,c("pase_0",
+ "age",
+ "sex",
+ "civil",
+ "smoke_ever",
+ "smoker",
+ "rtreat",
+ "alc",
+ "afli",
+ "hypertension",
+ "diabetes",
+ "mrs_0",
+ "nihss_c",
+ "thrombolysis",
+ "pad",
+ "thrombechtomy",
+ "ami",
+ "tci",
+ "pase_6")]
+
+## ====================================================================
+# Step 3: Formatting variables
+## ====================================================================
+
+export$diabetes[is.na(export$diabetes)]<-"no"
+export$diabetes[is.na(export$hypertension)]<-"no"
+export$thrombolysis[is.na(export$thrombolysis)]<-"no"
+export$thrombechtomy[is.na(export$thrombechtomy)]<-"no"
+export$pad[is.na(export$pad)]<-"no"
+export$ami[is.na(export$ami)]<-"no"
+# export$smoker_prev <- ifelse(export$smoker=="3","yes","no")
+export$smoker <- ifelse(export$smoker=="1","yes","no")
+export$smoker[is.na(export$smoker)] <- "no"
+# export$mrs_0[export$mrs_0==3]<-NA
+
+dta <- export %>%
+ # as_tibble()%>%
+ mutate(any_rep=factor(ifelse(thrombolysis=="yes"|thrombechtomy=="yes","yes","no")), # If not noted, no therapy was received
+ male_sex= factor(ifelse(sex=="female","no","yes")),
+ # smoke_ever=factor(ifelse(smoke_ever=="never","no","yes")),
+ civil=factor(ifelse(civil=="partner","no","yes")), # Sets "yes" for not-cohabiting
+ rtreat=factor(ifelse(rtreat=="Placebo","no","yes")), # "Yes" receives active treatment
+ alc=factor(ifelse(alc=="more","yes","no")), # Yes for more than guideline
+ pase_0=as.numeric(pase_0),
+ pase_6=as.numeric(pase_6),
+ across(c("diabetes",
+ "hypertension",
+ "smoker",
+ "afli",
+ "pad",
+ "ami",
+ "tci",
+ "mrs_0"),as.factor),
+ across(c("nihss_c",
+ "age"),as.numeric )
+ )%>%
+ select(-c(sex))
+
+
+## ====================================================================
+# Step 4: Defining outcome
+## ====================================================================
+
+## Changed to step 7
+## This is to perform proper quantile split based on actually included.
+
+## ====================================================================
+# Step 5: Ordering variables
+## ====================================================================
+
+vars <- c("age",
+ "male_sex",
+ "civil",
+ "pase_0",
+ "smoker",
+ "alc",
+ "afli",
+ "hypertension",
+ "diabetes",
+ "pad",
+ "ami",
+ "tci",
+ "mrs_0",
+ "nihss_c",
+ "any_rep",
+ "rtreat",
+ "pase_6")
+
+dta<-dta[vars]
+
+## ====================================================================
+# Step 6: Labeling
+## ====================================================================
+
+var.labels = c(age="Age",
+ male_sex="Male",
+ civil="Living alone",
+ pase_0="Pre-stroke PASE score",
+ pase_6="Six month PASE score",
+ smoker="Daily or occasinally smoking",
+ alc="More alcohol than recommendation",
+ afli="AFIB",
+ hypertension="Hypertension",
+ diabetes="Diabetes",
+ pad="PAD",
+ ami="Previous MI",
+ tci="Previous TIA",
+ mrs_0="Pre-stroke mRS [-1]",
+ nihss_c="Acute NIHSS score",
+ thrombolysis="Acute thrombolysis",
+ thrombechtomy="Acute thrombechtomy",
+ any_rep="Any reperfusion therapy",
+ rtreat="Active trial treatment",
+ pase_drop_fac="PASE first quartile drop F",
+ pase_hop_fac="PASE first quartile hop F",
+ pase_0_cut="PASE 0 quartiles",
+ pase_6_cut="PASE 6 quartiles")
+
+
+
+## ====================================================================
+# Step 7: final data export
+## ====================================================================
+
+data_summary<-summary(dta)
+
+# Saving "old" factorised variables
+sel<-sapply(dta,is.factor)
+# Reformatting factors as 1/2 for analysis
+dta<-dta |>
+ mutate(across(where(is.factor), as.numeric))|> # Turning factors into 1(no) or 2(yes) for model. Numbered alphabetically.
+ mutate(across(matches(colnames(dta)[sel]), as.factor),
+ across(starts_with("pase_"), as.numeric))
+
+# Filtering out non-PASE
+X_tbl<-dta |>
+ filter(!is.na(pase_0),!is.na(pase_6))
+
+nrow(X_tbl)
+
+# Defining possible outcome meassures. Keeping in df for characterisation
+X_tbl <- X_tbl|>
+ mutate(## Relative decline
+ pase_diff=(pase_0-pase_6),
+ pase_decl_rel = pase_diff/pase_0*100,
+ # pase_decl_rel_fac=factor(ifelse(pase_decl_rel>=rel_dif,"yes","no")),
+ ## Absolute decline
+ # pase_decl_abs_fac=factor(ifelse(pase_diff>=abs_dif,"yes","no")),
+ ## Drop
+ pase_0_cut=quantile_cut(as.numeric(pase_0),
+ groups=4,
+ group.names = c(as.character(1:4)),
+ y=as.numeric(pase_0),
+ ordered.f = TRUE,
+ inc.outs = TRUE#,
+ # detail.lst=FALSE
+ ),
+ pase_6_cut=quantile_cut(as.numeric(pase_6),
+ groups=4,
+ group.names = c(as.character(1:4)),
+ y=as.numeric(pase_0),
+ ordered.f = TRUE,
+ inc.outs = TRUE#,
+ # detail.lst=FALSE
+ ),
+ pase_drop_fac=factor(ifelse(pase_6_cut==1&pase_0_cut!=1,"yes","no")),
+ pase_hop_fac=factor(ifelse(pase_6_cut!=1&pase_0_cut==1,"yes","no")))
+
+Hmisc::label(X_tbl) = as.list(var.labels[match(names(X_tbl), names(var.labels))])
+
diff --git a/1 PA Decline/dst import.R b/1 PA Decline/dst import.R
new file mode 100644
index 0000000..f54505c
--- /dev/null
+++ b/1 PA Decline/dst import.R
@@ -0,0 +1,83 @@
+#' Reads docx file and splits each table into list
+#'
+#' @param path file path
+#' @param data.type character vector. Could be "paragraph" or "table cell".
+#'
+#' @return
+#' @export
+#'
+#' @examples
+docx2ds <- function(path = here::here("data-raw/Deltagerliste Skirva 2024.docx"),
+ data.type = "table cell", verbose = TRUE) {
+ # Ref: https://www.r-bloggers.com/2020/07/how-to-read-and-create-word-documents-in-r/
+ doc <- officer::read_docx(path)
+
+ content <- doc |> officer::docx_summary()
+
+ if (verbose) {
+ message("Content types in the current document are as follows:")
+ print(content$content_type |> unique())
+ }
+
+ table_cells <- content |> dplyr::filter(content_type %in% data.type)
+
+ # .x <- split(table_cells, table_cells$doc_index)[[4]]
+
+ split(table_cells, table_cells$doc_index) |> purrr::map(function(.x) {
+ table_data <- .x |>
+ dplyr::filter(!is_header) |>
+ dplyr::select(row_id, cell_id, text)
+
+ # split data into individual columns
+ splits <- split(table_data, table_data$cell_id)
+ splits <- lapply(splits, function(.y) .y$text)
+ splits <- splits |>
+ purrr::keep(function(.y) length(.y)>1)
+
+ # If a footer has been added, it is considered part of the first column,
+ # and will result in unequal col lengths.
+ # This solution does not handle merged cells
+ col_lengths <- lengths(splits)
+
+ if (col_lengths[1] > col_lengths[2]){
+ splits[[1]] <- splits[[1]][seq_len(col_lengths[2])]
+ }
+
+ # combine columns back together in wide format
+ table_result <- splits |>
+ dplyr::bind_cols()
+
+ # get table headers
+ cols <- .x |> dplyr::filter(is_header)
+ names(table_result) <- cols$text
+ table_result
+ })
+}
+
+get_coefs <- function(path,
+ index.table = 1) {
+ data = docx2ds(
+ path = path
+ )
+
+ data |>
+ purrr::pluck(index.table) |>
+ setNames(c(
+ "variable",
+ lapply(c("drop", "hop"),
+ paste,
+ c("median", "mean"),
+ sep = "_"
+ ) |>
+ purrr::list_c()
+ )) |>
+ dplyr::select(variable, tidyselect::ends_with("median")) #|>
+ # dplyr::mutate(dplyr::across(tidyselect::ends_with("median"),~as.numeric))
+ # setNames(c("variable","decrease","increase"))
+}
+
+gtsummary2docx <- function(data, path) {
+ data |>
+ gtsummary::as_flex_table() |>
+ flextable::save_as_docx(path = path)
+}
diff --git a/1 PA Decline/flowchart.R b/1 PA Decline/flowchart.R
new file mode 100644
index 0000000..1edd0c9
--- /dev/null
+++ b/1 PA Decline/flowchart.R
@@ -0,0 +1,48 @@
+create_flowchart <- function(data, export.path = NULL) {
+ out <- data |>
+ dplyr::select(pase_0,pase_4) |>
+ dplyr::mutate(id= dplyr::row_number(),
+ exclude=is.na(pase_0)|is.na(pase_4),
+ exclude_reason=factor(dplyr::case_when(
+ is.na(pase_0) ~ "Pre-stroke PASE missing",
+ is.na(pase_4) ~"Post-stroke PASE missing"
+ ),levels=c( "Pre-stroke PASE missing","Post-stroke PASE missing")),
+ ) |>
+ consort::consort_plot(
+ orders = c(
+ id = "Complete TALOS cohort",
+ exclude_reason = "Excluded",
+ id = "Main dataset"
+ ),
+ side_box = c("exclude_reason"),
+ labels = c(
+ "1" = "Identification",
+ "2" = "Inclusion",
+ "3" = "Complete data"
+ )
+ )
+
+ if (!is.null(export.path)) {
+ out |> export_consort_dot(path = export.path)
+ } else {
+ plot(out)
+ }
+}
+
+source(here::here("2 Longterm/data.R"))
+# The original functions from DST unedited
+source(here::here("1 PA Decline/Fra DDV/functions200411.R"))
+source(here::here("1 PA Decline/Fra DDV/functions240418.R"))
+# Modified functions to overwrite original
+source(here::here("R/functions.R"))
+
+df <- df_ddv |>
+ dplyr::tibble() |>
+ dplyr::mutate_all(as.character) |>
+ ready_clin() |>
+ data_formatting()|>
+ get_vars(c("clin","lifestyle","ses", "assess.pred")) |>
+ dplyr::mutate(exclude=ifelse(is.na(pase_0)|is.na(pase_4),"Excluded","Included"),
+ age=as.numeric(age))
+
+df |> create_flowchart()
\ No newline at end of file
diff --git a/1 PA Decline/grouped table rows.docx b/1 PA Decline/grouped table rows.docx
new file mode 100644
index 0000000..cfbb133
Binary files /dev/null and b/1 PA Decline/grouped table rows.docx differ
diff --git a/1 PA Decline/grouped table rows.qmd b/1 PA Decline/grouped table rows.qmd
new file mode 100644
index 0000000..33ac41c
--- /dev/null
+++ b/1 PA Decline/grouped table rows.qmd
@@ -0,0 +1,59 @@
+---
+title: "nicer tables"
+format: docx
+editor: visual
+---
+
+## Tables
+
+```{r}
+library(gtsummary)
+library(dplyr)
+packageVersion("gtsummary")
+
+trial%>%
+ select(age, stage, grade)%>%
+ tbl_summary()%>%
+ modify_table_body(
+ ~.x %>%
+
+ # add your variable
+ rbind(
+ tibble(
+ variable="Demographics",
+ var_type=NA,
+ var_label = "Demographics",
+ row_type="label",
+ label="Demographics",
+ stat_0= NA))%>% # expand the components of the tibble as needed if you have more columns
+
+ # can add another one
+ rbind(
+ tibble(
+ variable="Tumor characteristics",
+ var_type=NA,
+ var_label = "Tumor characteristics",
+ row_type="label",
+ label="Tumor characteristics",
+ stat_0= NA))%>%
+
+ # specify the position you want these in
+
+ arrange(factor(variable, levels=c("Demographics",
+ "age",
+ "Tumor characteristics",
+ "stage",
+ "grade"))))%>%
+
+ # and you can then indent the actual variables
+ modify_column_indent(columns=label, rows=variable%in%c("age",
+ "stage",
+ "grade"))%>%
+
+ # and double indent their levels
+ modify_column_indent(columns=label, rows= (variable%in%c("stage",
+ "grade")
+ & row_type=="level"),
+ double_indent=T)
+
+```
diff --git a/1 PA Decline/regular_fun.R b/1 PA Decline/regular_fun.R
new file mode 100644
index 0000000..1b457b0
--- /dev/null
+++ b/1 PA Decline/regular_fun.R
@@ -0,0 +1,117 @@
+## ItMLiHSmar2022
+## regular_fun.R, child script
+## Regularisation model building function
+## Andreas Gammelgaard Damsbo, agdamsbo@clin.au.dk
+##
+## Now modified to use in publication
+##
+
+regular_fun<-function(X,y,K,lambdas,alpha){
+n<-nrow(X)
+set.seed(321)
+
+# Using caret function to ensure both levels represented in all folds
+c<-createFolds(y=y, k = K, list = FALSE, returnTrain = TRUE)
+
+B<-yhatTestProbKeep<-list()
+accTrain<-accTest<-err_train<-err_test<-auc_train<-auc_test<-matrix(nrow = K,ncol = length(lambdas))
+
+catinfo<-levels(y)
+
+cMatTrain<-cMatTest<-table(true=factor(c(0,0),levels=catinfo),pred=factor(c(0,0),levels=catinfo))
+
+
+## Iterate over partitions
+for (idx1 in 1:K){
+
+ # Status
+ cat('Processing fold', idx1, 'of', K,'\n')
+
+ # idx1=1
+ # Get training- and test sets
+ I_train = c!=idx1 ## Creating selection vector of TRUE/FALSE
+ I_test = !I_train
+
+ Xtrain = X[I_train,]
+ ytrain = y[I_train]
+ Xtest = X[I_test,]
+ ytest = y[I_test]
+
+
+ ## Model matrices for glmnet
+ ## Using the complicated approach not to include first level.
+ # Xmat.train<-model.matrix(~ .-1, data=Xtrain,
+ # contrasts.arg = lapply(Xtrain[,sapply(Xtrain, is.factor)],
+ # contrasts, contrasts=T))
+ # Xmat.test<-model.matrix(~ .-1, data=Xtest,
+ # contrasts.arg = lapply(Xtest[,sapply(Xtest, is.factor)],
+ # contrasts, contrasts=T))
+
+ # Xmat.train<-model.matrix(~.-1,Xtrain)
+ # Xmat.test<-model.matrix(~.-1,Xtest)
+
+ # Weights
+ ytrain_weight<-as.vector(1 - (table(ytrain)[ytrain] / length(ytrain)))
+ # ytest_weight<-as.vector(1 / (table(ytest)[ytest] / length(ytest)))
+
+ # Fit regularized linear regression model
+ mod<-glmnet(Xtrain, ytrain,
+ alpha = alpha, ## Alpha = 1 for lasso
+ lambda = lambdas, ## Setting lambdas
+ standardize = TRUE, ## Scales and centers
+ weights = ytrain_weight,
+ family = "binomial"
+ )
+
+ # Keep coefficients for plot
+ B[[idx1]] <- as.matrix(coef(mod))
+
+ # Iterate over regularization strengths to compute training- and test
+ # errors for individual regularization strengths.
+ for (idx2 in 1:length(lambdas)){
+ # idx2=1
+
+ # Predict
+ yhatTrainProb<-predict(mod,
+ s = lambdas[idx2],
+ newx = data.matrix(Xtrain),
+ type = "response"
+ )
+
+ yhatTestProb<-predict(mod,
+ s = lambdas[idx2],
+ newx = data.matrix(Xtest),
+ type = "response"
+ )
+
+ # Compute training and test error
+ yhatTrain = round(yhatTrainProb)
+ yhatTest = round(yhatTestProb)
+
+ # Make predictions categorical again (instead of 0/1 coding)
+ yhatTrainCat = factor(round(yhatTrainProb),levels=c("0","1"),labels=catinfo,ordered = TRUE)
+ yhatTestCat = factor(round(yhatTestProb),levels=c("0","1"),labels=catinfo,ordered = TRUE)
+
+ # Evaluate classifier performance
+ # Accuracy
+ # accTrain[idx1,idx2] <- sum(yhatTrainCat==ytrain)/length(ytrain)
+ # accTest [idx1,idx2] <- sum(yhatTestCat==ytest)/length(ytest)
+ # #
+ # # Error rate
+ # err_train[idx1,idx2] = 1 - accTrain[idx1,idx2]
+ # err_test [idx1,idx2] = 1 - accTest[idx1,idx2]
+
+ # AUROC
+ suppressMessages(
+ auc_train[idx1,idx2]<-auc(ytrain, yhatTrainCat))
+ suppressMessages(
+ auc_test [idx1,idx2]<-auc(ytest, yhatTestCat))
+
+ # Compute confusion matrices
+ cMatTrain = cMatTrain + table(true=ytrain,pred=yhatTrainCat)
+ cMatTest = cMatTest + table(true=ytest,pred=yhatTestCat)
+ }
+}
+ls<-list(mod=mod,B=B,auc_train=auc_train,auc_test=auc_test,cMatTrain=cMatTrain,cMatTest=cMatTest)
+return(ls)
+}
diff --git a/1 PA Decline/regularisation_steps.R b/1 PA Decline/regularisation_steps.R
new file mode 100644
index 0000000..bacd072
--- /dev/null
+++ b/1 PA Decline/regularisation_steps.R
@@ -0,0 +1,150 @@
+## ItMLiHSmar2022
+## regularisation_steps.R, child script
+## Regularised model building and analysation for assignment
+## Andreas Gammelgaard Damsbo, agdamsbo@clin.au.dk
+##
+## Now modified to use in publication
+##
+
+## ====================================================================
+## Step 0: data import and wrangling
+## ====================================================================
+
+setwd("/Users/au301842/PhysicalActivityandStrokeOutcome/1 PA Decline/")
+
+# source("data_format.R")
+y1<-factor(as.integer(y)-1) ## Outcome is required to be factor of 0 or 1.
+
+
+## ====================================================================
+## Step 1: settings
+## ====================================================================
+
+## Folds
+K=10
+set.seed(3)
+c<-caret::createFolds(y=y,
+ k = K,
+ list = FALSE,
+ returnTrain = TRUE) # Foldids for alpha tuning
+
+## Defining tuning parameters
+lambdas=2^seq(-10, 5, 1)
+alphas<-seq(0,1,.1)
+
+## Weights for models
+weighted=TRUE
+if (weighted == TRUE) {
+ wght<-as.vector(1 - (table(y)[y] / length(y)))
+} else {
+ wght <- rep(1, nrow(y))
+}
+
+
+## Standardise numeric
+## Centered and
+
+
+
+## ====================================================================
+## Step 2: all cross validations for each alpha
+## ====================================================================
+
+library(furrr)
+library(purrr)
+library(doMC)
+registerDoMC(cores=6)
+
+# Nested CVs with analysis for all lambdas for each alpha
+#
+set.seed(3)
+cvs <- future_map(alphas, function(a){
+ cv.glmnet(model.matrix(~.-1,X),
+ y1,
+ weights = wght,
+ lambda=lambdas,
+ type.measure = "deviance", # This is standard measure and recommended for tuning
+ foldid = c, # Per recommendation the folds are kept for alpha optimisation
+ alpha=a,
+ standardize=TRUE,
+ family=quasibinomial,
+ keep=TRUE) # Same as binomial, but not as picky
+})
+
+## ====================================================================
+# Step 3: optimum lambda for each alpha
+## ====================================================================
+
+
+# For each alpha, lambda is chosen for the lowest meassure (deviance)
+each_alpha <- sapply(seq_along(alphas), function(id) {
+ each_cv <- cvs[[id]]
+ alpha_val <- alphas[id]
+ index_lmin <- match(each_cv$lambda.min,
+ each_cv$lambda)
+ c(lamb = each_cv$lambda.min,
+ alph = alpha_val,
+ cvm = each_cv$cvm[index_lmin])
+})
+
+# Best lambda
+best_lamb <- min(each_alpha["lamb", ])
+
+# Alpha is chosen for best lambda with lowest model deviance, each_alpha["cvm",]
+best_alph <- each_alpha["alph",][each_alpha["cvm",]==min(each_alpha["cvm",]
+ [each_alpha["lamb",] %in% best_lamb])]
+
+## https://stackoverflow.com/questions/42007313/plot-an-roc-curve-in-r-with-ggplot2
+p_roc<-roc.glmnet(cvs[[1]]$fit.preval, newy = y)[[match(best_alph,alphas)]]|> # Plots performance from model with best alpha
+ ggplot(aes(FPR,TPR)) +
+ geom_step() +
+ coord_cartesian(xlim=c(0,1), ylim=c(0,1)) +
+ geom_abline()+
+ theme_bw()
+
+## ====================================================================
+# Step 4: Creating the final model
+## ====================================================================
+
+source("regular_fun.R") # Custom function
+optimised_model<-regular_fun(X,y1,K,lambdas=best_lamb,alpha=best_alph)
+# With lambda and alpha specified, the function is just a k-fold cross-validation wrapper,
+# but keeps model performance figures from each fold.
+
+list2env(optimised_model,.GlobalEnv)
+# Function outputs a list, which is unwrapped to Env.
+# See source script for reference.
+
+## ====================================================================
+# Step 5: creating table of coefficients for inference
+## ====================================================================
+
+Bmatrix<-matrix(unlist(B),ncol=10)
+Bmedian<-apply(Bmatrix,1,median)
+Bmean<-apply(Bmatrix,1,mean)
+
+reg_coef_tbl<-tibble(
+ name = c("Intercept",Hmisc::label(X)),
+ medianX = round(Bmedian,5),
+ ORmed = round(exp(Bmedian),5),
+ meanX = round(Bmean,5),
+ ORmea = round(exp(Bmean),5))%>%
+ # arrange(desc(abs(medianX)))%>%
+ gt()
+
+## ====================================================================
+# Step 6: plotting predictive performance
+## ====================================================================
+
+reg_cfm<-confusionMatrix(cMatTest)
+reg_auc_sum<-summary(auc_test[,1])
+
+## ====================================================================
+# Step 7: Packing list to save in loop
+## ====================================================================
+
+ls[[i]] <- list("RegularisedCoefs"=reg_coef_tbl,
+ "bestA"=best_alph,
+ "bestL"=best_lamb,
+ "ConfusionMatrx"=reg_cfm,
+ "AUROC"=reg_auc_sum)
diff --git a/1 PA Decline/repeated measures.R b/1 PA Decline/repeated measures.R
new file mode 100644
index 0000000..22f3df5
--- /dev/null
+++ b/1 PA Decline/repeated measures.R
@@ -0,0 +1,29 @@
+# ds <- readr::read_csv(here::here("/Volumes/Data/REDCap/DDV/talos_ddv.csv"))
+
+
+# Tun first 3 lines of code in 00_master.R
+
+# Label attributes are removed then pivoted to long
+df <- purrr::map(X_tbl,\(.x){
+ # browser()
+ class(.x) <- class(.x)[-1]
+ .x
+}) |>
+ dplyr::bind_cols() |>
+ dplyr::mutate(id=dplyr::row_number()) |>
+ dplyr::select(id,dplyr::everything()) |>
+ tidyr::pivot_longer(c("pase_0","pase_6"),names_to = "time",values_to = "pase") |>
+ dplyr::mutate(time = as.numeric(factor(time))-1)
+
+lme4::lmer(formula = pase~age+male_sex+hypertension+diabetes+nihss_c+(1|id),data = df) |>
+ gtsummary::tbl_regression()
+
+summary(df$male_sex)
+
+df |>
+ dplyr::mutate(dplyr::across(c("id","hypertension","diabetes","time"),\(.x)factor(.x)),
+ female=male_sex==1) |>
+ (\(.x){
+ mmrm::mmrm(formula = pase~age+female+hypertension+diabetes+nihss_c+us(time|id),data=.x)
+ })() |> gtsummary::tbl_regression()
+
diff --git a/1 PA Decline/sankey individual.R b/1 PA Decline/sankey individual.R
new file mode 100644
index 0000000..5b76cb6
--- /dev/null
+++ b/1 PA Decline/sankey individual.R
@@ -0,0 +1,56 @@
+ds <- readr::read_csv(here::here("/Volumes/Data/REDCap/DDV/talos_ddv.csv"))
+
+df_raw <- ds |>
+ dplyr::filter(!pase_score_missings_0, !pase_score_missings_4) |>
+ dplyr::transmute(
+ id = dplyr::row_number(),
+ pase_0 = pase_score_sum_0,
+ pase_4 = pase_score_sum_4,
+ pase_0_cut = as.numeric(stRoke::quantile_cut(
+ x = pase_0,
+ groups = 4,
+ group.names = paste0(1:4)
+ )),
+ pase_6_cut = as.numeric(stRoke::quantile_cut(
+ x = pase_4,
+ y = pase_0,
+ groups = 4,
+ inc.outs = TRUE,
+ group.names = paste0(1:4)
+ )),
+ pase_diff = pase_4 - pase_0,
+ pase_diff_rel = pase_diff / pase_0,
+ pase_0_rank = rank(pase_0, ties.method = "first"),
+ pase_4_rank = rank(pase_4, ties.method = "first"),
+ change = dplyr::case_when(
+ pase_0_cut %in% 2:4 & pase_6_cut == 1 ~ "drop",
+ pase_6_cut %in% 2:4 & pase_0_cut == 1 ~ "hop",
+ pase_0_cut %in% 2:4 & pase_6_cut %in% 2:4 ~ "hh",
+ pase_0_cut %in% 1 & pase_6_cut == 1 ~ "ll"
+ ),
+ change_any = factor(dplyr::case_when(
+ pase_6_cut > pase_0_cut ~ "hop",
+ pase_6_cut < pase_0_cut ~ "drop",
+ pase_0_cut %in% 2:4 & pase_6_cut %in% 2:4 ~ "hh",
+ pase_0_cut %in% 1 & pase_6_cut == 1 ~ "ll"
+ )),
+ change_rel = factor(dplyr::case_when(
+ pase_diff_rel > .5 ~ "hop",
+ pase_diff_rel < -.5 ~ "drop",
+ .default = "stat"
+ ))
+ )
+
+df_raw |> skimr::skim()
+
+df_long <- df_raw |>
+ dplyr::select(pase_0_rank, pase_4_rank, change_rel,id) |>
+ tidyr::pivot_longer(dplyr::starts_with("pase_"), names_to = "time", values_to = "pase")
+
+df_long <- df_raw |>
+ dplyr::select(pase_0, pase_4, change_rel,id) |>
+ tidyr::pivot_longer(dplyr::starts_with("pase_"), names_to = "time", values_to = "pase")
+
+ggplot(df_long, aes(x = time, y = pase,group=id,colour = change_rel)) +
+ geom_line()+
+ facet_wrap(~change_rel)
diff --git a/1 PA Decline/sankey.R b/1 PA Decline/sankey.R
new file mode 100644
index 0000000..996932a
--- /dev/null
+++ b/1 PA Decline/sankey.R
@@ -0,0 +1,155 @@
+
+# source("1 PA Decline/data_format.R")
+
+# NEW QUARTILES
+
+df <- X_tbl |> select(pase_0_cut,pase_6_cut)
+
+df$change <- factor(ifelse(
+ df$pase_0_cut %in% 2:4 & df$pase_6_cut == 1,
+ "drop",
+ ifelse(
+ df$pase_6_cut %in% 2:4 & df$pase_0_cut == 1,
+ "hop",
+ "no"
+ )))
+
+
+# Visuals - sankey
+# https://stackoverflow.com/questions/50395027/beautifying-sankey-alluvial-visualization-using-r
+
+
+## Painting
+
+df <- df |> count(pase_0_cut,pase_6_cut,change)
+
+
+lbs0 <-
+ c(
+ paste0("1st \n(n=", sum(df$n[df$pase_0_cut == "1"]), ")"),
+ paste0("2nd \n(n=", sum(df$n[df$pase_0_cut == "2"]), ")"),
+ paste0("3rd \n(n=", sum(df$n[df$pase_0_cut == "3"]), ")"),
+ paste0("4th \n(n=", sum(df$n[df$pase_0_cut == "4"]), ")")
+ )
+
+
+lbs6 <-
+ c(
+ paste0("1st \n(n=", sum(df$n[df$pase_6_cut == "1"]), ")"),
+ paste0("2nd \n(n=", sum(df$n[df$pase_6_cut == "2"]), ")"),
+ paste0("3rd \n(n=", sum(df$n[df$pase_6_cut == "3"]), ")"),
+ paste0("4th \n(n=", sum(df$n[df$pase_6_cut == "4"]), ")")
+ )
+
+
+levels(df$pase_0_cut)<-lbs0[1:length(levels(df$pase_0_cut))]
+levels(df$pase_6_cut)<-lbs6[1:length(levels(df$pase_6_cut))]
+
+df$pase_0_cut <- factor(df$pase_0_cut, levels=rev(levels(df$pase_0_cut)))
+df$pase_6_cut <- factor(df$pase_6_cut, levels=rev(levels(df$pase_6_cut)))
+
+df$change <- factor(df$change, levels=c("no", "drop", "hop"))
+
+
+hops <- "#66c1a3" # grey
+# drops <- "#990033" # Midtrød
+drops <- "#CE0045" #Lighter Midtrød
+nos <- "grey90" # Light grey
+
+# border <- "#00596B"
+# box <- "#008099"
+
+border <- "#EA571D"
+box <- "#1E4B66"
+
+
+cls <- c(nos, drops, hops)
+
+alpha <- 0.7
+
+library(ggalluvial)
+
+p_delta <- ggplot(df,aes(y = n, axis1 = pase_0_cut, axis2 = pase_6_cut)) +
+ geom_alluvium(
+ aes(fill = change, color = change),
+ width = 1 / 16,
+ alpha = alpha,
+ knot.pos = 0.4
+ ) +
+ geom_stratum(aes(size=10),width = 1 / 4,
+ fill = box,
+ color = border) +
+ geom_text(stat = "stratum", aes(label = after_stat(stratum)), colour = "white", size = 20) +
+ scale_x_continuous(breaks = 1:2,
+ labels = c("Pre-stroke\nquartile", "Six months\nquartile")) +
+ scale_fill_manual(values = cls) +
+ scale_color_manual(values = cls) +
+ ggtitle("Change in PA\nafter stroke")
+
+
+# plotly::ggplotly(p_delta)
+
+png(
+ filename = "sankey_change_PhDDay.png",
+ units = "mm",
+ width = 100,
+ height = 200,
+ pointsize = 15,
+ res = 300
+); p_delta +
+ theme_minimal() +
+ theme(
+ legend.position = "none",
+ panel.grid.major = element_blank(),
+ panel.grid.minor = element_blank(),
+ axis.text.y = element_blank(),
+ axis.title.y = element_blank(),
+ axis.text.x = element_text(size = 14, face = "bold"),
+ plot.title = element_text(hjust = 0.5, vjust = 1, size = 30, face = "bold")
+ ); dev.off()
+
+
+png(
+ filename = "sankey_change_PhDDay_min.png",
+ units = "mm",
+ width = 500,
+ height = 500,
+ pointsize = 15,
+ res = 300
+); p_delta+
+ theme_minimal() +
+ theme(
+ legend.position = "none",
+ panel.grid.major = element_blank(),
+ panel.grid.minor = element_blank(),
+ axis.text.y = element_blank(),
+ axis.title.y = element_blank(),
+ axis.text.x = element_blank(),
+ plot.title = element_blank(),
+ panel.background = element_rect(fill='transparent'),
+ plot.background = element_rect(fill='transparent', color=NA)
+ ); dev.off()
+
+
+
+png(
+ filename = "sankey_change_ESOC23.png",
+ units = "mm",
+ width = 500,
+ height = 500,
+ pointsize = 60,
+ res = 300
+); p_delta +
+ theme_minimal() +
+ theme(
+ legend.position = "none",
+ panel.grid.major = element_blank(),
+ panel.grid.minor = element_blank(),
+ axis.text.y = element_blank(),
+ axis.title.y = element_blank(),
+ axis.text.x = element_blank(),
+ plot.title = element_blank(),
+ panel.background = element_rect(fill='transparent'),
+ plot.background = element_rect(fill='transparent', color=NA)
+ ); dev.off()
+
diff --git a/1 PA Decline/sankey_change_ARTICLEA.pdf b/1 PA Decline/sankey_change_ARTICLEA.pdf
new file mode 100644
index 0000000..cef4536
Binary files /dev/null and b/1 PA Decline/sankey_change_ARTICLEA.pdf differ
diff --git a/1 PA Decline/sankey_change_ARTICLEA.png b/1 PA Decline/sankey_change_ARTICLEA.png
new file mode 100644
index 0000000..ab59c74
Binary files /dev/null and b/1 PA Decline/sankey_change_ARTICLEA.png differ
diff --git a/1 PA Decline/sankey_change_ARTICLEA_ejn.png b/1 PA Decline/sankey_change_ARTICLEA_ejn.png
new file mode 100644
index 0000000..2a86cd5
Binary files /dev/null and b/1 PA Decline/sankey_change_ARTICLEA_ejn.png differ
diff --git a/1 PA Decline/sankey_change_ESOC23.png b/1 PA Decline/sankey_change_ESOC23.png
new file mode 100644
index 0000000..a253ed9
Binary files /dev/null and b/1 PA Decline/sankey_change_ESOC23.png differ
diff --git a/1 PA Decline/sankey_change_PhDDay.png b/1 PA Decline/sankey_change_PhDDay.png
new file mode 100644
index 0000000..8af7c7c
Binary files /dev/null and b/1 PA Decline/sankey_change_PhDDay.png differ
diff --git a/1 PA Decline/sankey_change_PhDDay_min.png b/1 PA Decline/sankey_change_PhDDay_min.png
new file mode 100644
index 0000000..777debe
Binary files /dev/null and b/1 PA Decline/sankey_change_PhDDay_min.png differ
diff --git a/1 PA Decline/standardise.R b/1 PA Decline/standardise.R
new file mode 100644
index 0000000..2521e6d
--- /dev/null
+++ b/1 PA Decline/standardise.R
@@ -0,0 +1,41 @@
+## ItMLiHSmar2022
+## standardise.R, child script
+## Data standardisation, returns list
+## Andreas Gammelgaard Damsbo, agdamsbo@clin.au.dk
+
+standardise<-function(train,test,type){
+ # From:
+ # https://datascience.stackexchange.com/questions/13971/standardization-normalization-test-data-in-r
+
+ sel<-sapply(Xtrain,is.numeric) # Deciding which to stadardise (only numeric)
+ cnm<-colnames(Xtrain) # Saving column names for ordering
+
+ # Subsetting
+
+ ## Data to treat
+ train.tr<-train[,sel]
+ test.tr<-test[,sel]
+
+ ## Data to save
+ train.sv<-train[,!sel]
+ test.sv<-test[,!sel]
+
+ # Calculate mean and SD of train data
+ trainMean <- sapply(train.tr,mean)
+ trainSd <- sapply(train.tr,sd)
+
+ if (type=="c"){
+ ## centered
+ norm.trainData<-sweep(train.tr, 2L, trainMean) # using the default "-" to subtract mean column-wise
+ norm.testData<-sweep(test.tr, 2L, trainMean) # using the default "-" to subtract mean column-wise
+ }
+
+ if (type=="cs"){
+ ## centered AND scaled (Z-score standardisation)
+ norm.trainData<-sweep(sweep(train.tr, 2L, trainMean), 2, trainSd, "/")
+ norm.testData<-sweep(sweep(test.tr, 2L, trainMean), 2, trainSd, "/")
+ }
+ return(list(XtrainSt=cbind(norm.trainData,train.sv)[,cnm], # Reordering columns to original
+ XtestSt=cbind(norm.testData,test.sv)[,cnm]))
+}
+
diff --git a/1 PA Decline/summaries.qmd b/1 PA Decline/summaries.qmd
new file mode 100644
index 0000000..55fcfcd
--- /dev/null
+++ b/1 PA Decline/summaries.qmd
@@ -0,0 +1,109 @@
+---
+title: "Article A: Final renders"
+format: docx
+editor: visual
+---
+
+```{r}
+# ds <- readr::read_csv(here::here("/Volumes/Data/REDCap/DDV/talos_ddv.csv"))
+source(here::here("2 Longterm/data.R"))
+# The original functions from DST unedited
+source(here::here("1 PA Decline/Fra DDV/functions200411.R"))
+source(here::here("1 PA Decline/Fra DDV/functions240418.R"))
+# Modified functions to overwrite original
+source(here::here("R/functions.R"))
+```
+
+Files and resources used for article ready data:
+
+- "2 Longterm/data.R"
+
+- "R/functions240319.R"
+
+```{r}
+# ds |> finalfit::missing_plot()
+```
+
+On handling missings: https://finalfit.org/articles/missing.html
+
+```{r}
+# unique(df_long$variable)
+```
+
+```{r}
+pred_data <- df_ddv |>
+ dplyr::tibble() |>
+ dplyr::mutate_all(as.character) |>
+ ready_clin() |>
+ data_formatting() |>
+ prediction_ready() |>
+ dplyr::mutate(
+ dplyr::across(
+ c(
+ tidyselect::starts_with("pase_"),
+ "age"
+ ),
+ as.numeric
+ )
+ )
+
+pred_data |> labelling_data() |> readr::write_rds("labelled_test.rds")
+
+skimr::skim(pred_data)
+
+wilcox.test(pred_data$pase_0, pred_data$pase_4, paired = TRUE)
+```
+
+```{r}
+pred_data |>
+ true_pred_sum_plot() |>
+ gtsummary::as_gt() |>
+ # add_var_groups_gt()|>
+ gt::gtsave(filename = here::here("1 PA Decline/table1.docx"))
+system2("open",here::here("'1 PA Decline/table1.docx'"))
+# gtsummary2docx(path=here::here("1 PA Decline/table1.docx"))
+```
+
+```{r}
+pred_data |>
+ dplyr::mutate(reg_female = dplyr::if_else(reg_female, "Female", "Male")) |>
+ pase_cutter(drop.pase = FALSE) |>
+ dplyr::select(pase_change, dplyr::everything()) |>
+ summary_tblone(by = "reg_female", missing = "no") |>
+ gtsummary::modify_column_hide("stat_0") |>
+ gtsummary::add_p() |>
+ gtsummary::bold_p() |>
+ micRo::mask_micro_summary() |>
+ gtsummary::as_gt() |>
+ gt::gtsave(filename = here::here("1 PA Decline/table_bysex.docx"))
+```
+
+```{r}
+skimr::skim(pred_data)
+```
+
+## Excluded patients
+
+```{r}
+df_ddv |>
+ dplyr::tibble() |>
+ dplyr::mutate_all(as.character) |>
+ ready_clin() |>
+ data_formatting()|>
+ get_vars(c("clin","lifestyle","ses", "assess.pred")) |>
+ dplyr::mutate(exclude=ifelse(is.na(pase_0)|is.na(pase_4),"Excluded","Included"),
+ age=as.numeric(age),
+ pase_0=as.numeric(pase_0),
+ pase_4=as.numeric(pase_4)
+ )|>
+ # dplyr::select(-pase_0,-pase_4) |>
+ #dplyr::select(exclude,soc_status_nowork, fam_indk_hl, edu_level_hl)|>
+ gtsummary::tbl_summary(by=exclude, missing = "ifany") |>
+ gtsummary::add_p() |>
+ fix_labels() |>
+ gtsummary::as_gt() |>
+ gt::gtsave("1 PA Decline/summary_by_missing.docx")
+#|>
+ # mask_micro_summary(micro.n = 5)
+
+```
diff --git a/1 PA Decline/summary_by_missing.docx b/1 PA Decline/summary_by_missing.docx
new file mode 100644
index 0000000..3963638
Binary files /dev/null and b/1 PA Decline/summary_by_missing.docx differ
diff --git a/1 PA Decline/table mods.R b/1 PA Decline/table mods.R
new file mode 100644
index 0000000..31907ca
--- /dev/null
+++ b/1 PA Decline/table mods.R
@@ -0,0 +1,41 @@
+source(here::here("1 PA Decline/dst import.R"))
+ls_tbl <- docx2ds(
+ path = "/Users/au301842/Library/CloudStorage/OneDrive-Personal/Research/PhD/1 Change in PA/Manuscript/Manuscript_Change in PA_v2_10_IJS.docx"
+)
+
+ls <- ls_tbl |> purrr::pluck(3) |>
+ (\(.x){
+ .x[-c(1:3,nrow(.x)),]
+ })()
+
+ls |> setNames(1:5) |>
+ dplyr::mutate(dplyr::across(2:5,as.numeric)) |>
+ gt::gt() |> gt::fmt_number(n_sigfig=3) |> gt::gtsave("modtable3.docx")
+
+
+
+ls |> setNames(1:5) |>
+ dplyr::mutate(dplyr::across(2:5, \(.x){
+ as.character(sprintf('%#.3g', as.numeric(.x)))
+ })) |> kableExtra::kable()
+
+
+## Splitting by leveled variables (expanded view with all levels)
+n <- 0
+for (i in seq_len(nrow(ls))){
+ if (ls[[2]][i]!=""){
+ n[i]<-n[length(n)]+1
+ } else {
+ n[i] <- n[length(n)]
+ }
+}
+
+split(ls,n) |> lapply(function(.x){
+
+ if (" TRUE" %in% .x[[1]]){
+ cbind(.x[1,1:2],.x[3,3:5],.x[1,6],.x[3,7:9])
+ } else {
+ .x
+ }
+}) |> dplyr::bind_rows() |>
+ gt::gt()
\ No newline at end of file
diff --git a/1 PA Decline/table1.RTF b/1 PA Decline/table1.RTF
new file mode 100644
index 0000000..8257551
--- /dev/null
+++ b/1 PA Decline/table1.RTF
@@ -0,0 +1,715 @@
+{\rtf\ansi\ansicpg1252{\fonttbl{\f0\froman\fcharset0\fprq0 Courier New;}{\f1\froman\fcharset0\fprq0 Times;}}{\colortbl;\red211\green211\blue211;}
+
+\paperw12240\paperh15840\widowctrl\ftnbj\fet0\sectd\linex0
+\lndscpsxn
+\margl1440\margr1440\margt1440\margb1440
+\headery720\footery720\fs20
+
+\trowd\trrh0\trhdr
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf1 \cellx1337
+\intbl {\f0 {\f0\fs20 {\b Characteristic}}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf1 \cellx2674
+\intbl {\f0 {\f0\fs20 {\b N}}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf1 \cellx4011
+\intbl {\f0 {\f0\fs20 {\b Overall}, N = 522{\super \i 1}}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf1 \cellx5348
+\intbl {\f0 {\f0\fs20 {\b [0,84.7]}, N = 131{\super \i 1}}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf1 \cellx6685
+\intbl {\f0 {\f0\fs20 {\b (84.7,137]}, N = 130{\super \i 1}}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf1 \cellx8022
+\intbl {\f0 {\f0\fs20 {\b (137,202]}, N = 130{\super \i 1}}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf1 \cellx9359
+\intbl {\f0 {\f0\fs20 {\b (202,574]}, N = 131{\super \i 1}}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 Age}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 522}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 N}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 522}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 131}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 130}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 130}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 131}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 Median (IQR)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 68 (59, 76)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 75 (67, 80)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 71 (65, 77)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 67 (56, 75)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 60 (52, 68)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 Range}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 19, 99}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 19, 99}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 31, 89}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 24, 90}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 33, 85}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 Mean (SD)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 67 (13)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 73 (11)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 70 (11)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 65 (13)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 60 (11)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 Male}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 522}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 342 (66%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 67 (51%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 82 (63%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 86 (66%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 107 (82%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 Living alone}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 515}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 170 (33%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 63 (48%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 41 (32%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 36 (28%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 30 (24%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 Daily or occasinally smoking}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 522}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 164 (31%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 45 (34%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 40 (31%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 44 (34%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 35 (27%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 More alcohol than recommendation}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 509}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 47 (9.2%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 13 (10%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 12 (9.4%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 12 (9.3%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 10 (8.1%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 AFIB}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 517}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 81 (16%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 24 (18%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 24 (19%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 18 (14%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 15 (12%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 Hypertension}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 518}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 265 (51%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 81 (62%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 76 (58%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 60 (47%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 48 (38%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 Diabetes}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 522}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 57 (11%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 20 (15%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 16 (12%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 9 (6.9%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 12 (9.2%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 PAD}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 522}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 21 (4.0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 9 (6.9%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 5 (3.8%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 4 (3.1%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 3 (2.3%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 Previous MI}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 522}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 41 (7.9%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 8 (6.1%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 15 (12%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 9 (6.9%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 9 (6.9%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 Previous TIA}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 516}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 13 (2.5%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 3 (2.3%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 5 (3.8%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 4 (3.1%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 1 (0.8%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 Pre-stroke mRS [-1]}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 522}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 1}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 434 (83%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 86 (66%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 110 (85%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 115 (88%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 123 (94%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 2}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 54 (10%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 22 (17%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 13 (10%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 13 (10%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 6 (4.6%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 3}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 27 (5.2%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 17 (13%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 6 (4.6%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 2 (1.5%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 2 (1.5%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 4}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 7 (1.3%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 6 (4.6%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 1 (0.8%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 0 (0%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 Acute NIHSS score}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 518}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 N}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 518}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 130}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 130}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 128}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 130}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 Median (IQR)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 3.0 (2.0, 5.0)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 3.0 (2.0, 5.8)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 3.0 (2.0, 5.8)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 3.0 (2.0, 5.0)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 3.0 (1.0, 5.8)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 Range}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 0.0, 32.0}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 0.0, 24.0}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 0.0, 23.0}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 0.0, 16.0}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 0.0, 32.0}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 Mean (SD)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 4.6 (4.6)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 5.0 (5.3)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 4.5 (4.2)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 4.1 (3.6)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 4.5 (5.1)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 Any reperfusion therapy}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 522}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 197 (38%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 46 (35%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 48 (37%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 49 (38%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 54 (41%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1337
+\intbl {\f0 {\f0\fs20 Active trial treatment}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2674
+\intbl {\f0 {\f0\fs20 522}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4011
+\intbl {\f0 {\f0\fs20 253 (48%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5348
+\intbl {\f0 {\f0\fs20 63 (48%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6685
+\intbl {\f0 {\f0\fs20 64 (49%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8022
+\intbl {\f0 {\f0\fs20 61 (47%)}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 65 (50%)}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9359
+\intbl {\f0 {\f0\fs20 {\super \i 1}n (%)}}\cell
+
+\row
+
+}
diff --git a/1 PA Decline/table1.docx b/1 PA Decline/table1.docx
new file mode 100644
index 0000000..cc7ba99
Binary files /dev/null and b/1 PA Decline/table1.docx differ
diff --git a/1 PA Decline/table2.RTF b/1 PA Decline/table2.RTF
new file mode 100644
index 0000000..bf407fd
--- /dev/null
+++ b/1 PA Decline/table2.RTF
@@ -0,0 +1,542 @@
+{\rtf\ansi\ansicpg1252{\fonttbl{\f0\froman\fcharset0\fprq0 Courier New;}{\f1\froman\fcharset0\fprq0 Times;}}{\colortbl;\red51\green51\blue51;\red211\green211\blue211;}
+
+\paperw12240\paperh15840\widowctrl\ftnbj\fet0\sectd\linex0
+\lndscpsxn
+\margl1440\margr1440\margt1440\margb1440
+\headery720\footery720\fs20
+
+\trowd\trrh0\trhdr
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0\cf1 {\f0\fs20 Model coefficients} {\f0\fs20\i\super } \line {\f0\fs20 Combined table of both full and regularised model coefficients} {\f0\fs20\i\super }}\cell
+
+\row
+
+\trowd\trrh0\trhdr
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1040
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2\clmgf \cellx2080
+\intbl {\f0 {\f0\fs20 DROP}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clmrg \cellx3120
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clmrg \cellx4160
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clmrg \cellx5200
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2\clmgf \cellx6240
+\intbl {\f0 {\f0\fs20 HOP}}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clmrg \cellx7280
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clmrg \cellx8320
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clmrg \cellx9360
+\intbl {\f0 {\f0\fs20 }}\cell
+
+\row
+
+\trowd\trrh0\trhdr
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx1040
+\intbl {\f0 {\f0\fs20 name}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx2080
+\intbl {\f0 {\f0\fs20 medianX.x}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx3120
+\intbl {\f0 {\f0\fs20 ORmed.x}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx4160
+\intbl {\f0 {\f0\fs20 meanX.x}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx5200
+\intbl {\f0 {\f0\fs20 ORmea.x}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx6240
+\intbl {\f0 {\f0\fs20 medianX.y}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx7280
+\intbl {\f0 {\f0\fs20 ORmed.y}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx8320
+\intbl {\f0 {\f0\fs20 meanX.y}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx9360
+\intbl {\f0 {\f0\fs20 ORmea.y}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1040
+\intbl {\f0 {\f0\fs20 Intercept}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2080
+\intbl {\f0 {\f0\fs20 -3.732}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 0.024}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4160
+\intbl {\f0 {\f0\fs20 -3.773}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5200
+\intbl {\f0 {\f0\fs20 0.023}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 -4.636}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7280
+\intbl {\f0 {\f0\fs20 0.010}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8320
+\intbl {\f0 {\f0\fs20 -4.777}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.008}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1040
+\intbl {\f0 {\f0\fs20 Age}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2080
+\intbl {\f0 {\f0\fs20 0.025}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 1.026}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4160
+\intbl {\f0 {\f0\fs20 0.027}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5200
+\intbl {\f0 {\f0\fs20 1.027}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.046}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7280
+\intbl {\f0 {\f0\fs20 1.047}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8320
+\intbl {\f0 {\f0\fs20 0.049}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 1.050}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1040
+\intbl {\f0 {\f0\fs20 Male}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2080
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4160
+\intbl {\f0 {\f0\fs20 -0.023}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5200
+\intbl {\f0 {\f0\fs20 0.977}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 -0.271}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7280
+\intbl {\f0 {\f0\fs20 0.763}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8320
+\intbl {\f0 {\f0\fs20 -0.331}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.718}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1040
+\intbl {\f0 {\f0\fs20 Living alone}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2080
+\intbl {\f0 {\f0\fs20 0.884}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 2.422}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4160
+\intbl {\f0 {\f0\fs20 0.888}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5200
+\intbl {\f0 {\f0\fs20 2.431}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.325}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7280
+\intbl {\f0 {\f0\fs20 1.384}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8320
+\intbl {\f0 {\f0\fs20 0.329}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 1.390}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1040
+\intbl {\f0 {\f0\fs20 Daily or occasinally smoking}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2080
+\intbl {\f0 {\f0\fs20 0.156}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 1.169}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4160
+\intbl {\f0 {\f0\fs20 0.161}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5200
+\intbl {\f0 {\f0\fs20 1.175}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7280
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8320
+\intbl {\f0 {\f0\fs20 -0.001}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.999}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1040
+\intbl {\f0 {\f0\fs20 More alcohol than recommendation}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2080
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4160
+\intbl {\f0 {\f0\fs20 0.004}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5200
+\intbl {\f0 {\f0\fs20 1.004}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.247}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7280
+\intbl {\f0 {\f0\fs20 1.280}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8320
+\intbl {\f0 {\f0\fs20 0.298}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 1.347}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1040
+\intbl {\f0 {\f0\fs20 AFIB}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2080
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4160
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5200
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.015}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7280
+\intbl {\f0 {\f0\fs20 1.015}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8320
+\intbl {\f0 {\f0\fs20 0.050}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 1.051}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1040
+\intbl {\f0 {\f0\fs20 Hypertension}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2080
+\intbl {\f0 {\f0\fs20 0.083}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 1.086}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4160
+\intbl {\f0 {\f0\fs20 0.100}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5200
+\intbl {\f0 {\f0\fs20 1.105}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.005}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7280
+\intbl {\f0 {\f0\fs20 1.005}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8320
+\intbl {\f0 {\f0\fs20 0.044}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 1.045}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1040
+\intbl {\f0 {\f0\fs20 Diabetes}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2080
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4160
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5200
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.110}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7280
+\intbl {\f0 {\f0\fs20 1.116}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8320
+\intbl {\f0 {\f0\fs20 0.165}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 1.179}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1040
+\intbl {\f0 {\f0\fs20 PAD}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2080
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4160
+\intbl {\f0 {\f0\fs20 0.005}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5200
+\intbl {\f0 {\f0\fs20 1.005}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.211}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7280
+\intbl {\f0 {\f0\fs20 1.235}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8320
+\intbl {\f0 {\f0\fs20 0.231}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 1.260}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1040
+\intbl {\f0 {\f0\fs20 Previous MI}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2080
+\intbl {\f0 {\f0\fs20 0.047}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 1.049}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4160
+\intbl {\f0 {\f0\fs20 0.062}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5200
+\intbl {\f0 {\f0\fs20 1.064}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7280
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8320
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1040
+\intbl {\f0 {\f0\fs20 Pre-stroke mRS [-1]}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2080
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4160
+\intbl {\f0 {\f0\fs20 0.020}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5200
+\intbl {\f0 {\f0\fs20 1.020}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.605}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7280
+\intbl {\f0 {\f0\fs20 1.832}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8320
+\intbl {\f0 {\f0\fs20 0.590}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 1.803}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1040
+\intbl {\f0 {\f0\fs20 Acute NIHSS score}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2080
+\intbl {\f0 {\f0\fs20 0.033}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 1.034}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4160
+\intbl {\f0 {\f0\fs20 0.037}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5200
+\intbl {\f0 {\f0\fs20 1.037}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7280
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8320
+\intbl {\f0 {\f0\fs20 0.001}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 1.001}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1040
+\intbl {\f0 {\f0\fs20 Any reperfusion therapy}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2080
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4160
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5200
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7280
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8320
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx1040
+\intbl {\f0 {\f0\fs20 Active trial treatment}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx2080
+\intbl {\f0 {\f0\fs20 0.062}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 1.064}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx4160
+\intbl {\f0 {\f0\fs20 0.106}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx5200
+\intbl {\f0 {\f0\fs20 1.111}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx7280
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx8320
+\intbl {\f0 {\f0\fs20 0.000}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 1.000}}\cell
+
+\row
+
+}
diff --git a/1 PA Decline/table3.RTF b/1 PA Decline/table3.RTF
new file mode 100644
index 0000000..1d42d2f
--- /dev/null
+++ b/1 PA Decline/table3.RTF
@@ -0,0 +1,184 @@
+{\rtf\ansi\ansicpg1252{\fonttbl{\f0\froman\fcharset0\fprq0 Courier New;}{\f1\froman\fcharset0\fprq0 Times;}}{\colortbl;\red51\green51\blue51;\red211\green211\blue211;}
+
+\paperw12240\paperh15840\widowctrl\ftnbj\fet0\sectd\linex0
+\lndscpsxn
+\margl1440\margr1440\margt1440\margb1440
+\headery720\footery720\fs20
+
+\trowd\trrh0\trhdr
+
+\pard\plain\uc0\qc\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0\cf1 {\f0\fs20 Performance meassures} {\f0\fs20\i\super } \line {\f0\fs20 Combined table of both drop and hop} {\f0\fs20\i\super }}\cell
+
+\row
+
+\trowd\trrh0\trhdr
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx3120
+\intbl {\f0 {\f0\fs20 Meassure}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx6240
+\intbl {\f0 {\f0\fs20 Drop}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85\clbrdrb\brdrs\brdrw20\brdrcf2 \cellx9360
+\intbl {\f0 {\f0\fs20 Hop}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Sensitivity}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.862}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.882}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Specificity}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.290}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.246}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Pos Pred Value}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.712}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.660}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Neg Pred Value}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.507}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.557}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Precision}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.712}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.660}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Recall}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.862}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.882}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 F1}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.780}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.755}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Prevalence}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.671}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.624}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Detection Rate}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.578}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.550}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Detection Prevalence}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.812}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.834}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Balanced Accuracy}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.576}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.564}}\cell
+
+\row
+
+\trowd\trrh0
+
+\pard\plain\uc0\ql\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx3120
+\intbl {\f0 {\f0\fs20 Mean AUC}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx6240
+\intbl {\f0 {\f0\fs20 0.607}}\cell
+
+\pard\plain\uc0\qr\clvertalc \clpadfl3\clpadl25 \clpadft3\clpadt85 \clpadfb3\clpadb25 \clpadfr3\clpadr85 \cellx9360
+\intbl {\f0 {\f0\fs20 0.606}}\cell
+
+\row
+
+}
diff --git a/1 PA Decline/table_bysex.docx b/1 PA Decline/table_bysex.docx
new file mode 100644
index 0000000..0c4a477
Binary files /dev/null and b/1 PA Decline/table_bysex.docx differ
diff --git a/2 Longterm/.DS_Store b/2 Longterm/.DS_Store
new file mode 100644
index 0000000..0285727
Binary files /dev/null and b/2 Longterm/.DS_Store differ
diff --git a/2 Longterm/260315/_targets.R b/2 Longterm/260315/_targets.R
new file mode 100755
index 0000000..b336018
--- /dev/null
+++ b/2 Longterm/260315/_targets.R
@@ -0,0 +1,285 @@
+# Created by use_targets().
+# Follow the comments below to fill in this target script.
+# Then follow the manual to check and run the pipeline:
+# https://books.ropensci.org/targets/walkthrough.html#inspect-the-pipeline
+
+# Load packages required to define the pipeline:
+library(targets)
+library(tarchetypes) # Load other packages as needed.
+
+# Set target options:
+tar_option_set(
+ seed = 142,
+ packages = c("tibble"), # packages that your targets need to run
+ format = "qs" # , # Optionally set the default storage format. qs is fast.
+ #
+ # For distributed computing in tar_make(), supply a {crew} controller
+ # as discussed at https://books.ropensci.org/targets/crew.html.
+ # Choose a controller that suits your needs. For example, the following
+ # sets a controller with 2 workers which will run as local R processes:
+ #
+ # controller = crew::crew_controller_local(workers = 2)
+ #
+ # Alternatively, if you want workers to run on a high-performance computing
+ # cluster, select a controller from the {crew.cluster} package. The following
+ # example is a controller for Sun Grid Engine (SGE).
+ #
+ # controller = crew.cluster::crew_controller_sge(
+ # workers = 50,
+ # # Many clusters install R as an environment module, and you can load it
+ # # with the script_lines argument. To select a specific verison of R,
+ # # you may need to include a version string, e.g. "module load R/4.3.0".
+ # # Check with your system administrator if you are unsure.
+ # script_lines = "module load R"
+ # )
+ #
+ # Set other options as needed.
+)
+
+# tar_make_clustermq() is an older (pre-{crew}) way to do distributed computing
+# in {targets}, and its configuration for your machine is below.
+options(clustermq.scheduler = "multiprocess")
+
+# tar_make_future() is an older (pre-{crew}) way to do distributed computing
+# in {targets}, and its configuration for your machine is below.
+future::plan(future.callr::callr)
+
+# Run the R scripts in the R/ folder with your custom functions:
+tar_source()
+source(here::here("R/glmnet-reg.R")) # Source other scripts as needed.
+
+# Replace the target list below with your own:
+list(
+ tar_target(
+ name = pop_df,
+ command = get_clinical()
+ ),
+ tar_target(
+ name = reg_list,
+ command = get_reg_ls()
+ ),
+ tar_target(
+ name = df_deaths,
+ command = get_deaths(reg_list)
+ ),
+ tar_target(
+ name = df_events,
+ command = get_events(reg_list)
+ ),
+ tar_target(
+ name = df_events_deaths,
+ command = merge_events(list(events = df_events, deaths = df_deaths, clinical = pop_df))
+ ),
+ tar_target(
+ name = df_treated,
+ command = get_treated(reg_list)
+ ),
+ tar_target(
+ name = df_dst,
+ command = get_dst(reg_list, pop_df)
+ ),
+ tar_target(
+ name = list_filtered,
+ command = list(all_events = df_events_deaths, clinical = pop_df, dst = df_dst)
+ ),
+ tar_target(
+ name = df_all_data,
+ command = collectall(list_filtered)
+ ),
+ tar_target(
+ name = df_all_data_formatted,
+ command = data_formatting(df_all_data)
+ ),
+ tar_target(
+ name = ls_all_events,
+ command = all_events(list(events = df_events, deaths = df_deaths, clinical = pop_df))
+ ),
+ tar_target(
+ name = df_event_data,
+ command = events_ready(df_all_data_formatted)
+ ),
+ tar_target(
+ name = df_talos_data,
+ command = talos_ready(df_all_data_formatted)
+ ),
+ tar_target(
+ name = df_talos_data_imp,
+ command = talos_imp(df_talos_data)
+ ),
+ tar_target(
+ name = tbl_events_summary,
+ command = events_tblone(df_event_data)
+ ),
+ tar_target(
+ name = tbl_events_cox_regression,
+ command = show_table_regression(df_event_data, use.mice = FALSE)
+ ),
+ tar_target(
+ name = tbl_events_cox_regression_uv,
+ command = uv_cox_table(df_event_data)
+ ),
+ tar_target(
+ name = df_event_data_small,
+ command = events_ready_small(df_all_data_formatted)
+ ),
+ tar_target(
+ name = tbl_events_summary_small,
+ command = events_tblone(df_event_data_small)
+ ),
+ tar_target(
+ name = tbl_events_cox_regression_small,
+ command = show_table_regression(df_event_data_small, use.mice = FALSE)
+ ),
+ tar_target(
+ name = df_events_mids,
+ command = events_dataset(df_event_data, impute = TRUE)
+ ),
+ tar_target(
+ name = df_events_complete,
+ command = complete_preds_data(df_event_data)
+ ),
+ tar_target(
+ name = tbl_events_mids_cox_regression,
+ command = show_table_regression(df_event_data, use.mice = TRUE)
+ ),
+ tar_target(
+ name = plot_events_survival_smooth,
+ command = df_event_data |> events_dataset(impute = FALSE) |> cox_regression(include_formula=TRUE) |> plot_survival_smooth()
+ )#,
+ # tar_target(
+ # name = plot_events_survival_smooth_mids,
+ # command = df_events_mids |> cox_regression() |> plot_survival_smooth()
+ # ),
+ # tar_target(
+ # name = df_pred_data,
+ # command = prediction_ready(df_all_data_formatted)
+ # ),
+ # tar_target(
+ # name = tbl_pred_summary,
+ # command = preds_tblone(df_pred_data)
+ # ),
+ # tar_target(
+ # name = tbl_pred_summary_true,
+ # command = df_pred_data |>
+ # dplyr::select(pase_0, pase_4, soc_status_nowork, fam_indk_hl, edu_level_hl) |>
+ # true_pred_sum_plot()
+ # ),
+ # tar_target(
+ # name = tbl_pred_summary_exp,
+ # command = df_pred_data |>
+ # dplyr::select(pase_0, pase_4, soc_status_nowork, fam_indk_hl, edu_level_hl) |>
+ # preds_tblone()
+ # ),
+ # tar_target(
+ # name = tbl_pred_summary_exp_sex,
+ # command = df_pred_data |>
+ # dplyr::select(reg_female, soc_status_nowork, fam_indk_hl, edu_level_hl) |>
+ # summary_tblone()
+ # ),
+ # tar_target(
+ # name = tbl_pred_summary_exp_pase,
+ # command = df_pred_data |> sum_pase_tables()
+ # ),
+ # tar_target(
+ # name = tbl_pred_summary_exp_missing_edu,
+ # command = df_pred_data |>
+ # dplyr::select(age,reg_female, reg_trombolyse, reg_trombektomi, reg_hyperten, reg_diabetes, nihss_0, pase_0, pase_4, soc_status_nowork, fam_indk_hl, edu_level_hl) |>
+ # who_is_missing(var="edu_level_hl")
+ # ),
+ # tar_target(
+ # name = tbl_pred_summary_exp_missing_bmi,
+ # command = df_pred_data |>
+ # dplyr::select(age,reg_female, reg_trombolyse, reg_trombektomi, reg_hyperten, reg_diabetes, nihss_0, pase_0, pase_4, reg_bmi, soc_status_nowork, fam_indk_hl, edu_level_hl) |>
+ # who_is_missing(var="reg_bmi")
+ # ),
+ # tar_target(
+ # name = ls_pred_models,
+ # command = pred_models(df_pred_data,auto.l = TRUE,weighted = FALSE)
+ # ),
+ # tar_target(
+ # name = ls_pred_models_anyupdown,
+ # command = pred_models(df_pred_data,auto.l = TRUE,weighted = FALSE,split.type="anyupdown")
+ # ),
+ # tar_target(
+ # name = ls_pred_models_relupdown_20,
+ # command = pred_models(df_pred_data,auto.l = TRUE,weighted = FALSE,split.type="relupdown",rel.bin=20)
+ # ),
+ # tar_target(
+ # name = ls_pred_models_relupdown_50,
+ # command = pred_models(df_pred_data,auto.l = TRUE,weighted = FALSE,split.type="relupdown",rel.bin=50)
+ # ),
+ # tar_target(
+ # name = df_pred_mids,
+ # command = fun_impute(data = df_pred_data, outcome.vars = c("pase_0", "pase_4"))
+ # ),
+ # tar_target(
+ # name = ls_pred_mids_reg,
+ # command = mids_regularisation(df_pred_mids)
+ # ),
+ # tar_target(
+ # name = ls_pred_mids_reg_anyupdown,
+ # command = mids_regularisation(df_pred_mids,split.type="anyupdown")
+ # ),
+ # tar_target(
+ # name = ls_pred_mids_reg_relupdown_20,
+ # command = mids_regularisation(df_pred_mids,split.type="relupdown",rel.bin=20)
+ # ),
+ # tar_target(
+ # name = ls_pred_mids_reg_relupdown_50,
+ # command = mids_regularisation(df_pred_mids,split.type="relupdown",rel.bin=50)
+ # ),
+ # tar_target(
+ # name = ls_pred_summary,
+ # command = multi_summary(ls_pred_models)
+ # ),
+ # tar_target(
+ # name = ls_pred_mids_summary,
+ # command = multi_summary(ls_pred_mids_reg)
+ # ),
+ # tar_target(
+ # name = tbl_preds_log_reg,
+ # command = pred_log_reg(df_pred_data)
+ # ),
+ # tar_target(
+ # name = tbl_preds_lin_reg,
+ # command = pred_lin_reg(df_pred_data)
+ # ),
+ # tar_target(
+ # name = tbl_preds_lin_imp_reg,
+ # command = pred_lin_reg(df_pred_mids)
+ # ),
+ # tar_target(
+ # name = list_pred_clusters,
+ # command = get_clusters(df_events_complete,rm.out = TRUE)
+ # ),
+ # tar_target(
+ # name = list_pred_clusters_seq,
+ # command = get_clusters(df_events_complete,n.cl=4)
+ # )#,
+ # tar_target(
+ # name = list_df_multi_grouping,
+ # command = multi_grouping_df_list(df_all_data_formatted,args.list=df_mega_list())
+ # ),
+ # tar_target(
+ # name = list_multi_group_results,
+ # command = multi_results_list(list_df_multi_grouping)
+ # ),
+ # tar_target(
+ # name = list_multi_group_results_direct,
+ # command = df_all_data_formatted |> multi_grouping_df_list(args.list=df_mega_list()) |> multi_cox_performance_test()
+ # )
+
+
+ #,
+ # tar_quarto(
+ # name = report,
+ # path = "index.qmd"
+ # ),
+ # tar_target(
+ # name = pa_change_export_files,
+ # command = quarto::quarto_render(here::here("doc/pa_change.qmd"), output_format = "docx")
+ # )
+)
+
+## TODO
+## - modify pipeline to only perform imputation once and have the rest use this single object.
diff --git a/2 Longterm/260315/alternative_grouping.R b/2 Longterm/260315/alternative_grouping.R
new file mode 100755
index 0000000..c89a971
--- /dev/null
+++ b/2 Longterm/260315/alternative_grouping.R
@@ -0,0 +1,268 @@
+source("R/functions.R")
+
+### FUNCTIONALISE --> DONE
+
+df <- targets::tar_read(df_all_data_formatted) |>
+ group_format(binning.fun = bin_anyupdown) |>
+ dplyr::mutate(pase_change = factor(pase_change, levels = c("high", "up", "low", "down")))
+
+
+df |> gtsummary::tbl_summary(by = pase_change)
+
+cox <- df |>
+ # dplyr::select(-pase_0,-pase_4,-pase_rel_dif) |>
+ cox_regression(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_change")
+
+
+df |>
+ # dplyr::select(-pase_0,-pase_4,-pase_rel_dif) |>
+ cox_regression(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_change") |>
+ tbl_regression_standard()
+
+df |>
+ # dplyr::select(-pase_0,-pase_4,-pase_rel_dif) |>
+ cox_regression() |>
+ ggsurvfit::survfit2() |>
+ ggsurvfit::ggsurvfit() + ggsurvfit::add_confidence_interval() +
+ ggsurvfit::scale_ggsurvfit() +
+ ggsurvfit::add_risktable()
+
+
+###
+
+
+data <- targets::tar_read(df_all_data_formatted)
+
+
+df <- targets::tar_read(df_all_data_formatted) |>
+ group_format(binning.fun = bin_relupdown, rel.bin = 50)
+
+
+df |> gtsummary::tbl_summary(by = pase_change)
+
+df |>
+ # dplyr::select(-pase_0,-pase_4,-pase_rel_dif) |>
+ cox_regression(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_change") |>
+ tbl_regression_standard()
+
+df |>
+ # dplyr::select(-pase_0,-pase_4,-pase_rel_dif) |>
+ cox_regression() |>
+ ggsurvfit::survfit2() |>
+ ggsurvfit::ggsurvfit() + ggsurvfit::add_confidence_interval() +
+ ggsurvfit::scale_ggsurvfit() +
+ ggsurvfit::add_risktable()
+
+
+
+targets::tar_read(list_df_multi_grouping) |> purrr::map(\(.x) summary(.x[["pase_change"]]))
+
+
+
+
+
+## BMI out
+
+### Univariable models
+
+
+
+ls_df <- targets::tar_read(df_all_data_formatted) |>
+ multi_grouping_df_list(args.list=df_mega_list(strategies=c(
+ # "bin_original",
+ # "bin_anyupdown",
+ "bin_relupdown",
+ "bin_absupdown",
+ "bin_quantile",
+ # "bin_clusterlcm",
+ "bin_percentage")),remove="pase_0")
+
+
+performance_overview_uni <- ls_df |> multi_cox_performance_test(all.vars = FALSE, use.strata = FALSE, outcome.var = "pase_change")
+
+# performance_overview_uni
+
+# Comparing the best and the original
+
+
+cox_models_uni <- ls_df|>
+ purrr::map(\(.x){
+ .x |>
+ cox_regression(all.vars = FALSE, use.strata = FALSE, outcome.var = "pase_change")
+ })
+
+ls_df[c(pick_non_duplicated(performance_overview_uni,"Name","AIC_wt",1:3),"lowest_percentage_25")]|>
+ purrr::map(\(.x){
+ .x |> dplyr::select(pase_change) |>
+ gtsummary::tbl_summary()
+ }) |> tbl_merged_named()
+
+
+lapply(best_models_uni, performance::model_performance) |>
+ (\(.x){
+ dplyr::bind_cols(model=names(.x), dplyr::bind_rows(.x))
+ })()
+
+
+models_ls_uni <- best_models_uni |> lapply(\(.x){
+ .x |> gtsummary::tbl_regression(exponentiate=TRUE) |> gtsummary::bold_p()
+})
+
+
+models_ls_uni |> tbl_merged_named()
+
+
+## Multivariable models
+
+performance_overview_multi <- ls_df |> multi_cox_performance_test(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_change")
+
+# performance_overview_multi
+
+# Comparing the best and the original
+# best_models_multi <- head(performance_overview_multi,10)
+
+cox_models_multi <- ls_df |>
+ purrr::map(\(.x){
+ .x |>
+ cox_regression(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_change")
+ })
+
+ls_df[c(pick_non_duplicated(performance_overview_multi,"Name","AIC_wt",1:3),"lowest_percentage_25")]|>
+ purrr::map(\(.x){
+ .x |> dplyr::select(pase_change) |>
+ gtsummary::tbl_summary()
+ }) |> tbl_merged_named()
+
+lapply(best_models_multi, performance::model_performance) |>
+ (\(.x){
+ dplyr::bind_cols(model=names(.x), dplyr::bind_rows(.x))
+ })()
+
+
+models_ls_multi <- best_models_multi |> lapply(\(.x){
+ .x |> gtsummary::tbl_regression(exponentiate=TRUE) |> gtsummary::bold_p()
+})
+
+
+models_ls_multi |> tbl_merged_named()
+
+
+
+## Handle for mids objects
+# targets::tar_read(df_events_mids)
+# targets::tar_read(df_event_data)
+
+ls_df_mids <- targets::tar_read(df_events_mids) |> multi_grouping_df_list(args.list=df_mega_list(strategies=c(
+ # "bin_original",
+ # "bin_anyupdown",
+ "bin_relupdown",
+ "bin_absupdown",
+ "bin_quantile",
+ # "bin_clusterlcm",
+ "bin_percentage")),remove="pase_0")
+
+cox_models_mids <- ls_df_mids|>
+ purrr::map(\(.x){
+ .x |>
+ cox_regression(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_change")
+ })
+
+performance_overview_mids <- lapply(cox_models_mids,mids_model_aic)|>
+ (\(.x){
+ dplyr::bind_cols(Name=names(.x), AIC=Reduce(c,.x))
+ })() |> dplyr::arrange(AIC) |>
+ dplyr::mutate(rank=rank(AIC,ties.method = "min"))
+
+# performance_overview_mids|> head(20)
+
+# Comparing the best and the original
+
+best_models_mids <- head(performance_overview_mids,10)
+
+# best_models_mids <- cox_models_mids[c(pick_non_duplicated(performance_overview_mids,"Name","AIC",1:3),"quantile_change_6_2_ANY","lowest_percentage_25")]
+
+models_ls_mids <- best_models_mids |> lapply(\(.x){
+ .x |> gtsummary::tbl_regression(exponentiate=TRUE) |> gtsummary::bold_p() |> gtsummary::add_glance_source_note()
+})
+
+models_ls_mids |> tbl_merged_named()
+
+## Difference between mids-results
+# targets::tar_read(df_event_data)
+
+## NOTE on investigation
+# In the original grouping, PASE-cutting was performed based only on patients without prior events.
+# In the new multi-grouping strategies evaluation, PASE grouping is based on all TALOS-patients.
+# We already did export some data, so we should probably stick with this. On the other hand,
+# this is probably a minor thing, and we should perform analyses based on all patients like intended.
+# MAYBE
+#
+
+##
+
+
+
+
+best_models <- list("uni"=performance_overview_uni,
+ "multi"=performance_overview_multi,
+ "mids"=performance_overview_mids) |>
+ lapply(\(.x){
+ .x |> dplyr::select(Name,rank,AIC)
+ }) |> dplyr::bind_rows()
+
+models_overall_rank <- split(best_models,best_models$Name) |>
+ purrr::imap(\(.x,.i){
+ tibble::tibble(name=.i,rank_sum=sum(.x$rank), median_AIC=median(.x$AIC))
+ })|> dplyr::bind_rows() |>
+ dplyr::arrange(rank_sum)
+
+models_overall_rank[models_overall_rank$name %in% c("quantile_change_10_1","quantile_change_8_2","quantile_change_8_2_ANY"),]
+
+all_cox_models <- list(
+ "Univariable"=cox_models_uni,
+ "Multivariable"=cox_models_multi,
+ "Imputed multivariable"=cox_models_mids
+)
+
+names_best <- models_overall_rank$name[c(1:6)]
+
+best_sum_tables <- names_best|>
+ lapply(\(.x){
+ ls_df[[.x]] |>
+ dplyr::select(pase_change) |> gtsummary::tbl_summary()
+ }) |>
+ setNames(glue::glue("{rank(models_overall_rank$rank_sum,ties.method = 'min')[c(1:6)]}_{names_best}"))
+
+best_cox_tables <- names_best |>
+ lapply(\(.x){
+ list("Group counts"=ls_df[[.x]] |>
+ dplyr::select(pase_change) |> gtsummary::tbl_summary() |> fix_labels(),
+ all_cox_models |>
+ lapply(\(.y){
+ .y[[.x]] |> tbl_regression_standard() |> gtsummary::modify_table_styling(columns=tidyselect::starts_with("p.value"),hide = TRUE) |>
+ gtsummary::remove_row_type(variables=-pase_change,type="all")
+ })) |> purrr::list_flatten() |>
+ tbl_merged_named()
+ }) |>
+ setNames(glue::glue("{rank(models_overall_rank$rank_sum,ties.method = 'min')[c(1:6)]}_{names_best}"))
+
+## Counts also for multivariable analyses could be added as well
+
+best_stack <- best_cox_tables |> tbl_stack_named()
+
+best_stack |> gtsummary::as_gt() |>
+ gt::gtsave(filename = here::here("out/sens_cox.docx"))
+
+## Checking on a specific model
+ls_df_fun[[24]] |>
+ # dplyr::select(-pase_0,-pase_4,-pase_rel_dif) |>
+ cox_regression() |>
+ ggsurvfit::survfit2() |>
+ ggsurvfit::ggsurvfit() + ggsurvfit::add_confidence_interval() +
+ ggsurvfit::scale_ggsurvfit() +
+ ggsurvfit::add_risktable()
+
+ls_df_fun[[24]] |>
+ # dplyr::select(-pase_0,-pase_4,-pase_rel_dif) |>
+ cox_regression(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_change") |>
+ tbl_regression_standard()
diff --git a/2 Longterm/260315/combined_script.R b/2 Longterm/260315/combined_script.R
new file mode 100755
index 0000000..3a17fe9
--- /dev/null
+++ b/2 Longterm/260315/combined_script.R
@@ -0,0 +1,740 @@
+# Code from: cont_pase_sens.qmd
+targets::tar_config_set(store = here::here("_targets"))
+source(here::here("R/functions.R"))
+source(here::here("R/glmnet-reg.R"))
+library(targets)
+library(tidyverse)
+tbl_cont_0 <- targets::tar_read("df_all_data_formatted")|>
+ dplyr::filter(!is.na(pase_0),!is.na(pase_4)) |>
+ # pase_cutter(drop.nas = TRUE) |>
+ events_ready(v.groups=c("clin","lifestyle.events","ses", "assess.events","quartiles")) |>
+ dplyr::select(dplyr::all_of(c("pase_0", "age", "reg_female", "nihss_0", "reg_trombolyse",
+"reg_trombektomi", "rtreat_placebo", "reg_alone", "reg_smoker",
+"reg_more_alc", "reg_hyperten", "reg_diabetes", "reg_atriefli",
+"reg_ami", "soc_status_nowork", "fam_indk_hl", "edu_level_hl",
+"who_4", "mdi_4", "mfi_gen_4", "mrs_4_above1", "time", "status"
+))) |>
+ (\(data){
+ # c("pase_0","pase_4") |>
+ # purrr::map(\(exp){
+ list("Univariable"=cox_regression(data=data,all.vars = FALSE, use.strata = FALSE, outcome.var = "pase_0"),
+ "Multivariable"=cox_regression(data=data,all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_0")) |>
+ purrr::map(\(.x){
+ .x |> gtsummary::tbl_regression(exponentiate=TRUE) |> gtsummary::add_nevent()|>
+ fix_labels()
+ }) |>
+ tbl_merged_named()
+ # })
+ })() |>
+ gtsummary::modify_table_body( ~ filter(.x, variable == "pase_0"))
+tbl_cont_4 <- targets::tar_read("df_all_data_formatted")|>
+ dplyr::filter(!is.na(pase_0),!is.na(pase_4)) |>
+ # pase_cutter(drop.nas = TRUE) |>
+ events_ready(v.groups=c("clin","lifestyle.events","ses", "assess.events","quartiles")) |>
+ dplyr::select(dplyr::all_of(c("pase_4", "age", "reg_female", "nihss_0", "reg_trombolyse",
+"reg_trombektomi", "rtreat_placebo", "reg_alone", "reg_smoker",
+"reg_more_alc", "reg_hyperten", "reg_diabetes", "reg_atriefli",
+"reg_ami", "soc_status_nowork", "fam_indk_hl", "edu_level_hl",
+"who_4", "mdi_4", "mfi_gen_4", "mrs_4_above1", "time", "status"
+))) |>
+ (\(data){
+ # c("pase_0","pase_4") |>
+ # purrr::map(\(exp){
+ list("Univariable"=cox_regression(data=data,all.vars = FALSE, use.strata = FALSE, outcome.var = "pase_4"),
+ "Multivariable"=cox_regression(data=data,all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_4")) |>
+ purrr::map(\(.x){
+ .x |> gtsummary::tbl_regression(exponentiate=TRUE) |> gtsummary::add_nevent()|>
+ fix_labels()
+ }) |>
+ tbl_merged_named()
+ # })
+ })() |>
+ gtsummary::modify_table_body( ~ filter(.x, variable == "pase_4"))
+list("PASE 0"=tbl_cont_0,
+ "PASE 6"=tbl_cont_4) |> tbl_stack_named()
+
+
+
+# Code from: events_type_sens.qmd
+targets::tar_config_set(store = here::here("_targets"))
+source(here::here("R/functions.R"))
+source(here::here("R/glmnet-reg.R"))
+library(targets)
+library(tidyverse)
+df <- targets::tar_read(df_all_data_formatted) |>
+ dplyr::mutate(
+ status.all=dplyr::if_else(
+ startsWith(as.character(event),"death"),"death","cve",missing = NA_character_)|> factor()
+ )|>
+ get_vars(vars.groups = c("clin","lifestyle.events","ses", "ssri")) |>
+ dplyr::rename(status=status.all,
+ time=time.all)
+df$status |> summary()
+tbl <- df |>
+ pase_cutter(drop.nas = TRUE, drop.pase = TRUE) |>
+ (\(.x) {
+ list(
+ "death" = .x |> dplyr::mutate(status = dplyr::if_else(status == "death", 1, 0, 0)),
+ "cve" = .x |> dplyr::mutate(status = dplyr::if_else(status == "cve", 1, 0, 0))
+ )
+ })() |> lapply(\(.x) {
+ ls <- list(
+ "Univariate" = .x |> dplyr::select(-rtreat) |>
+ standard_multi_cox_table(all.vars = FALSE) |> gtsummary::add_nevent(),
+ "Multivariate" = .x |> dplyr::select(-rtreat) |>
+ standard_multi_cox_table(all.vars = TRUE) |> gtsummary::add_nevent()
+ ) |>
+ purrr::map(gtsummary::bold_p) |>
+
+ tbl_merged_named()
+ ls |>
+ gtsummary::modify_table_body( ~ filter(.x, variable == "pase_change"))
+ }) |>
+ gtsummary::tbl_stack(group_header = c("death","cve"))# |>
+ # gtsummary::as_gt() |>
+ # gt::gtsave(here::here("out/trial_strat_sens.docx"))
+
+tbl
+
+names(tbl)
+
+
+
+# Code from: mrs_sensitivity.qmd
+source(here::here("R/functions.R"))
+ls_mrs0 <- targets::tar_read(df_all_data_formatted) |>
+ dplyr::filter(mrs_0==0)|>
+ dplyr::filter(!is.na(pase_0),!is.na(pase_4)) |>
+ events_ready() |>
+ (\(.x){
+ list(
+ std=.x,
+ imp=.x |> events_dataset(impute = TRUE)
+ )
+ })() |>
+ purrr::map(\(.x){
+ .x |>
+ pase_cutter(drop.pase = TRUE,drop.nas = TRUE)
+ })
+
+# targets::tar_read(df_all_data_formatted) |>
+# dplyr::filter(mrs_0==0) |>
+# dplyr::filter(!is.na(pase_0),!is.na(pase_4)) |> events_ready() |>
+# pase_cutter(drop.pase = TRUE,drop.nas = TRUE) |>
+# cox_regression(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_change") |>
+# tbl_regression_standard()
+
+ls <- list(
+ "Univariable"= ls_mrs0$std |>
+ dplyr::select(pase_change,dplyr::everything()) |>
+ splitdf4uvcox(include=c("time","status")) |>
+ purrr::map(\(.x){
+ .x |> tbl_regression_standard()
+ }) |>
+ gtsummary::tbl_stack(),
+ "Multivariable" = ls_mrs0$std |>
+ cox_regression(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_change") |>
+ tbl_regression_standard() |> gtsummary::add_glance_source_note(),
+ "Multivariable Imputed"= ls_mrs0$imp |>
+ cox_regression(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_change") |>
+ tbl_regression_standard()
+) |> purrr::map(\(.x){
+ .x|>
+ gtsummary::modify_table_styling(column = p.value,
+ hide=TRUE)
+}) |> tbl_merged_named()
+
+ls
+# |> gtsummary::as_gt() |>
+# gt::gtsave(filename = here::here(glue::glue("out/sens_subset_mrs0_0.docx")))
+
+# ls_mrs0$std |>
+# cox_regression(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_change") |> performance::check_model()
+targets::tar_read(df_all_data_formatted)|>
+ dplyr::filter(!is.na(pase_0),!is.na(pase_4)) |>
+ dplyr::filter(mrs_0==0) |>
+ dplyr::select(pase_0,pase_4) |>
+ summary()
+# ls_mrs0$std |> gtsummary::tbl_summary(by = pase_change) |> fix_labels()
+ls_mrs0_change <- targets::tar_read(df_all_data_formatted) |>
+ get_vars(vars.groups =c("clin","lifestyle.events","ses", "assess.events.pre")) |>
+ dplyr::filter(event.include) |>
+ dplyr::select(-tidyselect::all_of("event.include")) |>
+ (\(.x){
+ list(
+ std=.x,
+ imp=.x |>
+ dplyr::select(-tidyselect::any_of("reg_bmi"))|>
+ fun_impute(ignore = c("pase_0","pase_4"),pase.mod = FALSE)
+ )
+ })() |>
+ purrr::map(\(.x){
+ .x |>
+ pase_cutter(drop.pase = TRUE,drop.nas = TRUE)
+ })
+
+# targets::tar_read(df_all_data_formatted) |>
+# dplyr::filter(mrs_0==0) |>
+# dplyr::filter(!is.na(pase_0),!is.na(pase_4)) |> events_ready() |>
+# pase_cutter(drop.pase = TRUE,drop.nas = TRUE) |>
+# cox_regression(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_change") |>
+# tbl_regression_standard()
+
+ls_change <- list(
+ "Univariable"= ls_mrs0_change$std |>
+ dplyr::select(pase_change,dplyr::everything()) |>
+ splitdf4uvcox(include=c("time","status")) |>
+ purrr::map(\(.x){
+ .x |> tbl_regression_standard()
+ }) |>
+ gtsummary::tbl_stack(),
+ "Multivariable" = ls_mrs0_change$std |>
+ cox_regression(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_change") |>
+ tbl_regression_standard() |> gtsummary::add_glance_source_note(),
+ "Multivariable Imputed"= ls_mrs0_change$imp |>
+ cox_regression(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_change") |>
+ tbl_regression_standard()
+) |> purrr::map(\(.x){
+ .x|>
+ gtsummary::modify_table_styling(column = p.value,
+ hide=TRUE)
+}) |> tbl_merged_named()
+
+ls_change
+#| eval: false
+coll <- list(
+ mrs0_0=ls_mrs0$std|>
+ cox_regression(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_change"),
+ pase_change_mrs0 = ls_mrs0_change$std|>
+ cox_regression(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_change"),
+ pase_change=df |>
+ get_vars(vars.groups =c("clin","lifestyle.events","ses", "assess.events")) |>
+ dplyr::filter(event.include) |>
+ dplyr::select(-tidyselect::all_of("event.include")) |>
+ pase_cutter(drop.pase = TRUE,drop.nas = TRUE)|>
+ cox_regression(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_change"),
+ prestroke_pase=df |>
+ pase_cutter(drop.nas = FALSE) |>
+ get_vars(vars.groups = c("clin", "lifestyle.events", "ses", "assess.pred", "quartiles"), vars.vec = c("inc_time",
+ "time",
+ "status")) |>
+ dplyr::mutate(time = time + inc_time / 365) |>
+ dplyr::select(-dplyr::any_of(c("pase_0", "pase_4", "pase_change", "inc_time", "event.include", "pase_4_quartile")))|>
+ cox_regression(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_0_quartile")) |>
+ purrr::map(performance::check_collinearity)
+
+coll |> purrr::imap(\(.x,.i){
+ .x |> dplyr::as_tibble() |> gt::gt() |> gt::tab_header(.i)|>
+ gt::gtsave(filename = here::here(glue::glue("out/coll_{.i}.docx")))
+})
+
+
+
+# Code from: pa_event_plots.qmd
+targets::tar_config_set(store = here::here("_targets"))
+source(here::here("R/functions.R"))
+source(here::here("R/glmnet-reg.R"))
+library(targets)
+library(tidyverse)
+# targets::tar_read(plot_events_survival_smooth)
+p1 <- targets::tar_read(df_event_data) |>
+ events_dataset(impute = FALSE) |>
+ dplyr::mutate(pase_change = factor(pase_change,
+ levels = c("Persistently high", "Decrease", "Increase", "Persistently low")),
+ pase_change = dplyr::recode(pase_change,
+ "Persistently high"="Consistently above lowest",
+ "Decrease"="Decrease to lowest",
+ "Increase"="Increase from lowest",
+ "Persistently low"="Consistently lowest")
+ ) |>
+ cox_regression() |>
+ plot_survival_smooth(line.w = 1) +
+ ggplot2::labs(
+ fill = "PA level change group",
+ color = "PA level change group",
+ linetype = "PA level change group"
+ ) +
+ ggplot2::scale_x_continuous(limits = c(0, 9.5), breaks = c(0, 3, 6, 9))
+
+
+ggplot2::ggsave(here::here("out/smooth_surv.png"),
+ p1,
+ dpi = 600,
+ units = "cm",
+ height = 8,
+ width = 15)
+p1
+surv.data <- targets::tar_read(df_event_data) |>
+ events_dataset(impute = FALSE) |>
+ cox_regression(all.vars = FALSE) |> # Minimal model to just give risk table
+ ggsurvfit::survfit2() |>
+ ggsurvfit::tidy_survfit(times = c(0, 3, 6, 9))
+
+
+risk_event <- c("n.risk", "cum.event") |>
+ purrr::map2(c("Numbers at risk", "Events"), \(.x, .y){
+ surv.data |>
+ tidyr::pivot_wider(id_cols = strata, names_from = time, values_from = {{ .x }}) |>
+ mask_micro_table(col.sel = -strata) |> # Masking columns
+ tidyr::pivot_longer(cols = -strata) |>
+ setNames(c("strata", "time", .x)) |>
+ dplyr::mutate(dplyr::across(time, ~ as.numeric(.x))) |>
+ dplyr::mutate(strata = factor(strata, levels = rev(c("Persistently high", "Decrease", "Increase", "Persistently low")))) |>
+ ggplot2::ggplot(ggplot2::aes(x = time, y = strata, label = get(.x))) +
+ ggplot2::geom_text() +
+ ggplot2::labs(y = NULL, title = .y) +
+ ggplot2::theme_minimal() +
+ ggsurvfit::theme_risktable_default()
+ })
+
+p2 <- ggsurvfit::ggsurvfit_align_plots(list(p1, risk_event[1]) |> purrr::list_flatten()) |>
+ patchwork::wrap_plots(ncol = 1, heights = c(2, 1), guides = "collect")
+
+ggplot2::ggsave(here::here("out/smooth_surv_tables.png"),
+ p2,
+ dpi = 600,
+ units = "cm",
+ height = 9,
+ width = 15)
+p2
+#| include: false
+targets::tar_read(df_event_data) |>
+ events_dataset(impute = FALSE) |>
+ dplyr::mutate(pase_change = factor(pase_change, levels = c("Persistently high", "Decrease", "Increase", "Persistently low"))) |>
+ cox_regression(all.vars = FALSE) |> # Minimal model to just give risk table
+ ggsurvfit::survfit2() |>
+ ggsurvfit::ggsurvfit() +
+ ggplot2::scale_y_continuous(
+ limits = c(0, 1.02),
+ breaks = seq(0, 1, .25),
+ labels = scales::percent,
+ expand = c(0.01, 0)
+ ) +
+ ggplot2::scale_x_continuous(breaks = c(0, 4, 8.5), expand = c(0.02, 0)) +
+ ggsurvfit::add_risktable()
+#| include: false
+targets::tar_read(df_event_data_small) |>
+ events_dataset(impute = FALSE) |>
+ dplyr::mutate(pase_change = factor(pase_change, levels = c("Persistently high", "Decrease", "Increase", "Persistently low"))) |>
+ cox_regression() |>
+ plot_survival_smooth() +
+ ggplot2::labs(
+ fill = "PA change group",
+ color = "PA change group",
+ linetype = "PA change group"
+ )
+#| include: false
+targets::tar_read(df_event_data) |>
+ events_dataset(impute = FALSE) |>
+ dplyr::mutate(pase_change = factor(pase_change, levels = c("Persistently high", "Decrease", "Increase", "Persistently low"))) |>
+ cox_regression() |>
+ plot_survival_smooth() +
+ ggplot2::labs(
+ fill = "PA change group",
+ color = "PA change group",
+ linetype = "PA change group"
+ )
+
+
+
+# Code from: pa_events_analyses.qmd
+targets::tar_config_set(store = here::here("_targets"))
+source(here::here("R/functions.R"))
+source(here::here("R/glmnet-reg.R"))
+library(targets)
+library(tidyverse)
+#| include: false
+list("Univariate"=targets::tar_read(tbl_events_cox_regression_uv),
+"Multivariate"=targets::tar_read(tbl_events_cox_regression),
+"Imputed Multivariate"=targets::tar_read(tbl_events_mids_cox_regression)) |>
+ # purrr::map(gtsummary::modify_table_styling,column=p.value,hide=TRUE) |>
+ purrr::map(gtsummary::bold_p) |>
+ tbl_merged_named()
+#| include: true
+list("Univariate"=targets::tar_read(tbl_events_cox_regression_uv),
+"Multivariate"=targets::tar_read(tbl_events_cox_regression),
+"Imputed Multivariate"=targets::tar_read(tbl_events_mids_cox_regression)) |>
+ purrr::map(gtsummary::modify_table_styling,column=p.value,hide=TRUE) |>
+ tbl_merged_named()
+#| echo: true
+targets::tar_read(df_event_data) |>
+ # dplyr::select(-reg_bmi) |>
+ na.omit() |>
+ nrow()
+#| include: false
+targets::tar_read(tbl_events_cox_regression_small)
+
+targets::tar_read(df_event_data_small)
+#| include: false
+targets::tar_read(tbl_events_mids_cox_regression)
+targets::tar_read("df_all_data_formatted") |>
+ events_ready() |>
+ dplyr::filter(!is.na(pase_0),!is.na(pase_4)) |>
+ (\(data){
+ c("pase_0","pase_4") |>
+ purrr::map(\(exp){
+ with(data,survival::coxph(as.formula(glue::glue("survival::Surv(time, status)~{exp}")))) |>
+ gtsummary::tbl_regression(exponentiate=TRUE)|>
+ fix_labels()
+ })
+ })() |>
+ gtsummary::tbl_stack()
+targets::tar_read("df_all_data_formatted") |>
+ pase_cutter(drop.nas = TRUE) |>
+ events_ready(v.groups=c("clin","lifestyle.events","ses", "assess.events","quartiles")) |>
+ dplyr::select(-dplyr::any_of(c("pase_0","pase_4","pase_change"))) |>
+ (\(data){
+ c("pase_0_quartile","pase_4_quartile") |>
+ purrr::map(\(exp){
+ list("Univariable"=cox_regression(data=data,all.vars = FALSE, use.strata = FALSE, outcome.var = exp),
+ "Multivariable"=cox_regression(data=data,all.vars = TRUE, use.strata = FALSE, outcome.var = exp)) |>
+ purrr::map(\(.x){
+ .x |> gtsummary::tbl_regression(exponentiate=TRUE)|>
+ fix_labels()
+ }) |>
+ tbl_merged_named()
+ })
+ })() |>
+ gtsummary::tbl_stack()
+targets::tar_read("df_all_data_formatted") |>
+ pase_cutter(drop.nas = TRUE) |>
+ get_vars(vars.groups = c("clin","lifestyle.events","ses", "assess.events","quartiles"),vars.vec = c("inc_time")) |>
+ dplyr::mutate(time=time+inc_time/365) |>
+ dplyr::select(-dplyr::any_of(c("pase_0","pase_4","pase_change","inc_time","event.include","pase_4_quartile"))) |>
+ (\(data){
+ list(
+ with(data,survival::coxph(as.formula(glue::glue("survival::Surv(time, status)~{exp}")))) |>
+ gtsummary::tbl_regression(exponentiate=TRUE)|>
+ fix_labels() |> gtsummary::add_glance_source_note()
+ )
+ })() |>
+ gtsummary::tbl_stack()
+
+
+
+# Code from: pa_events_summaries.qmd
+targets::tar_config_set(store = here::here("_targets"))
+source(here::here("R/functions.R"))
+source(here::here("R/glmnet-reg.R"))
+library(targets)
+library(tidyverse)
+#| include: false
+targets::tar_read(tbl_events_summary)
+#| include: true
+targets::tar_read(tbl_events_summary) |> mask_micro_summary(micro.n = 5)
+#| include: false
+ls <- targets::tar_read(df_event_data)|>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::select(-tidyselect::all_of(c("status", "time"))) |>
+ dplyr::filter(!is.na(pase_change)) |>
+ labelling_data() |>
+ gtsummary::tbl_summary(
+ missing = "ifany",
+ by = pase_change,
+ # value = list(where(is.logical) ~ TRUE),
+ missing_text = "Missing"
+ ) |>
+ gtsummary::add_overall() |>
+ gtsummary::add_n()
+
+ls |> add_missing_stats() |> mask_micro_summary(micro.n = 5)
+targets::tar_read(df_event_data)|>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::select(pase_change, time) |>
+ dplyr::filter(!is.na(pase_change)) |>
+ labelling_data() |>
+ gtsummary::tbl_summary(
+ missing = "ifany",
+ by = pase_change,
+ type = gtsummary::all_continuous() ~ "continuous2",
+ statistic = list(gtsummary::all_continuous() ~ c("{median} ({p25}, {p75})","{mean} ({sd})")),
+ # value = list(where(is.logical) ~ TRUE),
+
+ missing_text = "Missing"
+ ) |>
+ gtsummary::add_overall()
+#| include: true
+targets::tar_read(df_all_data_formatted) |>
+ (\(.x)summary(.x$pase_0))()
+
+# targets::tar_read(df_all_data_formatted) |>
+# dplyr::filter(!is.na(pase_0),!is.na(pase_4))|>
+# (\(.x)summary(.x$pase_0))()
+#| include: false
+targets::tar_read(df_all_data_formatted) |>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::select(mrs_4, pase_change) |>
+ dplyr::mutate(pase_change = forcats::fct_relevel(pase_change, c("Persistent high", "Increase", "Decrease", "Persistent low"))) |>
+ na.omit() |>
+ (\(.x){
+ table(mrs = .x$mrs_4, pase = .x$pase_change)
+ })() |>
+ rankinPlot::grottaBar(groupName = "pase", scoreName = "mrs")
+targets::tar_read(df_event_data)|>
+ pase_cutter(drop.pase = FALSE) |>
+ dplyr::filter(!is.na(pase_change))|>
+ dplyr::select(pase_0,pase_4) |>
+ labelling_data() |>
+ gtsummary::tbl_summary()
+targets::tar_read(df_all_data_formatted)|>
+ pase_cutter(drop.pase = FALSE) |>
+ dplyr::filter(!is.na(pase_change))|>
+ dplyr::count(pase_0_quartile,pase_4_quartile) |>
+ write_csv(here::here("out/event_sankey_data.csv"))
+ds <- targets::tar_read(df_all_data_formatted) |>
+ get_vars(vars.groups = c("clin", "lifestyle", "ses", "assess.events", "extra")) |>
+ dplyr::select(-time, -status, -soc_status) |>
+ pase_cutter(drop.pase = TRUE) |>
+ labelling_data()
+
+ls <- list(
+ pase_out = ds |>
+ dplyr::mutate(event.filter = factor(
+ dplyr::case_when(is.na(pase_change) ~ "pase_incomplete",
+ !event.include ~ "early_event",
+ .default = "included"
+ ),
+ levels = c("pase_incomplete", "early_event", "included")
+ )),
+ event_out = ds |>
+ dplyr::mutate(event.filter = factor(
+ dplyr::case_when(!event.include ~ "early_event",
+ is.na(pase_change) ~ "pase_incomplete",
+ .default = "included"
+ ),
+ levels = c("early_event", "pase_incomplete", "included")
+ ))
+) |>
+ purrr::map(dplyr::select, -event.include, -pase_change, -event)
+
+ls_tbl <- ls |>
+ purrr::map(\(.x){
+ .x |>
+ dplyr::filter(event.filter != "pase_incomplete") |>
+ dplyr::mutate(event.filter = factor(event.filter))
+ }) |>
+ (\(.x) list(.x, purrr::pluck(ls, 1) |> dplyr::mutate(event.filter = event.filter == "included")))() |>
+ purrr::list_flatten()
+#| include: false
+ls_tbl |>
+ purrr::map(\(.x){
+ .x |>
+ gtsummary::tbl_summary(
+ by = event.filter,
+ missing = "ifany"
+ ) |>
+ gtsummary::add_p()
+ }) |>
+ (\(.x)gtsummary::tbl_merge(.x, c(names(.x)[1:2], "all_out")))()
+targets::tar_read(df_all_data_formatted) |>
+ get_vars(vars.groups = c("clin", "lifestyle", "ses", "assess.events", "extra", "assess.pred")) |>
+ dplyr::select(-time,
+ # -status,
+ -soc_status) |>
+ pase_cutter(drop.pase = FALSE) |>
+ labelling_data() |>
+ dplyr::mutate(event.filter = factor(
+ dplyr::case_when(
+ !event.include | is.na(pase_change) ~ "excluded",
+ .default = "included"
+ )
+ )) |>
+ dplyr::select(-who_4, -mdi_4, -mrs_4_above1, -mfi_gen_4) |>
+ gtsummary::tbl_summary(
+ by = event.filter,
+ missing = "ifany"
+ ) |>
+ gtsummary::add_p()
+ds |>
+ dplyr::mutate(pase_incomplete=is.na(pase_change),
+ excluded=pase_incomplete | !event.include,
+ early_event=!event.include) |>
+ dplyr::select(early_event,pase_incomplete,excluded) |>
+ gtsummary::tbl_summary(by=excluded)
+#| include: true
+ls_tbl |>
+ purrr::pluck(3) |>
+ dplyr::select(-who_4, -mdi_4, -mrs_4_above1, -mfi_gen_4) |>
+ (\(.x){
+ .x |>
+ gtsummary::tbl_summary(
+ by = event.filter,
+ missing = "no"
+ ) |>
+ gtsummary::add_p()
+ })() |> mask_micro_summary(micro.n = 5)
+#| include: true
+targets::tar_read(df_event_data)|>
+ pase_cutter(drop.pase = FALSE)|>
+ dplyr::filter(!is.na(pase_change)) |>
+ dplyr::select(-time, -status, -pase_0_quartile, -pase_4_quartile, -pase_change) |>
+ labelling_data() |>
+ dplyr::mutate(reg_female=ifelse(reg_female,"Female","Male")) |>
+ gtsummary::tbl_summary(
+ missing = "ifany",
+ by = reg_female,
+ value = list(where(is.logical) ~ TRUE)
+ )|> gtsummary::add_p() |>
+ mask_micro_summary()
+#| include: false
+events <- targets::tar_read(ls_all_events) |>
+ dplyr::bind_rows() |>
+ dplyr::left_join(targets::tar_read(df_all_data_formatted) |>
+ dplyr::select(c("event.include", "rdate", "enddate", "PNR")), by = c("CPR" = "PNR")) |>
+ dplyr::mutate(
+ date.event = as.Date(date.event),
+ event.trial = !date.event > enddate,
+ event.itt = !date.event > (lubridate::dmonths(6) + rdate)
+ ) |>
+ dplyr::mutate(event.type = dplyr::if_else(grepl("^death", event.type), "death", event.type))
+
+ls <- list(
+ # Events during inclusion and during first 6 months after inclusion (Intention to treat)
+ events |>
+ dplyr::select(event.type, event.trial, event.itt) |>
+ tidyr::pivot_longer(cols = c("event.trial", "event.itt")) |>
+ dplyr::filter(value) |>
+ dplyr::select(-value) |>
+ gtsummary::tbl_summary(by = name),
+
+ # All registred events
+ events |>
+ dplyr::select(event.type) |>
+ gtsummary::tbl_summary(),
+
+ # All events in the selected group
+ events |>
+ dplyr::select(event.type, event.include) |>
+ # tidyr::pivot_longer(cols = c("event.trial","event.itt")) |>
+ dplyr::filter(event.include) |>
+ dplyr::select(-event.include) |>
+ gtsummary::tbl_summary(),
+
+ # All considered events (first event)
+ targets::tar_read(df_events_deaths)|>
+ dplyr::mutate(event.type = dplyr::if_else(grepl("^death", event.type), "death", event.type)) |>
+ dplyr::select(event.type) |>
+ gtsummary::tbl_summary(),
+
+ # All included events (first event)
+ targets::tar_read(df_all_data_formatted)|>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::filter(!is.na(pase_change))|>
+ dplyr::filter(event.include) |>
+ # dplyr::select(-event.include)|>
+ dplyr::mutate(event = dplyr::if_else(grepl("^death", event), "death", event)) |>
+ dplyr::select(event) |>
+ dplyr::filter(!is.na(event)) |>
+ gtsummary::tbl_summary()
+) |>
+ setNames(c("During trial", "All events", "Selected events", "Considered", "Included"))
+
+ls[4] |>
+ purrr::map(\(.x) .x |>
+ mask_micro_summary(micro.n = 5)) |>
+ tbl_merged_named()
+targets::tar_read(df_all_data_formatted)|>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::filter(!is.na(pase_change))|>
+ dplyr::filter(event.include) |>
+ # dplyr::select(-event.include)|>
+ dplyr::mutate(event = dplyr::case_when(grepl("^death", event)~"Mors",
+ grepl("^DI6", event)~ "DI61-4",
+ .default = event)) |>
+ dplyr::select(event) |>
+ dplyr::filter(!is.na(event)) |>
+ gtsummary::tbl_summary() |> mask_micro_summary(micro.n = 5)
+targets::tar_read(df_event_data) |>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::filter(!is.na(pase_change)) |>
+ events_table(by="pase_change")
+
+
+
+# Code from: sex_events.qmd
+targets::tar_config_set(store = here::here("_targets"))
+source(here::here("R/functions.R"))
+source(here::here("R/glmnet-reg.R"))
+library(targets)
+library(tidyverse)
+
+df <- targets::tar_read(df_all_data_formatted) |>
+ get_vars(vars.groups = c("clin","lifestyle.events","ses", "ssri")) |>
+ dplyr::rename(status=status.all,
+ time=time.all)
+df |>
+ pase_cutter(drop.nas = TRUE,drop.pase = TRUE) |>
+ dplyr::mutate(reg_female=factor(ifelse(reg_female,"Female","Male"))) |>
+ (\(.x) {
+ split(.x, .x$reg_female)
+ })() |> lapply(\(.x) {
+ ls <- list("Univariate"=.x |> dplyr::select(-reg_female,-rtreat) |>
+ standard_multi_cox_table(all.vars = FALSE) |> gtsummary::add_nevent(),
+"Multivariate"=.x |> dplyr::select(-reg_female,-rtreat) |>
+ standard_multi_cox_table(all.vars = TRUE) |> gtsummary::add_nevent())|>
+ purrr::map(gtsummary::bold_p) |>
+ tbl_merged_named()
+ ls |>
+ gtsummary::modify_table_body(~filter(.x, variable == "pase_change"))
+ }) |>
+ (\(.x) {
+ gtsummary::tbl_stack(.x,group_header=names(.x))
+ })()
+
+
+
+
+
+
+# Code from: ssri_events.qmd
+targets::tar_config_set(store = here::here("_targets"))
+source(here::here("R/functions.R"))
+source(here::here("R/glmnet-reg.R"))
+library(targets)
+library(tidyverse)
+
+df <- targets::tar_read(df_all_data_formatted) |>
+ get_vars(vars.groups = c("clin","lifestyle.events","ses", "ssri")) |>
+ dplyr::rename(status=status.all,
+ time=time.all)
+df |>
+ dplyr::select(#-event.include,
+ -rtreat_placebo)|>
+ labelling_data() |>
+ gtsummary::tbl_summary(by=rtreat) |>
+ gtsummary::add_overall() #|>
+ # mask_micro_summary()
+df |>
+ dplyr::select(
+ -rtreat_placebo,
+ -pase_4#,
+ # -reg_bmi
+ ) |>
+ cox_regression(outcome.var = "rtreat",use.strata = FALSE) |>
+ gtsummary::tbl_regression(exponentiate = TRUE,
+ add_estimate_to_reference_rows = TRUE,
+ show_single_row = where(is.logical)) |>
+ gtsummary::bold_p() |>
+ fix_labels()
+df |>
+ dplyr::select(-rtreat_placebo) |>
+ cox_regression(outcome.var = "rtreat",all.vars = FALSE, use.strata = TRUE,include_formula = TRUE) |>
+ plot_survival_smooth()
+df |>
+ pase_cutter(drop.nas = TRUE,drop.pase = TRUE) |>
+ (\(.x) {
+ split(.x, .x$rtreat)
+ })() |> lapply(\(.x) {
+ ls <- list("Univariate"=.x |> dplyr::select(-rtreat_placebo, -rtreat) |>
+ standard_multi_cox_table(all.vars = FALSE),
+"Multivariate"=.x |> dplyr::select(-rtreat_placebo, -rtreat) |>
+ standard_multi_cox_table(all.vars = TRUE))|>
+ purrr::map(gtsummary::bold_p) |>
+ tbl_merged_named()
+ ls |>
+ gtsummary::modify_table_body(~filter(.x, variable == "pase_change"))
+ }) |> tbl_stack_named()
+ # gtsummary::tbl_stack(group_header=levels(factor(df$rtreat)))
+
+
+
diff --git a/2 Longterm/260315/cont_pase_sens.docx b/2 Longterm/260315/cont_pase_sens.docx
new file mode 100755
index 0000000..5bb4616
Binary files /dev/null and b/2 Longterm/260315/cont_pase_sens.docx differ
diff --git a/2 Longterm/260315/events_type_sens.docx b/2 Longterm/260315/events_type_sens.docx
new file mode 100755
index 0000000..9b60a40
Binary files /dev/null and b/2 Longterm/260315/events_type_sens.docx differ
diff --git a/2 Longterm/260315/functions.R b/2 Longterm/260315/functions.R
new file mode 100755
index 0000000..6affb00
--- /dev/null
+++ b/2 Longterm/260315/functions.R
@@ -0,0 +1,4131 @@
+# pop <- haven::read_sas(here::here("E:/rawdata/709203/Population/pop_talos.sas7bdat"))
+
+# sst <- list.files(here::here("E:/rawdata/709203/Eksterne data"), pattern = "*.sas7bdat", full.names = TRUE) |>
+# purrr::map(haven::read_sas)
+
+source(here::here("R/glmnet-reg.R"))
+
+#' Read all sas files in folder to list
+#'
+#' @param path folder path
+#'
+#' @return list
+sas2list <- function(path) {
+ ls <- list.files(here::here(path), pattern = "*.sas7bdat", full.names = TRUE) |>
+ purrr::map(haven::read_sas)
+ names(ls) <- list.files(here::here(path), pattern = "*.sas7bdat") |>
+ gsub(".sas7bdat", "", x = _) |>
+ toupper()
+ ls
+}
+
+
+#' Flatten multilevel list
+#'
+#' @param paths character vector of folder paths
+#'
+#' @return flattened list
+flatmultiread <- function(paths) {
+ paths |>
+ purrr::map(sas2list) |>
+ purrr::list_flatten()
+}
+
+# ls <- targets::tar_read(reg_data)
+
+# Vectors are kept for compatibility. Calling functions can be done from within other functions. So much easier!
+
+date_cutter <- function() as.Date("2023-01-01")
+date.cut <- date_cutter() # The earliest date will define the overall date cut
+
+censor_cutter <- function() 12
+censor.cut <- censor_cutter() # years of maximum follow up, due to small numbers
+
+vasc.diags <- c("I21", "I61", "I63", "I64","G45", "K28")
+
+#' Extract deaths from Dødsårsagsregiseret
+#'
+#' @param ls
+#' @param max.date
+#' @param diags.vasc
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(reg_data) |> get_deaths()
+get_deaths <- function(ls, max.date = date.cut, diags.vasc = vasc.diags) {
+
+
+ # vasc.death.tilg <- mapply(ls$DAR_T_DODSAARSAG_2[, "C_DODTILGRUNDL_ACME"],
+ # FUN = function(i) { # mapply inside apply call to handle rowvise matching in in matrix
+ # i_3 <- substr(i, 1, 3) # Substr only the 3 first characters to match by group
+ # i_3 %in% diags.vasc # Rowvise matching
+ # }
+ # )
+
+ vasc.death.tilg <- ls$DAR_T_DODSAARSAG_2[["C_DODTILGRUNDL_ACME"]] |> substr(1, 3) %in% diags.vasc
+
+
+ vasc.death.any <- apply(mapply(ls$DAR_T_DODSAARSAG_2[, c("C_DODTILGRUNDL_ACME", "C_DOD_1A", "C_DOD_1B", "C_DOD_1C", "C_DOD_1D")],
+ FUN = function(i) { # mapply inside apply call to handle rowvise matching in in matrix
+ i_3 <- substr(i, 1, 3) # Substr only the 3 first characters to match by group
+ i_3 %in% diags.vasc # Rowvise matching
+ }
+ ), 1, any) # Simplify to TRUE if any
+ #
+ vasc.death.other <- apply(mapply(ls$DAR_T_DODSAARSAG_2[, c("C_DOD_1A", "C_DOD_1B", "C_DOD_1C", "C_DOD_1D")],
+ FUN = function(i) { # mapply inside apply call to handle rowvise matching in in matrix
+ i_3 <- substr(i, 1, 3) # Substr only the 3 first characters to match by group
+ i_3 %in% diags.vasc # Rowvise matching
+ }
+ ), 1, any) # Simplify to TRUE if any
+
+ diag.either <- xor(vasc.death.other, vasc.death.tilg)
+ diag.both <- vasc.death.other & vasc.death.tilg
+
+ vasc.death.diags <-
+ apply(
+ mapply(
+ ls$DAR_T_DODSAARSAG_2[, c(
+ "C_DODTILGRUNDL_ACME",
+ "C_DOD_1A",
+ "C_DOD_1B",
+ "C_DOD_1C",
+ "C_DOD_1D"
+ )],
+ FUN = function(i) {
+ # mapply inside apply call to handle rowvise matching in in matrix
+ substr(i, 1, 3) # Substr only the 3 first characters to match by group
+ }
+ ),
+ 1,
+ paste,
+ collapse = ","
+ )
+
+ deaths.vasc <-
+ ls$DAR_T_DODSAARSAG_2 |>
+ dplyr::select(K_CPR, D_STATDATO) |>
+ dplyr::filter(vasc.death.tilg)
+
+ df.death.all <- ls$CPR3_T_PERSON |>
+ dplyr::filter(C_STATUS == 90) |> # People migrating are filtered (n ~ 1)
+ dplyr::select(c(
+ "V_PNR",
+ "D_STATUS_HEN_START"
+ )) |>
+ dplyr::left_join(deaths.vasc, by = c("V_PNR" = "K_CPR")) |>
+ dplyr::mutate(vasc_death = !is.na(D_STATDATO)) |>
+ dplyr::transmute(
+ PNR = V_PNR,
+ death_date = D_STATUS_HEN_START,
+ vasc_death = vasc_death
+ )
+
+ df.death.all |> dplyr::filter(death_date < max.date)
+}
+
+
+#' Title
+#'
+#' @param ls
+#' @param max.date
+#' @param diags.vasc
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' ls <- targets::tar_read(reg_list)
+get_events <- function(ls, max.date = date.cut, diags.vasc = vasc.diags) {
+ ident.vars <- toupper(c("_recnum", "_cpr"))
+
+ df.vasc.events.lpr <- ls$LPR_T_DIAG |>
+ dplyr::mutate(dia.f = substr(C_DIAG, 2, 4)) |> # Subsets only 2:4 chars, to get main group
+ dplyr::filter(
+ dia.f %in% diags.vasc
+ # & # Filters to only include pre-defined diagnoses
+ # C_DIAGTYPE=="A"
+ ) |> # Filters to only include if main diagnosis
+ dplyr::select(
+ ends_with(ident.vars),
+ "C_DIAG",
+ "C_DIAGTYPE"
+ ) |>
+ dplyr::left_join(
+ ls$LPR_T_ADM |> dplyr::select(
+ tidyselect::ends_with(ident.vars),
+ "D_INDDTO",
+ "C_INDM",
+ "D_UDDTO",
+ "C_UDM",
+ "C_SGH",
+ "C_AFD",
+ "C_ADIAG"
+ ),
+ by = c("V_RECNUM" = "K_RECNUM")
+ )
+
+ ## LPR-F - LPR 3
+
+ ident.vars.lpr3 <- toupper(c("cpr", "_kontakt", "DW_EK_FORLOEB"))
+
+ df.vasc.events.lpr3 <- ls$LPR_F_DIAGNOSER |>
+ dplyr::mutate(dia.f = substr(DIAGNOSEKODE, 2, 4)) |> # Subsets only 2:4 chars, to get main group
+ dplyr::filter(
+ dia.f %in% diags.vasc
+ # & # Filters to only include pre-defined diagnoses
+ # DIAGNOSETYPE=="A"
+ ) |> # Filters to only include if main diagnosis
+ dplyr::select(
+ ends_with(ident.vars.lpr3),
+ "DIAGNOSEKODE",
+ "DIAGNOSETYPE"
+ ) |>
+ dplyr::left_join(
+ ls$LPR_F_KONTAKTER |> dplyr::select(
+ ends_with(ident.vars.lpr3),
+ "DATO_START",
+ "DATO_SLUT",
+ "PRIORITET"
+ ),
+ by = c("DW_EK_KONTAKT")
+ ) |>
+ dplyr::mutate(PRIORITET = as.character((PRIORITET == "ATA1") + 1)) # If ATA1 then 1, if not (ATA3) then 2, cowboy coding
+
+ df.vasc.events <- dplyr::full_join(df.vasc.events.lpr, df.vasc.events.lpr3, by = c(
+ "V_CPR" = "CPR",
+ "C_DIAG" = "DIAGNOSEKODE",
+ "C_DIAGTYPE" = "DIAGNOSETYPE",
+ "D_INDDTO" = "DATO_START",
+ "D_UDDTO" = "DATO_SLUT",
+ "C_INDM" = "PRIORITET"
+ )) |>
+ dplyr::mutate(date.event = D_INDDTO)
+
+ df.vasc.events |> dplyr::filter(date.event < max.date)
+}
+
+
+# deaths <- targets::tar_read(df_deaths)
+# events <- targets::tar_read(df_events)
+# clinical <- targets::tar_read(pop_df)
+
+
+#' Filter only truly considered events
+#'
+#' @param data
+#'
+#' @return tibble
+define_events <- function(data) {
+ data |> dplyr::filter(
+ C_DIAGTYPE == "A", # Primary diagnosis
+ C_INDM == "1", # Acutely admitted
+ difftime(date.event, rdate, units = "days") > 5 # More than five (5) days after randomisation/primary stroke
+ )
+}
+
+#' The big merger and filter of events
+#'
+#' @param ls list of events, deaths and clinical
+#'
+#' @return tibble
+#'
+#' @examples
+#' ls <- list(events = targets::tar_read(df_events), deaths = targets::tar_read(df_deaths), clinical = targets::tar_read(pop_df))
+#' ls |> all_events()
+all_events <- function(ls) {
+ # ls <- list(events = targets::tar_read(df_events), deaths = targets::tar_read(df_deaths), clinical = targets::tar_read(pop_df))
+ df.events <- dplyr::full_join(
+ purrr::pluck(ls, "events"),
+ purrr::pluck(ls, "deaths") |>
+ dplyr::mutate(
+ # These are just added to ease later filtering
+ C_DIAGTYPE = "A",
+ C_INDM = "1"
+ ), # Ads diagtype=A, C_INDM=1 for easier sorting later
+ by = c(
+ "V_CPR" = "PNR",
+ "date.event" = "death_date",
+ "C_DIAGTYPE",
+ "C_INDM"
+ )
+ ) |>
+ dplyr::full_join(dplyr::select(purrr::pluck(ls, "clinical"), c("PNR", "rdate", "enddate")),
+ by = c("V_CPR" = "PNR")
+ ) |>
+ dplyr::arrange(date.event) |> # Sort by event date
+ dplyr::mutate(event.type = dplyr::if_else(
+ is.na(C_DIAG),
+ dplyr::if_else(vasc_death, "death.vasc", "death.other"),
+ substr(C_DIAG, 1, 4)
+ ))
+
+ df.events |>
+ dplyr::group_split(V_CPR) |> # Splits by CPR
+ purrr::map(define_events) |> # Custom function to specify criteria for events
+ purrr::discard(\(x) nrow(x) == 0) |> # Discard empty elements
+ purrr::map(dplyr::transmute, # Saving only relevant variables
+ CPR = V_CPR,
+ date.event,
+ event.type)
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' ls <- list(events = targets::tar_read(df_events), deaths = targets::tar_read(df_deaths), clinical = targets::tar_read(pop_df))
+#' ls |> merge_events()
+merge_events <- function(data){
+ data|>
+ all_events() |>
+ purrr::modify(\(x) x[1, ]) |> # Select first event
+ purrr::list_rbind()
+}
+
+
+#' Count number of prescriptions of given ATC group for each CPR
+#'
+#' @param atc.code atc group
+#' @param data dataset from LMS
+#'
+#' @return tibble
+count_treat <- function(atc.code, data) {
+ data |>
+ dplyr::filter(grepl(atc.code, ATC)) |>
+ dplyr::count(CPR) |>
+ dplyr::filter(n > 1)
+}
+
+
+#' Get LMS data
+#'
+#' @param ls list of datasets
+#' @param max.date filter date for max inclusion
+#' @param atc.tbl tibble of atc codes
+#'
+#' @return tibble
+get_lms <- function(ls, max.date, atc.tbl) {
+ ls$LMS_EPIKUR |>
+ dplyr::filter(grepl(atc.tbl[1], ATC)) |>
+ dplyr::left_join(ls$LMS_LAEGEMIDDELOPLYSNINGER) |>
+ dplyr::filter(as.Date(ACTDATE) < max.date)
+}
+
+#' Get count of treated patients from LMS data
+#'
+#' @param ls list of datasets
+#' @param max.date filter date for max inclusion
+#' @param atc.tbl tibble of atc codes
+#'
+#' @return tibble
+get_treated <- function(ls,
+ max.date = date.cut,
+ atc.tbl = c(
+ atc.antidep = "N06A",
+ atc.ssri = "N06AB"
+ )) {
+ df <- atc.tbl |>
+ purrr::map(count_treat, get_lms(ls, max.date, atc.tbl)) |>
+ purrr::reduce(dplyr::full_join, by = "CPR")
+ colnames(df) <- c("CPR", paste0("n.", names(atc.tbl)))
+ df
+}
+
+#' BMI calc, drops
+#'
+#' @param w weight in kg
+#' @param h height in cm
+#' @param data data set
+#'
+#' @return tibble
+bmi_calc <- function(data, drop = TRUE) {
+ # After inspection, both h+w are missing if any is missing
+ out <- data |> dplyr::mutate(reg_bmi = suppressWarnings(as.numeric(dplyr::if_else(reg_vaegt == "NA", reg_vaegt_anslaaet, reg_vaegt)) / ((as.numeric(reg_hojde) / 100)^2)))
+
+ if (drop) {
+ out <- out |>
+ dplyr::select(-dplyr::all_of(c("reg_vaegt", "reg_vaegt_anslaaet", "reg_hojde")))
+ }
+ out
+}
+
+is_equal <- function(data, test) {
+ data == test
+}
+
+#' Load clinical population data
+#'
+#' @return tibble
+#' @examples
+#' get_clinical() |> colnames()
+#'
+get_clinical <- function() {
+ sas2list("E:/rawdata/709203/Population")[[2]] |>
+ correct_na() |>
+ dplyr::mutate(
+ reg_smoker = dplyr::case_match(
+ reg_rygning, "1" ~ TRUE,
+ c("2", "3", "4") ~ FALSE,
+ "9" ~ NA
+ ),
+ # Living alone defined as not together with somebody
+ reg_alone = dplyr::case_match(
+ reg_civil, "1" ~ FALSE,
+ c("2", "3") ~ TRUE,
+ "9" ~ NA
+ ),
+ reg_more_alc = dplyr::case_match(
+ reg_alkohol, "1" ~ FALSE,
+ "2" ~ TRUE,
+ "9" ~ NA
+ ),
+ reg_female = sex == "Kvinde",
+ dplyr::across(
+ .cols = c(
+ "reg_hyperten",
+ "reg_diabetes",
+ "reg_atriefli",
+ "reg_perifer_arteriel",
+ "reg_tidl_tci",
+ "reg_ami"
+ ),
+ ~ dplyr::case_match(
+ .x, "1" ~ TRUE,
+ "2" ~ FALSE,
+ "9" ~ NA
+ )
+ ),
+ dplyr::across(
+ .cols = c(
+ "reg_trombolyse",
+ "reg_trombektomi"
+ ),
+ ~ dplyr::case_match(
+ .x, "1" ~ TRUE,
+ c("3","4") ~ FALSE,
+ "9" ~ NA
+ )
+ ),
+ reg_any_perf = reg_trombolyse | reg_trombektomi
+ ) |>
+ bmi_calc()
+}
+
+# get_clinical() |> pragmatic_imputation() |> skimr::skim()
+
+# get_clinical <- function() {
+# sas2list("E:/rawdata/709203/Population")[[2]] |>
+# dplyr::mutate(
+# reg_smoker = reg_rygning == 1,
+# reg_cohabiting = reg_civil == 1,
+# reg_more_alc = reg_alkohol == 2,
+# reg_female = sex == "Kvinde",
+# dplyr::across(.cols = c("reg_hyperten", "reg_diabetes", "reg_atriefli", "reg_perifer_arteriel", "reg_tidl_tci", "reg_ami", "reg_trombolyse", "reg_trombektomi"), ~ .x == 1),
+# reg_any_perf = reg_trombolyse | reg_trombektomi
+# ) |>
+# bmi_calc()
+# }
+
+pragmatic_imputation <- function(data, vec=c("reg_trombolyse", "reg_trombektomi","reg_any_perf")) {
+ # Assumes, if not TRUE, then FALSE (gets rid of NAs)
+ data |> dplyr::mutate(dplyr::across(.cols = tidyselect::any_of(vec), ~dplyr::if_else(.x,TRUE,FALSE,missing = FALSE)))
+}
+
+#' Load all registry tables to list
+#'
+#' @return list
+get_reg_ls <- function() {
+ flatmultiread(c("E:/rawdata/709203/Eksterne data", "E:/rawdata/709203/Grunddata"))
+}
+
+
+#' Definition of relevant variables from DST tables
+#'
+#' @return
+define_dst_vars <- function() {
+ list(
+ bef = c("PNR", "FAMILIE_ID"),
+ faik = c("FAMILIE_ID", "FAMAEKVIVADISP_13", "FAMSOCIOGRUP_13"),
+ ras = c("PNR", "SOC_STATUS_KODE"),
+ uddf = c("PNR", "HFAUDD")
+ )
+}
+
+#' Simple wrapper of dplyr::select
+#'
+#' @param data
+#' @param vars
+#'
+#' @return
+select_vars <- function(data, vars) {
+ data |> dplyr::select({{ vars }})
+}
+
+#' Subset DST tables to only include relvant variables.
+#'
+#' @param ls List of all registry tables
+#'
+#' @return
+get_dst_tables <- function(ls) {
+ dst_vars <- define_dst_vars()
+ dst_tbl <- toupper(names(dst_vars))
+ ls.all <- purrr::map(seq_along(dst_vars), function(i) {
+ ls.reg <- ls[grepl(paste0("^", dst_tbl[i]), names(ls))] |> purrr::map(select_vars, vars = dst_vars[[i]])
+ names(ls.reg) <- paste0("y", stringr::str_extract(names(ls.reg), "[0-9]{4}"))
+ ls.reg
+ })
+ names(ls.all) <- dst_tbl
+ ls.all
+}
+
+#' Wrapper to generate string matching pattern for stringr::str_detect()
+#'
+#' @param data
+#'
+#' @return
+match_str <- function(data) {
+ paste0("[", paste0(data, collapse = ","), "]")
+}
+
+#' Wrapper to generate string matching pattern for grepl()
+#'
+#' @param data character vector
+#'
+#' @return
+match_str_grepl <- function(data) {
+ paste0("(", paste0(data, collapse = "|"), ")")
+}
+
+# get_dst_tables(ls)
+
+#' Generate sequence of previous N length
+#'
+#' @param data numeric vector of length 1
+#'
+#' @return
+#'
+#' @examples
+#' last5y(10)
+#' last5y(c(10, 6, 3))
+lastNy <- function(data, n = 5) {
+ paste0("y", seq((data - n), data) - 1)
+}
+
+#' Filter PNR (cpr) across list elements
+#'
+#' @param data list of tibbles to pass through
+#' @param index index number (PNR/CPR)
+#'
+#' @return tibble
+filterCPRacross <- function(data, index) {
+ data |>
+ purrr::map(function(i) {
+ i[i$PNR == index, ]
+ }) |>
+ purrr::list_rbind()
+}
+
+#' Summarise data from last 5 years prior to inclusion
+#'
+#' @param data list with
+#' @param v.median variables to get median
+#' @param v.latest variables to get latest
+#' @param v.mean variables to get mean
+#'
+#' @return tibble
+previousNyears <- function(data, data.clin, n.years = 5, v.median = NULL, v.latest = c("FAMSOCIOGRUP_13", "SOC_STATUS_KODE"), v.mean = c("FAMAEKVIVADISP_13")) {
+ df.cpryear <- data.clin |> dplyr::transmute(
+ CPR = PNR,
+ year = as.numeric(format(as.Date(rdate), "%Y"))
+ )
+
+ seqs <- purrr::map(df.cpryear$year, lastNy, n = n.years)
+
+ seq_along(seqs) |>
+ purrr::map(function(i) {
+ df <- data[c(seqs[[i]])] |>
+ filterCPRacross(index = df.cpryear$CPR[i]) |>
+ dplyr::group_by(PNR) |>
+ dplyr::summarise(
+ dplyr::across(tidyselect::any_of(v.latest), \(x) tail(x, n = 1), .names = "{.col}.latest"),
+ dplyr::across(tidyselect::any_of(v.mean), \(x) mean(x, na.rm = TRUE), .names = "{.col}.{n.years}.mean"),
+ dplyr::across(tidyselect::any_of(v.median), \(x) median(x, na.rm = TRUE), .names = "{.col}.{n.years}.median")
+ )
+ }) |>
+ purrr::list_rbind()
+}
+
+
+#' Extract relevant and summarised data from BAF and FAIK
+#'
+#' @param data list of dst data tables
+#'
+#' @return tibble
+#'
+#' @examples
+#' get_reg_ls() |>
+#' get_dst_tables() |>
+#' get_beffaikras()
+get_beffaikras <- function(data, clin.data = get_clinical()) {
+ data <- data[stringr::str_detect(match_str(c("BEF", "FAIK", "RAS")), names(data))] |> purrr::list_flatten()
+
+ years <- stringr::str_extract(names(data), "y[0-9]{4}")
+
+ years[duplicated(years)] |>
+ purrr::map(grep, years) |>
+ purrr::map(function(i) {
+ data[c(i)] |> purrr::reduce(dplyr::full_join)
+ }) |>
+ purrr::set_names(years[duplicated(years)]) |>
+ previousNyears(data.clin = clin.data)
+
+ ## BEF
+ ## # Befolkningsoversigt. Data skal bruges for at kunne udtrække husstandsindkomst.
+ ## FAIK
+ ## # Familieindkomst. Familie id skal flættes med ID fra BEF for hvert år for at tage hensyn til evt skifte i status.
+ ## FAMAEKVIVADISP_13 er relevante variabel for ækvivaleret indkomst
+ ## Der findes også familiesocioøkonomisk status. Gør som Sine. Be done with it!
+}
+
+#' Title
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- read_edu_level()
+#' data |> dplyr::count(ISCED)
+read_edu_level <- function() {
+ haven::read_dta("E:/Formater/SAS formater i Danmarks Statistik/STATA_datasaet/Disced/c_audd_level_l1l4_k.dta") |>
+ dplyr::transmute(
+ HFAUDD = start,
+ ISCED = AUDD_LEVEL_L1L4_K
+ )
+}
+
+haven::read_dta(
+ "E:/Formater/SAS formater i Danmarks Statistik/STATA_datasaet/Disced/c_audd_level_l1l3_k.dta") |>
+ dplyr::count(AUDD_LEVEL_L1L3_K)
+
+# ls <- get_reg_ls() |> get_dst_tables()
+
+get_uddf <- function(ls) {
+ ls |>
+ purrr::pluck("UDDF") |>
+ purrr::pluck(1) |>
+ dplyr::mutate(HFAUDD = as.character(HFAUDD)) |>
+ dplyr::left_join(read_edu_level()) |>
+ dplyr::group_by(PNR) |>
+ dplyr::summarise(ISCED = max(ISCED), .groups = "keep") |>
+ dplyr::mutate(
+ ISCED = as.numeric(ISCED),
+ ISCED_lvl = dplyr::case_match(ISCED, 0:2 ~ "low",
+ 3:4 ~ "medium",
+ 5:9 ~ "high",
+ .default = NA
+ ),
+ ISCED_bin = dplyr::case_match(ISCED, 0:3 ~ "low",
+ 4:9 ~ "high",
+ .default = NA
+ )
+ )
+}
+
+
+#' Collects all relevant variables from DST tables
+#'
+#' @param ls list of all registry tables
+#' @param df.clin clinical data set
+#'
+#' @return tibble
+#' @examples
+#' get_reg_ls() |> get_dst(df.clin = get_clinical())
+get_dst <- function(ls, df.clin) {
+ ls_dst <- get_dst_tables(ls)
+ ls_dst |>
+ ## BEFxFAIKxRAS
+ get_beffaikras(clin.data = df.clin) |>
+ dplyr::full_join(
+ ## UDDF
+ get_uddf(ls_dst)
+ )
+}
+
+#' Eases pipe renaming of columns
+#'
+#' @param data tibble, list or other object, for which names() makes sense. see ?setNames
+#' @param prefix prefix to add
+#' @param exclude names not to modify
+#' @param new.names character vector of all new names
+#'
+#' @return object of same class as data
+#'
+#' @examples
+#' set_colnames(data = mtcars, prefix = "WOW", exclude = "mpg")
+set_colnames <- function(data, new.names = NULL, prefix = NULL, exclude = c("PNR", "CPR"), prefix.sep = "_") {
+ if (is.null(new.names)) {
+ nms <- names(data)
+ } else {
+ nms <- new.names
+ }
+
+ if (is.null(prefix)) {
+ nms.mod <- nms
+ } else {
+ nms.mod <- paste(prefix, nms, sep = prefix.sep)
+ }
+
+ setNames(
+ object = data,
+ nm = dplyr::if_else(stringr::str_detect(match_str(exclude), nms),
+ nms,
+ nms.mod
+ )
+ )
+}
+
+
+#' Store of variable names for data sub-setting
+#'
+#' @return list
+#' @examples
+#' define_variables()
+define_variables <- function() {
+ list(
+ talos = c(
+ "age",
+ "reg_female",
+ "nihss_0",
+ "reg_trombolyse",
+ "reg_trombektomi",
+ # "rtreat",
+ "pase_0",
+ "reg_alone",
+ "reg_bmi",
+ # "reg_hojde",
+ # "reg_vaegt_alt",
+ "reg_smoker",
+ "reg_more_alc",
+ "reg_hyperten",
+ "reg_diabetes",
+ "reg_tidl_tci",
+ "reg_atriefli",
+ "reg_ami",
+ "reg_perifer_arteriel"
+ ),
+ clin = c(
+ "age",
+ "reg_female",
+ "nihss_0",
+ "reg_trombolyse",
+ "reg_trombektomi",
+ # "rtreat",
+ "rtreat_placebo"),
+ lifestyle=c(
+ "pase_0",
+ "pase_4",
+ "reg_alone",
+ "reg_bmi",
+ # "reg_hojde",
+ # "reg_vaegt_alt",
+ "reg_smoker",
+ "reg_more_alc",
+ "reg_hyperten",
+ "reg_diabetes",
+ "reg_tidl_tci",
+ "reg_atriefli",
+ "reg_ami",
+ "reg_perifer_arteriel"),
+ lifestyle.events=c(
+ "pase_0",
+ "pase_4",
+ "reg_alone",
+ # "reg_bmi",
+ # "reg_hojde",
+ # "reg_vaegt_alt",
+ "reg_smoker",
+ "reg_more_alc",
+ "reg_hyperten",
+ "reg_diabetes",
+ # "reg_tidl_tci",
+ "reg_atriefli",
+ # "reg_perifer_arteriel",
+ "reg_ami"),
+ lifestyle.bmi=c(
+ "reg_bmi"
+ ),
+ ses=c(
+ # "soc_status",
+ # "soc_status_work",
+ "soc_status_nowork",
+ # "fam_indk",
+ "fam_indk_hl",
+ # "fam_indk_high",
+ # "fam_indk_low",
+ # "edu_level",
+ # "edu_high",
+ # "edu_low",
+ "edu_level_hl"
+ ),
+ assess.events = c(
+ "who_4",
+ "mdi_4",
+ "mfi_gen_4",
+ "mrs_4_above1",
+ "time",
+ "status",
+ "event.include"
+ ),
+ assess.events.pre = c(
+ "who_4",
+ "mdi_4",
+ "mfi_gen_4",
+ "mrs_0_above0",
+ "time",
+ "status",
+ "event.include"
+ ),
+ assess.pred = c(
+ "who_0",
+ "mrs_0_above0"
+ ),
+ extra = c(
+ "soc_status",
+ "pase_0",
+ "pase_4" ,
+ "event"
+ ),
+ cpr = "PNR",
+ ssri=c("rtreat",
+ "time.all",
+ "status.all",
+ "rdate",
+ "enddate"),
+ quartiles = c(
+ "pase_0_quartile",
+ "pase_4_quartile"
+ )
+ )
+}
+
+#' Get var names in vector from group names. Possibility to keep all vars for as log as possible. Can be supplied to `gtsummary` functions
+#'
+#' @param groups vector of group names. See names(define_variables()) for options
+#'
+#' @return
+#' @export
+#'
+#' @examples
+get_var_vec <- function(v.groups){
+ define_variables()[{{ v.groups }}] |> purrr::list_c()
+}
+
+#' SUbsets dataset based on variable group names as defined
+#'
+#' @param vector character vector of category names
+#'
+#' @return character vector
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> get_vars(c("universal", "events"))
+get_vars <- function(data, vars.groups, vars.vec=NULL) {
+ data |> dplyr::select(tidyselect::any_of(c("pase_0","pase_4",".imp",".id",get_var_vec(vars.groups),vars.vec)))
+}
+
+
+
+#' Collect all relevant data for the events analysis data set
+#'
+#' @param ls ls of tibbles
+#'
+#' @return tibble
+#'
+#' @examples
+#' ls <- targets::tar_read(list_filtered)
+#'
+collectall <- function(ls) {
+ purrr::pluck(ls, "clinical") |>
+ dplyr::left_join(purrr::pluck(ls, "all_events") |> set_colnames(prefix = "event"), by = c("PNR" = "CPR")) |>
+ dplyr::left_join(purrr::pluck(ls, "dst") |> set_colnames(prefix = "dst"), by = "PNR")
+}
+
+
+## Formatting for analysis
+
+#' Function to cut and group PASE data
+#'
+#' @param data data set including pase_0 and _4
+#'
+#' @return tibble
+pase_cutter <- function(data, pase.rev = TRUE, drop.pase = FALSE, drop.nas=FALSE) {
+ data.classes <- class(data)
+ if ("mids" %in% data.classes) {
+ data <- data |> mice::complete(action = "long", include = TRUE)
+ }
+
+ data <- data |>
+ dplyr::mutate(dplyr::across(.cols = c("pase_0", "pase_4"), \(i) {
+ cut(x = i, breaks = quantile(pase_0, na.rm = TRUE), labels = 1:4, include.lowest = TRUE)
+ }, .names = "{.col}_quartile")) |>
+ dplyr::mutate(pase_change = factor(dplyr::case_when(
+ pase_0_quartile == 1 & pase_4_quartile == 1 ~ "Persistently low",
+ pase_0_quartile %in% 2:4 &
+ pase_4_quartile %in% 2:4 ~ "Persistently high",
+ pase_0_quartile == 1 &
+ pase_4_quartile %in% 2:4 ~ "Increase",
+ pase_0_quartile %in% 2:4 &
+ pase_4_quartile == 1 ~ "Decrease"
+ ), ordered = FALSE),
+ pase_change=factor(pase_change,levels=c("Persistently low", "Increase", "Decrease", "Persistently high")))
+
+
+ if (drop.pase) {
+ data <- data |> dplyr::select(-tidyselect::all_of(c("pase_0_quartile", "pase_4_quartile", "pase_0", "pase_4")))
+ }
+
+
+ if (pase.rev) {
+ data <- data |> dplyr::mutate(
+ pase_change = factor(pase_change, levels = c("Persistently high", "Decrease", "Increase", "Persistently low"))
+ )
+ }
+
+ if (drop.nas) {
+ data <- data |>
+ dplyr::filter(!is.na(pase_change))
+ }
+
+
+ if ("mids" %in% data.classes) {
+ data |> mice::as.mids()
+ } else {
+ data
+ }
+}
+
+# as.Date(data$event_date.event)
+define_status_time <- function(data) {
+ data |> dplyr::mutate(dplyr::across(c("rdate", "enddate", "event_date.event"), ~ as.Date(.x)),
+ time = difftime(dplyr::if_else(is.na(event_date.event), date_cutter(), event_date.event), enddate) |> lubridate::time_length("years"),
+ time.all = difftime(dplyr::if_else(is.na(event_date.event), date_cutter(), event_date.event), rdate) |> lubridate::time_length("years"),
+ status = as.integer(!is.na(event_event.type)),
+ time = dplyr::if_else(time > censor_cutter(), censor_cutter(), time),
+ time.all = dplyr::if_else(time.all > censor_cutter(), censor_cutter(), time.all),
+ status = dplyr::if_else(time > censor_cutter(), FALSE, status),
+ status.all = dplyr::if_else(time.all > censor_cutter(), FALSE, status),
+ # status= dplyr::if_else(status,1,0),
+ event.include = time > 0
+ )
+}
+
+# as.integer(c(TRUE,FALSE))
+
+#' Grouping soc status
+#'
+#' @param data tibble
+#'
+#' @return tibble
+group_soc_status <- function(data) {
+ data |>
+ dplyr::mutate(
+ soc_status = factor(dplyr::case_when(
+ soc_status < 200 ~ "work",
+ soc_status == 200 ~ "off",
+ # only ~4 in the data set off work
+ soc_status >= 200 ~ "outside"
+ )),
+ soc_status_work = soc_status == "work",
+ soc_status_nowork = !soc_status_work
+ )
+}
+
+#' Correction of character NA
+#'
+#' @param data tibble
+#' @param char.missing character vector of entries to consider as NA
+#'
+#' @return tibble
+correct_na <- function(data, char.missing = "NA") {
+ data |> dplyr::mutate(dplyr::across(dplyr::where(is.character), ~ dplyr::na_if(.x, char.missing)))
+}
+
+#' Formatting the complete data set
+#'
+#' @param data the merged raw data set
+#'
+#' @return tibble
+#' @examples
+#' ds <- targets::tar_read(df_all_data) |>
+#' data_formatting() |>
+#' subset_df("mdi")
+#' ds |> skimr::skim()
+#' ds |> View()
+data_formatting <- function(data) {
+ to_logical <- grep(match_str_grepl(c("missings", "incompletes")), names(data))
+
+ suppressWarnings(
+ data |>
+ correct_na() |>
+ dplyr::mutate(dplyr::across(all_of(to_logical), ~ .x == "TRUE")) |>
+ dplyr::mutate(
+ # This uses the work-corrected score
+ # pase_0 = dplyr::if_else(pase_score_missings_w_0 | is.na(talos_pase10_0), NA, pase_score_sum_w_0),
+ # pase_4 = dplyr::if_else(pase_score_missings_w_4 | is.na(talos_pase10_4), NA, pase_score_sum_w_4),
+ # Below is the plain PASE scor used according to the manual used with TALOS
+ pase_0 = dplyr::if_else(pase_score_missings_0, NA,pase_score_sum_0),
+ pase_4 = dplyr::if_else(pase_score_missings_4, NA,pase_score_sum_4),
+ who_0 = as.numeric(talos_who07_0),
+ who_4 = as.numeric(talos_who07_4),
+ mrs_0 = factor(substr(talos_mrs01_0, 1, 1), ordered = FALSE),
+ mrs_0_above0 = (as.numeric(mrs_0) - 1) > 0,
+ mrs_4 = factor(substr(talos_mrs01_4, 1, 1), ordered = FALSE),
+ mrs_4_above1 = (as.numeric(mrs_4) - 1) > 1,
+ mdi_4 = as.numeric(talos_mdi12_4),
+ mfi_gen_4 = as.numeric(talos_mfi_gen_4),
+ nihss_0 = as.numeric(talos_nihss16_0),
+ soc_status = dst_SOC_STATUS_KODE.latest,
+ fam_indk = cut(dst_FAMAEKVIVADISP_13.5.mean,
+ breaks = quantile(dst_FAMAEKVIVADISP_13.5.mean, probs = seq(0, 1, 1 / 3), na.rm = TRUE),
+ ordered_results = FALSE,
+ labels = c("low", "medium", "high"),
+ include.lowest = TRUE
+ ),
+ fam_indk_bin = cut(dst_FAMAEKVIVADISP_13.5.mean,
+ breaks = quantile(dst_FAMAEKVIVADISP_13.5.mean, probs = seq(0, 1, 1 / 2), na.rm = TRUE),
+ ordered_results = FALSE,
+ labels = c("low", "high"),
+ include.lowest = TRUE
+ ),
+ fam_indk_hl=forcats::fct_rev(fam_indk),
+ fam_indk_high = dplyr::if_else(fam_indk_bin=="high",TRUE,FALSE),
+ fam_indk_low = dplyr::if_else(fam_indk_bin=="low",TRUE,FALSE),
+ edu_level = factor(dst_ISCED_lvl, ordered = FALSE, levels = c("low", "medium", "high")),
+ edu_high = dplyr::if_else(dst_ISCED_bin=="high",TRUE,FALSE),
+ edu_low = dplyr::if_else(dst_ISCED_lvl=="low",TRUE,FALSE),
+ edu_level_hl=forcats::fct_rev(edu_level),
+ rtreat_placebo=rtreat=="Placebo",
+ event = factor(event_event.type)
+ ) |>
+ group_soc_status() |>
+ define_status_time() |>
+ pragmatic_imputation(vec = c("reg_trombolyse", "reg_trombektomi","reg_any_perf"))
+ )
+}
+
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |>
+#' events_ready() |>
+#' View()
+events_ready <- function(data,v.groups=c("clin","lifestyle.events","ses", "assess.events"),vars.vec=NULL) {
+ out <- data |>
+ get_vars(vars.groups = v.groups,vars.vec=vars.vec)
+
+
+ if ("event.include" %in% names(out)){
+ out <- out |>
+ dplyr::filter(event.include) |>
+ # dplyr::filter(!is.na(pase_0),!is.na(pase_4))|>
+ dplyr::select(-tidyselect::all_of("event.include"))# |>
+ # labelling_data()
+ }
+
+ return(out)
+}
+
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted)
+#' data |> events_ready() |>
+#' View()
+talos_ready <- function(data,v.groups=c("talos","ssri")) {
+ data |>
+ get_vars(vars.groups = v.groups) |>
+ dplyr::mutate(inc_time=lubridate::time_length(difftime(enddate,rdate),"years"),
+ rtreat=factor(rtreat,labels=c("Active","Placebo"))) |>
+ dplyr::select(-rdate,-enddate) |>
+ dplyr::rename(status="status.all",
+ time="time.all") |>
+ labelling_data()
+}
+
+
+#' A good-enough approximation of the defined analysis-population in the TALOS protocol
+#'
+#' In practice this includes patients in the study for more than ~35 days
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+talos_analysis_pop_filter <- function(data){
+ data |>
+ (\(.x){
+ .x |> split(.x$rtreat)
+ })() |>
+ purrr::map2(c(268,284),\(.x,.y){
+ .x |>
+ dplyr::slice_max(inc_time,n = .y,with_ties = FALSE)
+ }) |>
+ dplyr::bind_rows()
+}
+
+
+talos_analysis_pop_filter_imp <- function(data){
+ data |>
+ mice::complete(action = "long", include = TRUE) |>
+ (\(.x){
+ split(.x,.x$.imp)
+ })() |>
+ purrr::map(talos_analysis_pop_filter) |>
+ dplyr::bind_rows() |>
+ mice::as.mids()
+}
+
+events_table <- function(data,by){
+ list(
+ "Overall"=data,
+ split(data,data[by])
+ ) |>
+ purrr::list_flatten() |>
+ purrr::imap(\(.x,.i){
+ .x |>
+ dplyr::summarise(
+ group=.i,
+ py = sum(time),
+ events = sum(status),
+ events_pr_100 = 100 * events / py
+ )
+ }) |>
+ dplyr::bind_rows() |>
+ setNames(c("group","Patient Years","Events","Events pr 100 patient years")) |>
+ tidyr::pivot_longer(-group) |>
+ tidyr::pivot_wider(names_from = group,values_from = value)|>
+ gt::gt() |>
+ gt::fmt_number(columns = -1, decimals = 1)
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+talos_imp <- function(data){
+ fun_impute(data=data,outcome.vars = c("time","status"),
+ ignore = c("inc_time","rtreat"),
+ pragmatic.reg = FALSE,
+ pase.mod = FALSE)
+}
+
+#' Title
+#'
+#' @param data
+#' @param v.groups
+#'
+#' @return
+#' @export
+#'
+#' @examples
+events_ready_small <- function(data,v.groups=c("clin","lifestyle.events","ses", "assess.events")) {
+ data |>
+ get_vars(vars.groups = v.groups) |>
+ dplyr::filter(event.include) |>
+ dplyr::filter(!is.na(pase_0),!is.na(pase_4))|>
+ dplyr::select(-tidyselect::all_of("event.include"))# |>
+ # labelling_data()
+}
+
+#' Title
+#'
+#' @param date
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted)
+#'
+#' data |>
+#' prediction_ready() |>
+#' View()
+prediction_ready <- function(data,
+ var.grps=c("clin","lifestyle","ses", "assess.pred")) {
+ data |>
+ get_vars(var.grps)|>
+ dplyr::filter(!is.na(pase_0),!is.na(pase_4))#|>
+ # labelling_data()
+}
+
+## Data inspection and exploration
+##
+##
+#' Title
+#'
+#' @param data
+#' @param subdf
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data) |>
+#' subset_df() |>
+#' View()
+subset_df <- function(data, subdf = "pase") {
+ data[grepl(paste0("^(", paste("PNR", subdf, paste0("talos_", subdf), sep = "|"), ")"), names(data))]
+}
+
+#' Imputation as a function, includes "pragmatic imputation"
+#'
+#' @param data
+#' @param outcome.vars
+#' @param ignore
+#' @param pragmatic.reg
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted) |> events_ready()
+#' data |> labelling_data() |> fun_impute()
+fun_impute <- function(data, outcome.vars = c("status", "time"), ignore = NULL,pragmatic.reg=TRUE,pase.mod=FALSE) {
+ # data |> mice::md.pattern()
+ if (pragmatic.reg){
+ data <- data |> pragmatic_imputation()
+ }
+
+ ## Excluding entries with missing outcome measures
+ data <- data |>
+ dplyr::filter(!dplyr::if_any(tidyselect::all_of(c(outcome.vars)), ~ is.na(.x)))
+
+ init <- data |>
+ mice::mice(maxit = 0)
+
+ meth <- init$method
+ meth[ignore] <- ""
+
+ pred <- init$predictorMatrix
+ pred[, c(outcome.vars)] <- 0
+
+ # data_out <- data |> mice::futuremice(
+ # pred = pred,
+ # method = meth,
+ # print = FALSE,
+ # parallelseed = 8123,
+ # use.logical = FALSE,
+ # maxit = 20,
+ # m = 10
+ # )
+
+ data_out <- data |> mice::mice(
+ pred = pred,
+ method = meth,
+ print = FALSE,
+ seed = 8123,
+ maxit = 20,
+ m = 10
+ )
+
+ if (pase.mod){
+ data_out <- data_out |> pase_cutter_mids()
+ }
+
+ data_out
+
+ # lattice::densityplot(imp_data)
+ # Regarding EVENTS
+ #
+ # On inspection/eye-balling densityplots looks reasonable with the current settings
+ #
+}
+
+#' Function to cut PASE in mids object
+#'
+#' @param data mids object
+#'
+#' @return mids object
+#' @export
+#'
+pase_cutter_mids <- function(data){
+data |>
+ mice::complete(action = "long", include = TRUE) |>
+ pase_cutter(drop.pase = FALSE, drop.nas = TRUE)|>
+ mice::as.mids()
+ }
+
+
+#' Completes events data set, option to impute
+#'
+#' @param data
+#' @param impute
+#'
+#' @return mids or tibble
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> events_dataset(impute=FALSE)
+#' targets::tar_read(df_all_data_formatted) |>
+events_dataset <- function(data, impute = TRUE, uv=FALSE) {
+ # data <- data |> events_ready()
+ if (impute) {
+ data |> events_ready()|>
+ dplyr::select(-tidyselect::any_of("reg_bmi"))|>
+ fun_impute(ignore = c("pase_0","pase_4"),pase.mod = FALSE)
+ } else if (uv){
+ data |> events_ready()|>
+ pase_cutter(drop.pase = TRUE,drop.nas = TRUE)
+ } else if ("mids" %in% class(data)){
+ data
+ } else {
+ data |> events_ready()|>
+ dplyr::select(-tidyselect::any_of("reg_bmi")) |>
+ pase_cutter(drop.pase = TRUE,drop.nas = TRUE)
+ }
+}
+
+#' Title
+#'
+#' @param data
+#' @param all.vars
+#' @param outcome.var
+#' @param use.strata
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> events_ready() |> subset_df("pase")
+#' data <- targets::tar_read(df_event_data) |> events_dataset(impute = FALSE)
+
+cox_regression <- function(data, all.vars = TRUE,outcome.var="pase_change",use.strata=TRUE, include_formula=FALSE) {
+ if ("mids" %in% class(data)) {
+ nms <- names(data$data)
+ } else {
+ nms <- names(data)
+ data <- data |>
+ labelling_data()
+ # BMI meassure is excluded from non-imputed dataset
+ # data <- data |> dplyr::select(-tidyselect::all_of(c("reg_bmi")))
+ }
+
+ vars <- nms[!nms %in% c("time", "status", outcome.var)]
+
+ form.prefix <- "survival::Surv(time, status) ~"
+
+ if (use.strata) {
+ reg.form <- glue::glue("{form.prefix} strata({outcome.var})")
+ } else {
+ reg.form <- glue::glue("{form.prefix} {outcome.var}")
+ }
+
+ if (all.vars) reg.form <- paste0(reg.form, " + ", paste(vars, collapse = " + "))
+
+ require(survival)
+ out <- with(data, survival::coxph(
+ as.formula(reg.form)
+ ))
+
+
+ if (isTRUE(include_formula)){
+ out$call$formula <- as.formula(reg.form)
+ }
+
+ out
+}
+
+#' Creates UV cox models for all variables in data set (but time and status)
+#'
+#' @param data
+#' @param include
+#'
+#' @return
+#' @export
+#'
+#' @examples
+splitdf4uvcox <- function(data,include=c("pase_change","time","status")){
+ names(data)[!names(data)%in%include] |>
+ purrr::map(\(.x){
+ data |> dplyr::select(tidyselect::all_of(c(.x,include))) |>
+ cox_regression(outcome.var = .x,use.strata=FALSE,all.vars = FALSE)
+
+ })
+}
+
+#' Creates and prints UV Cox analyses
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_event_data) |> uv_cox_table()
+uv_cox_table <- function(data){
+ data |>
+ events_dataset(impute = FALSE,uv = TRUE) |>
+ dplyr::select(pase_change,dplyr::everything()) |>
+ splitdf4uvcox(include=c("time","status")) |>
+ purrr::map(\(.x){
+ .x |> tbl_regression_standard()
+ }) |>
+ gtsummary::tbl_stack()
+ }
+
+tbl_merged_named <- function(data){
+ data |> gtsummary::tbl_merge(tab_spanner = names(data))
+}
+
+tbl_stack_named <- function(data){
+ data |> gtsummary::tbl_stack(group_header = names(data))
+}
+
+tbl_regression_standard <- function(data){
+ # browser()
+ data |> gtsummary::tbl_regression(exponentiate = TRUE,
+ add_estimate_to_reference_rows = TRUE,
+ show_single_row = where(is.logical),
+ statistics=list(gtsummary::all_continuous()~"[{conf.low};{conf.high}]",
+ gtsummary::all_categorical()~"[{conf.low}%;{conf.high}%]")
+ ) |>
+ fix_labels()
+}
+
+#' Wrapper to print summary table with extended info
+#'
+#' @param data formatted and subset data set
+#' @param by.var stratify by
+#'
+#' @return
+#' @examples
+#' targets::tar_read(df_pred_data)|>print_table_summary(by="reg_female")
+print_table_summary <- function(data, by.var = "pase_change") {
+ data |>
+ labelling_data() |>
+ # pase_cutter(drop.pase = TRUE) |>
+ gtsummary::tbl_summary(
+ missing = "ifany",
+ by = tidyselect::all_of(by.var),
+ value = list(where(is.logical) ~ TRUE)
+ ) |>
+ gtsummary::add_overall()
+}
+
+print_table_summary_explorer <- function(data, by.var = "pase_change") {
+ data |>
+ labelling_data() |>
+ # pase_cutter(drop.pase = TRUE) |>
+ gtsummary::tbl_summary(
+ missing = "ifany",
+ by = tidyselect::all_of(by.var),
+ value = list(where(is.logical) ~ TRUE),
+ type = list(gtsummary::all_continuous() ~ "continuous2"),
+ statistic = list(gtsummary::all_continuous() ~ c(
+ # # "{N_nonmiss} ({p_nonmiss}%)",
+ "{median} ({p25}, {p75})",
+ # # "{min}, {max}",
+ "{mean} ({sd})"#,
+ # # "{N_miss} ({p_miss}%)"
+ )#,
+ # gtsummary::all_categorical() ~ c(
+ # "{N_obs} ({p_nonmiss}%)"#,
+ # # "{N_miss} ({p_miss})"
+ # )
+ )
+ ) |>
+ gtsummary::add_overall() |>
+ gtsummary::add_n() #|>
+ # gtsummary::add_p()
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted)
+#' targets::tar_read(df_all_data_formatted) |> events_tblone()
+events_tblone <- function(data) {
+ #browser()
+ data |>
+ # events_ready() |>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::select(-tidyselect::all_of(c("status", "time"))) |>
+ dplyr::filter(!is.na(pase_change)) |>
+ print_table_summary()
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> View()
+#' targets::tar_read(df_pred_data)|>
+#' dplyr::transmute(stRoke::quantile_cut(pase_0,4,group.names = 1:4),soc_status_work,fam_indk,edu_level) |>
+#' summary_tblone()
+summary_tblone <- function(data,by=names(data)[1]) {
+ # data <- targets::tar_read(df_pred_data)
+ data |>
+ labelling_data() |>
+ # prediction_ready() |>
+ # dplyr::select(-reg_bmi) |>
+ # pase_cutter(drop.pase = TRUE) |>
+ # dplyr::filter(!is.na(pase_change)) |>
+ # dplyr::mutate(pase_change=forcats::fct_rev(pase_change)) |>
+ print_table_summary(by.var = by)
+}
+
+#
+#' Summaries of DST data for PASE quartiles at 0 and 4
+#'
+#' @param data
+#' @param vars
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_pred_data) |> sum_pase_tables()
+sum_pase_tables <- function(data,vars=c("pase_0","pase_4")){
+ vars |> lapply(function(.x){
+ dplyr::tibble(stRoke::quantile_cut(data[[.x]],y=data[["pase_0"]],4,group.names = 1:4),
+ dplyr::select(data,soc_status_nowork,fam_indk_hl,edu_level_hl)) |>
+ summary_tblone()
+ })
+}
+
+
+#' Creating a truthful stratified table for predictions
+#'
+#' @param data data frame
+#'
+#' @return list
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_pred_data) |> true_pred_sum_plot()
+true_pred_sum_plot <- function(data){
+ true_sum <- data |>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::mutate(pase_change=forcats::fct_rev(pase_change))
+
+ list(#true_sum,
+ true_sum |> (function(.x){
+ split(.x,.x$pase_change %in% c("Persistently low","Increase"))
+ })() |>
+ purrr::map(function(.y){
+ .y |>
+ dplyr::mutate(pase_change=factor(pase_change))
+ })) |>
+ purrr::list_flatten() |>
+ purrr::map(summary_tblone,by="pase_change") |>
+ purrr::map(mask_micro_summary) |>
+ gtsummary::tbl_merge()
+}
+
+#' Get quick summary of missing vs non-missing for each given variable
+#'
+#' @param data data set
+#' @param var variable to summarise over
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_pred_data) |> dplyr::select(soc_status_work,fam_indk,edu_level) |> who_is_missing()
+#' targets::tar_read(df_pred_data) |> who_is_missing(var="reg_bmi")
+who_is_missing <- function(data, var = "edu_level") {
+ data |>
+ dplyr::mutate(log = factor(c("non-missing","missing")[is.na(data[[var]])+1])) |>
+ dplyr::select(log, tidyselect::everything(),-tidyselect::all_of(var)) |>
+ summary_tblone() #|> gtsummary::bold_p()
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted)
+#' targets::tar_read(df_all_data_formatted) |> View()
+#' targets::tar_read(df_pred_data) |> preds_tblone()
+preds_tblone <- function(data) {
+ data |>
+ labelling_data() |>
+ # prediction_ready() |>
+ # dplyr::select(-reg_bmi) |>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::filter(!is.na(pase_change)) |>
+ dplyr::mutate(pase_change=forcats::fct_rev(pase_change)) |>
+ print_table_summary()
+}
+
+#' Title
+#'
+#' @param data
+#' @param b.cols
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' gt <- targets::tar_read(ls_pred_summary)[[1]]
+#' gt |> add_var_groups_gt()
+#'
+#' # For this to work, the function would need to handle labels and levels
+#' gt <- targets::tar_read(tbl_pred_summary)|> gtsummary::as_gt()
+#' gt |> add_var_groups_gt()
+add_var_groups_gt <- function(gt){
+ # gt <- sex_ls |> purrr::pluck(2) |> gtsummary::as_gt()
+ # gt <- fix_labels(gt)
+ cls <- class(gt)
+
+ b.cols <- names(gt$`_data`)
+
+ if (b.cols[[1]]!="variable"){
+ # Flag to indicate if format is native gt or not. Simple assumption
+ # class(gt) gt is not enough
+ labels <- gt$`_data`[[1]]
+ group.var <- names(gt$`_data`[[1]])
+ } else {
+ labels <- gt$`_data`[["label"]][gt$`_data`[["row_type"]]=="label"]
+ group.var <- gt$`_data`[["variable"]]
+ }
+
+
+
+ groups <- matrix(ncol=length(labels)) |>
+ data.frame() |>
+ setNames(ifelse(labels=="","unknown_var",labels)) |>
+ tibble::as_tibble() |> groups_in_ds(labels = TRUE)
+
+ group.labels <- names(groups) |> subset_named_labels(labels.raw = group_labels())
+
+ labels.all <- group.labels |> purrr::imap(function(.x,.y){
+ c(.x,groups[[.y]][["label"]])
+ }) |> purrr::list_c()
+
+ for (i in rev(seq_along(group.labels))){
+ gt <- gt |> gt::tab_row_group(label=gt::md(glue::glue("*{group.labels[[i]]}*")),
+ rows=which(group.var %in% groups[[names(group.labels)[[i]]]][["var"]]))
+
+ }
+
+ class(gt) <- cls
+ gt
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(tbl_preds_lin_imp_reg)
+#' data |> fix_labels()
+fix_labels <- function(data){
+ cls <- class(data)
+ data[[1]][["variable"]][data[[1]][["row_type"]]=="label"] |>
+ subset_named_labels(var_labels()) |>
+ unname() -> data[[1]][["label"]][data[[1]][["row_type"]]=="label"]
+ class(data) <- cls
+ data
+}
+
+
+#' Title
+#'
+#' @param data
+#' @param b.cols
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' tbl <- targets::tar_read(ls_pred_summary)[[1]]
+add_var_groups_pre_calc <- function(data,b.cols){
+
+ groups <- data |> groups_in_ds()
+
+ group.labels <- names(groups) |> subset_named_labels(labels.raw = group_labels())
+
+ t0 <- data.frame(matrix(ncol=length(b.cols))) |>
+ setNames(b.cols) |>
+ tibble::tibble()
+ list(ext = group.labels |> purrr::imap(function(.x,.y){
+ t0 |> dplyr::mutate(
+ variable=.y,
+ val_label=.x,
+ row_type="group",
+ label=.x
+ )
+ }) |> dplyr::bind_rows(),
+ lvls = group.labels |> purrr::imap(function(.x,.y){
+ c(.y,groups[[.y]][["var"]])
+ }) |> purrr::list_c()
+ )
+}
+
+#' Adds variable grouping and formatting to gtsummary tables
+#'
+#' @param tbl
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#'
+#' tbl <- targets::tar_read(tbl_pred_summary)
+#' targets::tar_read(tbl_pred_summary) |> add_var_groups()
+#'
+add_var_groups <- function(tbl,
+ pre_ls=add_var_groups_pre_calc(tbl$inputs$data,
+ names(tbl$table_body))){
+
+
+ tbl |> gtsummary::modify_table_body(
+ ~.x |> dplyr::bind_rows(pre_ls[["ext"]]) |>
+ dplyr::arrange(factor(variable,levels=pre_ls[["lvls"]]))
+ ) |>
+ gtsummary::modify_table_styling(columns=label,
+ rows= row_type%in%"level",text_format = "indent2") |>
+ gtsummary::modify_table_styling(columns=label,rows= row_type%in%"label",text_format = "indent")|>
+ gtsummary::modify_table_styling(columns=label,rows= row_type%in%"group",text_format = c("italic"))
+}
+
+#' Functionalised character vector of all labels
+#'
+#' @return
+#' @export
+#'
+#' @examples
+var_labels <- function(){
+ c(
+ age = "Age",
+ reg_female = "Female sex",
+ reg_bmi = "Body mass index",
+ reg_smoker = "Current smoker",
+ reg_alone = "Living alone",
+ reg_more_alc = "High alcohol consumption",
+ reg_hyperten = "Hypertension",
+ reg_diabetes = "Diabetes",
+ reg_atriefli = "Atrial fibrillation",
+ reg_perifer_arteriel = "Peripheral arterial disease",
+ reg_tidl_tci = "Previous TIA",
+ reg_ami = "Previous MI",
+ reg_trombolyse = "Treated with IVT",
+ reg_trombektomi = "Treated with EVT",
+ # reg_any_perf,
+ rtreat = "Trial allocation",
+ rtreat_placebo = "Placebo trial treatment",
+ pase_0 = "Pre-stroke PASE score",
+ pase_4 = "6 months post-stroke PASE score",
+ pase_0_quartile = "Pre-stroke PASE score quartile",
+ pase_4_quartile = "6 months post-stroke PASE score quartile",
+ # pase_change,
+ nihss_0 = "Admission NIHSS",
+ # soc_status,
+ soc_status_work = "Employed",
+ soc_status_nowork = "Not employed",
+ fam_indk = "Family income group",
+ fam_indk_hl = "Lower family income",
+ fam_indk_high = "Higher family income",
+ fam_indk_low = "Lower family income",
+ edu_level = "Educational level group",
+ edu_level_hl = "Lower educational level",
+ edu_high = "Higher educational level",
+ edu_low = "Low educational level",
+ who_4 = "WHO-5 score 6 months post-stroke",
+ mdi_4 = "MDI score 6 months post-stroke",
+ mrs_4_above1 = "mRS > 1 at 6 months post-stroke",
+ mfi_gen_4 = "General fatigue (MFI domain) 6 months post-stroke",
+ time = "Time",
+ status = "Status",
+ event.include = "Include event",
+ who_0 = "Pre-stroke WHO-5 score",
+ mrs_0_above0 = "Pre-stroke mRS > 0",
+ pase_change = "PA change group"
+ )
+}
+
+
+group_labels <- function(data){
+ c("clin" = "Clinical data",
+ "lifestyle" = "Lifestyle and chronic diseases",
+ "ses" = "Socio-economic factors",
+ "assess.events" = "Assessments",
+ "assess.pred" = "Assessments",
+ "extra" = "extras")
+}
+
+rev_naming <- function(x){
+ setNames(names(x),x)
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_pred_data)
+groups_in_ds <- function(data, labels=FALSE){
+ groups <- define_variables() |> purrr::imap(function(.x,.y){
+ tibble::tibble(group=.y,var=.x)
+ }) |>
+ dplyr::bind_rows()
+
+ if (labels){
+ matching <- subset_named_labels(names(data),
+ rev_naming(var_labels()))
+ }else {
+ matching <- names(data)
+ }
+ groups[match(matching,groups[["var"]]),] |>
+ (\(.x){
+ .x |> dplyr::mutate(group=factor(group,levels=unique(.x[["group"]])))
+ })() |>
+ cbind(
+ tibble::tibble(
+ label=labelling_data(data) |> labelled::var_label() |> purrr::list_c()
+ )
+ )|>
+ (\(.x){
+ split(.x,.x[["group"]])
+ })()
+}
+
+
+#' Subset labels
+#'
+#' @param data
+#' @param labels.raw
+#'
+#' @return character vector
+#' @export
+#'
+subset_named_labels <- function(data,labels.raw){
+ labels.raw[match(data,names(labels.raw))]
+}
+
+#' Assign labels to data.frame or tibble
+#'
+#' @param data
+#' @param labels
+#'
+#' @return
+#' @export
+#'
+#' @examples
+assign_labels <- function(data,labels){
+ # data |> labelled::set_variable_labels(labels)
+
+ labelled::var_label(data) <- labels
+
+ data
+}
+
+#' Flexible labelling using labelled for nicer tables
+#'
+#' @param data data set
+#'
+#' @return
+#' @export labelled data.frame/tibble
+#'
+#' @examples
+#' data <- targets::tar_read(df_pred_data)
+#' data <- data |> dplyr::mutate(test="test")
+#' data |> labelling_data() |> labelled::var_label()
+labelling_data <- function(data,label.list=var_labels()){
+
+ labs <- subset_named_labels(names(data),label.list)
+ labs[is.na(labs)] <- names(data)[is.na(labs)]
+
+ data |> assign_labels(labels = labs)
+}
+
+
+
+#' Print regression table
+#'
+#' @param data cox regression ready data set
+#'
+#' @return gtsummary tbl_regression list object
+#' @examples
+#' data <- targets::tar_read(df_event_data)
+#' targets::tar_read(df_events_mids) |> show_table_regression()
+#' targets::tar_read(df_event_data) |> show_table_regression(use.mice=FALSE)
+show_table_regression <- function(data, use.mice=FALSE, by.var="pase_change") {
+ # browser()
+ imp <- data |>
+ events_dataset(impute = use.mice)
+
+ if ("mids" %in% class(imp)){
+ imp <- imp |> pase_cutter_mids() |>
+ mice::complete(action = "long", include = TRUE) |>
+ dplyr::select(-tidyselect::any_of(c("pase_0","pase_4","pase_0_quartile","pase_4_quartile"))) |>
+ mice::as.mids()
+ } else {
+ imp <- imp |>
+ dplyr::select(-tidyselect::any_of(c("pase_0","pase_4","pase_0_quartile","pase_4_quartile")))
+ }
+ imp |> standard_multi_cox_table(by.var="pase_change")
+}
+
+standard_multi_cox_table <- function(data, by.var="pase_change",all.vars = TRUE){
+ # browser()
+ data |>
+ cox_regression(all.vars = all.vars, use.strata = FALSE,outcome.var = by.var) |>
+ tbl_regression_standard()
+}
+
+
+#' Splitting df to list by PA trajectory
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_pred_data) |> pred_ls_split()
+pred_ls_split <- function(data, excluded.vars = "reg_bmi"){
+ data |>
+ pase_cutter(drop.pase = FALSE) |>
+ dplyr::select(-tidyselect::all_of(c("pase_4","pase_0_quartile","pase_4_quartile"))) |>
+ dplyr::group_split(pase_split = pase_change %in% c("Increase", "Persistently low")) |>
+ setNames(c("drop", "hop")) |>
+ purrr::map2(.y = c("Decrease", "Increase"), .f = \(x, y){
+ x |>
+ dplyr::mutate(pase_bin = pase_change == y) |>
+ dplyr::select(-tidyselect::all_of(c(excluded.vars, c("pase_change", "pase_split")))) |>
+ na.omit()
+ })
+}
+
+bin_original <- function(data,...){
+ ## This will just follow the original pase_cutter binning
+ data
+}
+
+#' Help developing new binning functions without using "browser()"
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted) |> bin_ready_boiler()
+bin_ready_boiler <- function(data){
+ data |>
+ events_ready()|>
+ pase_cutter(drop.pase = FALSE)
+}
+
+#' Handles overall quantile change with dynamic definition of lowest and any change
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+bin_quantile <- function(data,quantiles=5,lowest=1,any=FALSE,...){
+
+ highest_seq <- seq_len(quantiles)[-seq_len(lowest)]
+
+ ## This will just follow the original pase_cutter binning
+ df <- data|>
+ dplyr::mutate(dplyr::across(.cols = c("pase_0", "pase_4"), \(i) {
+ as.numeric(stRoke::quantile_cut(x=i,groups=quantiles,y=pase_0,na.rm = TRUE,group.names=seq_len(quantiles)))
+ }, .names = "{.col}_quantile"))
+
+ if (any){
+ out <- df |>
+ dplyr::mutate(pase_change = factor(dplyr::case_when(
+ pase_0_quantile < pase_4_quantile ~ "up",
+ pase_0_quantile > pase_4_quantile ~ "down",
+ pase_0_quantile %in% seq_len(lowest) & pase_4_quantile %in% seq_len(lowest) ~ "low",
+ pase_0_quantile %in% highest_seq &
+ pase_4_quantile %in% highest_seq ~ "high"
+ ), ordered = FALSE))
+ } else {
+ out <- df |>
+ dplyr::mutate(pase_change = factor(dplyr::case_when(
+ pase_0_quantile %in% seq_len(lowest) &
+ pase_4_quantile %in% highest_seq ~ "up",
+ pase_0_quantile %in% highest_seq &
+ pase_4_quantile %in% seq_len(lowest) ~ "down",
+ pase_0_quantile %in% seq_len(lowest) & pase_4_quantile %in% seq_len(lowest) ~ "low",
+ pase_0_quantile %in% highest_seq &
+ pase_4_quantile %in% highest_seq ~ "high"
+ ), ordered = FALSE))
+ }
+
+
+ out |> dplyr::mutate(pase_change=factor(pase_change,levels=c("high", "down", "up", "low")))
+}
+
+bin_percentage<-function(data,percentage,...){
+ data |>
+ dplyr::mutate(pase_0_cut = as.numeric(cut(pase_0,quantile(pase_0,probs = c(0,percentage/100,1),na.rm = TRUE),include.lowest = TRUE,labels = 1:2)),
+ pase_4_cut = as.numeric(cut(pase_4,quantile(pase_0,probs = c(0,percentage/100,1),na.rm = TRUE),include.lowest = TRUE,labels = 1:2)),
+ pase_change = dplyr::case_when(
+ pase_0_cut > pase_4_cut ~ "down",
+ pase_0_cut < pase_4_cut ~ "up",
+ pase_0_cut %in% 1 ~ "low",
+ pase_0_cut %in% 2 ~ "high"
+ ),
+ pase_change = factor(pase_change, levels= c("high", "down", "up", "low"))
+ )
+}
+
+bin_anyupdown<-function(data,low.q=1,high.q=2:4,...){
+data |>
+ dplyr::mutate(pase_0_quartile=as.numeric(pase_0_quartile),
+ pase_4_quartile=as.numeric(pase_4_quartile),
+ pase_change = dplyr::case_when(
+ pase_0_quartile > pase_4_quartile ~ "down",
+ pase_0_quartile < pase_4_quartile ~ "up",
+ pase_0_quartile %in% low.q ~ "low",
+ pase_0_quartile %in% high.q ~ "high"
+ ),
+ pase_change = factor(pase_change, levels= c("high", "down", "up", "low"))
+ )
+}
+
+bin_absupdown<-function(data,abs.bin,low.q=1,high.q=2:4,...){
+ data |>
+ dplyr::mutate(pase_dif=(pase_4-pase_0),
+ pase_change = dplyr::case_when(
+ pase_dif > (abs.bin) ~ "up",
+ pase_dif < -(abs.bin) | pase_0 == 0 ~ "down",
+ pase_0_quartile %in% low.q ~ "low",
+ pase_0_quartile %in% high.q ~ "high"
+ ),
+ pase_change = factor(pase_change, levels= c("high", "down", "up", "low")))
+}
+
+bin_relupdown<-function(data,rel.bin,low.q=1,high.q=2:4,...){
+ data |>
+ dplyr::mutate(pase_rel_dif=(pase_4-pase_0)/pase_0,
+ pase_change = dplyr::case_when(
+ pase_rel_dif > (rel.bin/100) ~ "up",
+ pase_rel_dif < -(rel.bin/100) ~ "down",
+ pase_0_quartile %in% low.q ~ "low",
+ pase_0_quartile %in% high.q ~ "high"
+ ),
+ pase_change = factor(pase_change, levels= c("high", "down", "up", "low")))
+}
+
+#' Title
+#'
+#' @param data
+#' @param ...
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> group_format(binning.fun=bin_clusterlcm)
+bin_clusterlcm <- function(data,...){
+ data|>
+ #events_ready()|>
+ #pase_cutter(drop.pase = FALSE)|>
+ #dplyr::filter(!is.na(pase_0),!is.na(pase_4)) |>
+ dplyr::select(-tidyselect::any_of(c("pase_0_quartile","pase_4_quartile","pase_split","pase_dif","pase_rel_dif")))|>
+ lcm_cluster(n.clusters = 4) |>
+ final_membership() |>
+ dplyr::mutate(pase_change=clust) |>
+ dplyr::select(-clust)
+}
+
+#' Multi grouping
+#'
+#' @param data
+#' @param binning.fun
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted)
+#' targets::tar_read(df_all_data_formatted) |> group_format(binning.fun = bin_relupdown,rel.bin=20)
+#' targets::tar_read(df_all_data_formatted) |> group_format(binning.fun = bin_original,var.excl=NULL)
+#' targets::tar_read(df_all_data_formatted) |> group_format(binning.fun = bin_clusterlcm,var.excl=c("pase_0_quartile","pase_4_quartile","pase_split","pase_dif","pase_rel_dif"))
+group_format <- function(data,var.keep=NULL,binning.fun,var.excl=c("pase_0","pase_4","pase_0_quartile","pase_4_quartile","pase_split","pase_dif","pase_rel_dif"),...){
+ out_all <- data |>
+ events_ready()|>
+ pase_cutter(drop.pase = FALSE) |>
+ #bin_relupdown(rel.bin=20)
+ binning.fun(...)|>
+ dplyr::filter(!is.na(pase_0),!is.na(pase_4))
+
+ exl.ndx <- !names(out_all) %in% var.excl
+ if (all(exl.ndx)){
+ out <- out_all
+ } else {
+ out <- out_all[exl.ndx]
+ }
+
+ return(out)
+}
+
+ls_pase_pred_clean<-function(data,excluded.vars){
+data|>
+ purrr::map(\(.x){
+ .x |>
+ dplyr::select(-tidyselect::any_of(c(excluded.vars,
+ c("pase_4","pase_0_quartile","pase_4_quartile","pase_change", "pase_split","pase_rel_dif")))) |>
+ na.omit()
+ })
+}
+
+
+pred_ls_split_alt <- function(data, excluded.vars = "reg_bmi",type="relupdown",rel.bin){
+ #browser()
+ df<-data |>
+ pase_cutter(drop.pase = FALSE)
+
+ if (type=="anyupdown"){
+ ls_binned<-df |>
+ bin_anyupdown()|>
+ (\(.x){
+ list(.x|>dplyr::mutate(pase_bin=pase_change=="down")|>dplyr::filter(!pase_0_quartile==1),
+ .x|>dplyr::mutate(pase_bin=pase_change=="up")|>dplyr::filter(!pase_0_quartile==4))
+ })()
+
+ names<-c("Any quartile down","Any quartile up")
+ } else if (type=="relupdown"){
+ ls_binned<-df |>
+ bin_relupdown(rel.bin=rel.bin)|>
+ (\(.x){
+ list(.x|>dplyr::mutate(pase_bin=pase_change=="down"),
+ .x|>dplyr::mutate(pase_bin=pase_change=="up"))
+ })()
+
+ names<-c(paste0("More than ",rel.bin,"% down"),paste0("More than ",rel.bin,"% up"))
+ }
+
+
+ ls_binned |>
+ setNames(names)|>
+ ls_pase_pred_clean(excluded.vars = excluded.vars)
+}
+
+
+#' Run regularisation steps for split data set
+#'
+#' @param data selected data set
+#'
+#' @return list
+#'
+#' @examples
+#' data <- targets::tar_read(df_pred_data)
+#' targets::tar_read(df_pred_data) |> pred_models(auto.l = TRUE,weighted = FALSE,rel.bin=20,split.type="relupdown")
+pred_models <- function(data, split.type="pase_bin", excludes = "reg_bmi",rel.bin=50,...) {
+ if (split.type=="pase_bin"){
+ ls_split <- data |>
+ pred_ls_split(excluded.vars = excludes)
+ } else {
+ ls_split <- data |>
+ pred_ls_split_alt(excluded.vars = excludes,type=split.type,rel.bin=rel.bin)
+ }
+
+ ls <- ls_split|>
+ purrr::map(\(.x) regularisation_steps(.x,...))
+
+ class(ls) <- c("regular_list", class(ls))
+ ls
+}
+
+cross_mean_median_exp_table <- function(data) {
+ nms <- paste0("v", seq_len(ncol(data)))
+
+ cross_calcs <- data |>
+ as.data.frame() |>
+ setNames(nms) |>
+ dplyr::rowwise() |>
+ dplyr::transmute(
+ median = median(dplyr::c_across(tidyselect::all_of(nms))),
+ medianOR = exp(median),
+ mean = mean(dplyr::c_across(tidyselect::all_of(nms))),
+ meanOR = exp(mean)
+ )
+
+ dplyr::tibble(names = rownames(data), cross_calcs) |>
+ dplyr::select(-tidyselect::all_of(c("mean","median")))
+}
+
+
+gather_coefs_step1 <- function(data) {
+ data |>
+ list3levelpluck(lvl1 = "model", lvl2 = "B") |>
+ purrr::map(purrr::reduce, cbind)
+}
+
+gather_coefs <- function(data) {
+ # imputed.list <- "mids_regular_list" %in% class(data)
+
+ if ("mids_regular_list" %in% class(data)) {
+ data_step1 <- data |>
+ purrr::map(gather_coefs_step1) |>
+ purrr::map(purrr::reduce, cbind)
+ } else if ("regular_list" %in% class(data)) {
+ data_step1 <- data |> gather_coefs_step1()
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data_step1 |>
+ purrr::map(cross_mean_median_exp_table) |>
+ purrr::reduce(dplyr::full_join, by = "names", suffix = paste0("_", names(data)))
+}
+
+
+#' Merge and print model coefficients. Pools datafrom mids analyses.
+#'
+#' @param data list
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(ls_pred_models)
+#' targets::tar_read(ls_pred_models) |> print_pred_coefs()
+#' targets::tar_read(ls_pred_mids_reg) |> print_pred_coefs() |> add_var_groups_gt()
+print_pred_coefs <- function(data) {
+ # data <- targets::tar_read(ls_pred_mids_reg)
+ # nms <- names(data)
+
+ if ("mids_regular_list" %in% class(data)) {
+ type.table <- "Pooled regularised models"
+ } else if ("regular_list" %in% class(data)) {
+ type.table <- "Single regularised model"
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ merged_tbl <- data |>
+ gather_coefs() |>
+ ## Leaving out the intercept
+ (function(.x) .x[-1,])()
+
+ sel_mean_med <- colnames(merged_tbl)[!grepl(pattern = "OR",colnames(merged_tbl))][-1]
+ sel_or <- colnames(merged_tbl)[grepl(pattern = "OR",colnames(merged_tbl))]
+
+ news <- subset_named_labels(merged_tbl$names,var_labels())
+
+ merged_tbl <- merged_tbl |> dplyr::mutate(names=dplyr::if_else(is.na(news),names,news))
+
+ gt_merged_tbl <- merged_tbl|>
+ gt::gt() |>
+ gt::fmt_number(decimals = 5)
+
+ merged_tbl_log <- merged_tbl |> dplyr::mutate(dplyr::across(tidyselect::all_of(sel_or), ~.x!=1),
+ dplyr::across(tidyselect::all_of(sel_mean_med), ~.x!=0))
+
+ for (j in colnames(merged_tbl)[-1]) {
+
+ i <- merged_tbl_log[[j]]
+
+ gt_merged_tbl <- gt_merged_tbl |> gt::tab_style(style = list(
+ gt::cell_text(weight="bold")
+ ),
+ locations = gt::cells_body(
+ columns=j,
+ rows = i
+ )
+ )}
+
+ for (i in names(data)) {
+ gt_merged_tbl <- gt_merged_tbl |>
+ gt::tab_spanner(label = i, columns = tidyselect::ends_with(i))
+ }
+
+ gt_merged_tbl |> gt::tab_spanner(
+ label = type.table,
+ columns = -1
+ )
+}
+
+#' Calculates confusionMatrix from contingency tables. Pools if object class is .
+#'
+#' @param data
+#'
+#' @return list
+#'
+#' @examples
+#' targets::tar_read(ls_pred_mids_reg) |> multi_table_cfm()
+#' targets::tar_read(ls_pred_models) |> multi_table_cfm()
+multi_table_cfm <- function(data) {
+ # data <- targets::tar_read(ls_pred_mids_reg)
+ if ("mids_regular_list" %in% class(data)) {
+ data <- data |> purrr::map(\(x){
+ x |>
+ # Test tables are plucked
+ # purrr::map(\(y) y |> purrr::pluck("model") |> purrr::pluck("cMatTest"))|>
+ list3levelpluck(lvl1 = "model", lvl2 = "cMatTest") |>
+ # All tables are add together
+ purrr::reduce(\(i, j) i + j)
+ })
+ } else if ("regular_list" %in% class(data)) {
+ data <- data |> list3levelpluck(lvl1 = "model", lvl2 = "cMatTest")
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data |>
+ purrr::map(caret::confusionMatrix)
+}
+
+#' Collect and summarise auc meassures. Pools if "mids_regular_list" object
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(ls_pred_mids_reg) |> multi_auc_summary()
+#' targets::tar_read(ls_pred_models) |> multi_auc_summary()
+multi_auc_summary <- function(data) {
+ if ("mids_regular_list" %in% class(data)) {
+ data_step <- data |> purrr::map(\(x){
+ x |>
+ # Test tables are plucked
+ list3levelpluck(lvl1 = "model", lvl2 = "auc_test") |>
+ # All tables are add together
+ purrr::reduce(c)
+ })
+ } else if ("regular_list" %in% class(data)) {
+ data_step <- data |>
+ list3levelpluck(lvl1 = "model", lvl2 = "auc_test") |>
+ purrr::map(c)
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data_step |>
+ purrr::map(summary)
+}
+
+#' Map and 2 level recursive purrr::pluck to ease regular_list subsetting
+#'
+#' @param data
+#' @param lvl1
+#' @param lvl2
+#'
+#' @return
+#' @export
+#'
+#' @examples
+list3levelpluck <- function(data, lvl1 = "model", lvl2 = "cMatTest") {
+ data |> purrr::map(\(y) y |>
+ purrr::pluck(lvl1) |>
+ purrr::pluck(lvl2))
+}
+
+#' Plot performance curve from glmnet regularisation
+#'
+#' @param data list of cvs.glmnet objects
+#'
+#' @return ggplot list object
+#' @export
+#'
+#' @examples
+plot_roc_curve <- function(data, title.text) {
+ ggplot2::ggplot() +
+ purrr::map(data, function(i) {
+ ggplot2::geom_step(data = i, ggplot2::aes(x = FPR, y = TPR))
+ }) +
+ ggplot2::coord_cartesian(xlim = c(0, 1), ylim = c(0, 1)) +
+ ggplot2::geom_abline() +
+ ggplot2::theme_bw() +
+ ggplot2::ggtitle(title.text)
+}
+
+roc_gather_step <- function(x) {
+ with(x, glmnet::roc.glmnet(cvs[[1]]$fit.preval, newy = y1)[match(bestL, lambdas)])
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(ls_pred_mids_reg) |> multi_roc_plot()
+#' targets::tar_read(ls_pred_models) |> multi_roc_plot()
+multi_roc_plot <- function(data) {
+ if ("mids_regular_list" %in% class(data)) {
+ data_step1 <- data |>
+ purrr::map(purrr::map, roc_gather_step) |>
+ purrr::map(purrr::list_flatten)
+ } else if ("regular_list" %in% class(data)) {
+ data_step1 <- data |> purrr::map(roc_gather_step)
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data_step1 |>
+ purrr::map2(.y = names(data), plot_roc_curve) |>
+ patchwork::wrap_plots()
+}
+
+#' Title
+#'
+#' @param tuning.param
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+multi_tuning_gather <- function(tuning.param = "bestA", data) {
+ if ("mids_regular_list" %in% class(data)) {
+ data_step1 <- data |>
+ purrr::map(purrr::map, \(x) x |> purrr::pluck(tuning.param)) |>
+ purrr::map(purrr::reduce, c)
+ } else if ("regular_list" %in% class(data)) {
+ data_step1 <- data |>
+ purrr::map(purrr::pluck, tuning.param)
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data_step1 |> purrr::map(summary)
+}
+
+
+#' Tidied tuning summary call
+#'
+#' @param data
+#'
+#' @return
+#'
+#' @examples
+#' targets::tar_read(ls_pred_mids_reg) |> tuning_summary()
+#' targets::tar_read(ls_pred_models) |> tuning_summary()
+tuning_summary <- function(data) {
+ c(ALPHA = "bestA", LAMBDA = "bestL") |> purrr::map(\(x) x |> multi_tuning_gather(data = data))
+}
+
+#' Apply regularisation steps to MIDS object, output arranged by grouping
+#'
+#' @param data mids object from mice package
+#'
+#' @return list
+#'
+#' @examples
+#' targets::tar_read(df_pred_mids) |> mids_regularisation()
+#' ls <- targets::tar_read(df_pred_mids) |> mids_regularisation(weighted = FALSE,rel.bin=20,split.type="relupdown")
+mids_regularisation <- function(data,...) {
+ ls <- data |>
+ mice::complete(action = "long") |>
+ dplyr::group_split(.imp) |>
+ purrr::modify(\(x){
+ x |> dplyr::select(-tidyselect::all_of(c(".imp", ".id")))
+ }) |>
+ purrr::map(\(.x)pred_models(.x,auto.l=TRUE,excludes = NULL,...))
+
+ nms <- ls |>
+ purrr::map(names) |>
+ unique() |>
+ purrr::reduce(c)
+
+ # As a consequence of the above code each "set" of analyses are together.
+ # Here the same group analyses are subset and grouped
+ ls_n <- purrr::map(nms, function(i) {
+ ls |> purrr::map(purrr::pluck, i)
+ }) |>
+ setNames(nms)
+
+ # Special class is applied to ease future handling
+ class(ls_n) <- c("mids_regular_list", class(ls_n))
+ ls_n
+}
+
+#' A collection of all the summary functions to be applied to list of
+#' pred_models() output
+#'
+#' @param data list of data
+#'
+#' @return list
+#' @export
+#'
+multi_summary <- function(data){
+ list( "coefTable" = print_pred_coefs(data) |>
+ gt::fmt_number(n_sigfig = 3) |>
+ fix_labels() #|> add_var_groups_gt()
+ ,
+ "confusionMatrices" = multi_table_cfm(data),
+ "summaryAUC" = multi_auc_summary(data),
+ "rocPlots" = multi_roc_plot(data),
+ "tuningSummaries" = tuning_summary(data))
+}
+
+# funs <-list(
+# "coefTable" = print_pred_coefs,
+# "confusionMatrices" = multi_table_cfm,
+# "summaryAUC" = multi_auc_summary,
+# "rocPlots" = multi_roc_plot,
+# "tuningSummaries" = tuning_summary
+# )
+
+# multi_summary <- plyr::each(
+# "coefTable" = print_pred_coefs,
+# "confusionMatrices" = multi_table_cfm,
+# "summaryAUC" = multi_auc_summary,
+# "rocPlots" = multi_roc_plot,
+# "tuningSummaries" = tuning_summary
+# )
+
+#' Subset multiple elements from list
+#'
+#' @param data list
+#' @param indices numeric or character vector
+#'
+#' @return list
+#' @examples
+#' targets::tar_read(ls_pred_summary)$confusionMatrices |> purrr::map(list_subset)
+list_subset <- function(data,indices=c("overall","byClass")){
+ data[indices]
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(ls_pred_summary) |> print_model_resutls()
+print_model_resutls <- function(data){
+ par(mfrow=c(1,2))
+
+ list(data$coefTable,
+ invisible(data$confusionMatrices |> purrr::map(\(x) x |> purrr::pluck("table"))),
+ data$confusionMatrices |> purrr::map(list_subset),
+ data$summaryAUC,
+ data$tuningSummaries
+ )
+}
+
+
+#' Classic logistic regression on prediction covariables
+#'
+#' @param data data frame
+#'
+#' @return
+#' @export
+#'
+#' @examples gtsummary list elemnt
+#' targets::tar_read(df_pred_data) |> pred_log_reg()
+#' targets::tar_read(df_pred_data) |> pred_ls_split()
+pred_log_reg <- function(data){
+ data |> pred_ls_split() |>
+ purrr::map(\(x) {
+ gtsummary::tbl_regression(glm(pase_bin~.,family = binomial,data = x),
+ exponentiate= TRUE)#|>
+ # gtsummary::bold_p()
+ }
+ ) |> (\(x){gtsummary::tbl_merge(tbls = x,
+ tab_spanner = names(x))})() }
+
+#' Small wrapper to format CI with square brackets
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+square_ci <- function(data){
+ gsub("(-?\\d*\\.?\\d*)(, )(-?\\d*\\.?\\d*)",
+ "\\[\\1; \\3\\]",data)}
+
+#' Apply CI formatting across gtsummary table including merged tables
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+fix_ci <- function(data){
+ data |> gtsummary::modify_table_body(~ .x |>
+ dplyr::mutate(dplyr::across(dplyr::starts_with("ci"),
+ function(.y){square_ci(.y)})))
+}
+
+#' Classic linear regression on 6 months PASE score. Uni and multi.
+#'
+#' @param data data frame
+#'
+#' @return
+#' @export
+#'
+#' @examples gtsummary list elemnt
+#' data <- targets::tar_read(df_pred_data)
+#' data <- targets::tar_read(df_pred_mids)
+#' targets::tar_read(df_pred_data) |> pred_lin_reg()
+#' targets::tar_read(df_pred_mids) |> pred_lin_reg()
+pred_lin_reg <- function(data){
+
+ # list("tbl_regression-str:ref_row_text"="Reference") |>
+ # gtsummary::set_gtsummary_theme()
+
+ if ("mids" %in% class(data)){
+ cols <- names(data$data)
+
+ } else {
+ cols <- names(data)
+ data <- data |>
+ labelling_data()
+ }
+
+ vars <- cols[cols!="pase_4"]
+
+ formula_pase <- paste("pase_4",paste(vars,collapse = "+"),sep="~" )
+
+ # multi <- with(data=data,lm(pase_4~.)) |>
+ # gtsummary::tbl_regression(add_estimate_to_reference_rows = TRUE)|>
+ # gtsummary::bold_p() |> gtsummary::add_n()
+
+ if (!"mids" %in% class(data)){
+ ls <- list("Univariable"=data |>
+ gtsummary::tbl_uvregression(method=lm, show_single_row = dplyr::where(is.logical),
+ y=pase_4,
+ add_estimate_to_reference_rows = TRUE,pvalue_fun = NULL)#|> gtsummary::bold_p()
+ ,
+ "Multivariable (no BMI)"=lm(pase_4~.,data=dplyr::select(data,-reg_bmi)) |>
+ gtsummary::tbl_regression(add_estimate_to_reference_rows = TRUE, show_single_row = dplyr::where(is.logical))|>
+ # gtsummary::bold_p() |>
+ gtsummary::add_n()
+ ,
+ "Multivariable (ALL)"= lm(pase_4~.,data=data) |>
+ gtsummary::tbl_regression(add_estimate_to_reference_rows = TRUE, show_single_row = dplyr::where(is.logical))|>
+ # gtsummary::bold_p() |>
+ gtsummary::add_n()
+ )
+
+ } else {
+ ls <- list("Multivariable (ALL)"= suppressWarnings(mice::lm.mids(pase_4~.,data=data) |>
+ gtsummary::tbl_regression(add_estimate_to_reference_rows = TRUE, show_single_row = dplyr::where(is.logical))|>
+ # gtsummary::bold_p() |>
+ gtsummary::add_n()))
+ }
+
+ ls |> (\(x){gtsummary::tbl_merge(tbls = x,
+ tab_spanner = names(x))})() |>
+ fix_ci()
+}
+
+
+#' Simple standard plot
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_event_data) |> events_dataset(impute = FALSE)|> cox_regression() |> plot_survival()
+plot_survival <- function(data){
+ data |>
+ ggsurvfit::survfit2() |>
+ ggsurvfit::ggsurvfit(linetype_aes = TRUE, size = 0.8) +
+ ggsurvfit::add_confidence_interval() +
+ ggsurvfit::add_risktable(
+ risktable_stats = c("n.risk", "cum.event"),
+ stats_label = list(cum.event = "Cumulative Observed Events",
+ n.risk = "Number at Risk"),
+ theme =
+ list(
+ ggsurvfit::theme_risktable_default(axis.text.y.size = 11,
+ plot.title.size = 11),
+ ggplot2::theme(plot.title = ggplot2::element_text(face = "bold"))
+ )
+ ) +
+ ggplot2::scale_y_continuous(
+ limits = c(0, 1),
+ labels = scales::percent,
+ expand = c(0.01, 0)
+ ) +
+ ggplot2::scale_x_continuous(breaks = 0:9, expand = c(0.02, 0))
+}
+
+
+#' Smooth tidy survfit object
+#'
+#' @param data survfit object
+#'
+#' @return tibble
+#' @export
+#'
+#' @examples
+#' ls <- targets::tar_read(df_event_data) |> events_dataset(impute = FALSE)|> cox_regression()
+#' data <- ls |> ggsurvfit::survfit2(robust=TRUE) |>
+#' ggsurvfit::tidy_survfit(type="survival") |>
+#' dplyr::group_split(strata) |> purrr::pluck(1)
+#'
+#' ls |> ggsurvfit::survfit2(robust=TRUE) |>
+#' ggsurvfit::tidy_survfit(type="survival") |>
+#' dplyr::group_split(strata) |>
+#' purrr::map(smooth_col)
+smooth_col <- function(data, force_mono=TRUE){
+ smoothed <- lapply(c("estimate","conf.high","conf.low"),function(i){
+ # stats::predict(cobs::cobs(x = data$time,
+ # y = data[i],
+ # constraint = "decrease",
+ # nknots=4,
+ # pointwise = rbind(c(0,min(data$time),1)),
+ # degree = 2,)) |>
+ # tibble::as_tibble() |> dplyr::select(fit) |>
+ stats::predict(mgcv::gam(data=data,formula = as.formula(glue::glue("{i}~s(time,bs='cs')")))) |>
+ tibble::as_tibble()|>
+ setNames(glue::glue("{i}_smooth"))
+ }) |> purrr::list_cbind()
+
+ if (force_mono){
+ ## Forcing starting point to be 1
+ smoothed[1,1] <- 1
+
+ smoothed[1] <- force_decrease(smoothed[1]) ## Only monotonize the esitimate
+ }
+
+ dplyr::tibble(data,
+ smoothed)
+
+}
+
+#' Forces the direction
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+force_decrease <- function(data){
+ data |> purrr::imap(function(.x,.n){
+ s <- c()
+ for (i in seq_along(.x)){
+ if (i == 1) {
+ s[1] <- .x[1]
+ } else {
+ if (.x[i]>s[i-1]){
+ s[i] <- s[i-1]
+ } else {
+ s[i] <- .x[i]
+ }
+ }
+ }
+ s
+ }) |>
+ dplyr::bind_cols()
+}
+
+
+#' Prepare cox regression for smooth survival plot
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> events_dataset(impute = FALSE)|> cox_regression() |> smooth_cox_data()
+smooth_cox_data <- function(data){
+ data |>
+ ggsurvfit::survfit2(robust=TRUE) |>
+ ggsurvfit::tidy_survfit(type="survival") |>
+ dplyr::group_split(strata) |>
+ purrr::map(smooth_col) |>
+ purrr::list_rbind()
+}
+
+#' Plot smooth survival plot
+#'
+#' @param data df from cox regression
+#'
+#' @return ggplot list object
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_event_data) |> events_dataset(impute = FALSE) |> cox_regression(include_formula=TRUE)
+#' data <- targets::tar_read(df_events_mids) |> cox_regression()
+#' data |> plot_survival_smooth()
+plot_survival_smooth <- function(data,line.w=1.2){
+ if ("mira" %in% class(data)) stop("Only plots non-imputed survival data")
+
+ n.level <- length(data$xlevels[[1]])
+
+ # data |>
+ # ggsurvfit::survfit2() |>
+ # ggsurvfit::tidy_survfit()
+
+ if (data |> ggsurvfit::survfit2() |> purrr::pluck("n") |> length() ==1 ){
+ ds <- data |>
+ ggsurvfit::survfit2() |>
+ ggsurvfit::tidy_survfit()
+ p <- ds |>
+ ggplot2::ggplot(ggplot2::aes(x=time, y=estimate))+
+ ggplot2::geom_smooth(se=TRUE, method="loess", formula = "y~x", linewidth=line.w, color="grey10")
+ # Added auto max for y axis removed again to ensure same y axis
+ # max_y <- max(ds$conf.high)
+
+ } else {
+ ds <- data |>
+ smooth_cox_data()
+ p <- ds |>
+ ggplot2::ggplot()+
+ ggplot2::geom_line(ggplot2::aes(x=time, y=estimate_smooth, color=strata, linetype=strata), linewidth=line.w)+
+ ggplot2::geom_ribbon(ggplot2::aes(x=time, ymin=conf.low_smooth,ymax=conf.high_smooth, fill=strata), alpha=.2)
+ # Added auto max for y axis removed again to ensure same y axis
+ # max_y <- max(ds$conf.high_smooth)
+
+ }
+
+ if (n.level==4){
+ colors <- viridisLite::turbo(n=n.level,direction = 1)[c(1,3,2,4)]
+ } else {
+ colors <- viridisLite::turbo(n=n.level,direction = 1)
+ }
+
+ p+
+ ggplot2::scale_y_continuous(limits = c(0,1.02),
+ breaks = seq(0,1,.25),
+ labels = scales::percent,
+ expand = c(0.01, 0)
+ ) +
+ ggplot2::scale_x_continuous(breaks = 0:9, expand = c(0.02, 0))+
+ ggplot2::scale_fill_manual(values=colors)+
+ ggplot2::scale_color_manual(values=colors)+
+ ggplot2::theme_minimal()+
+ ggplot2::theme(axis.title.x = ggplot2::element_blank(),
+ axis.title.y = ggplot2::element_blank(),
+ # axis.text = ggplot2::element_blank(),
+ # legend.position = "none",
+ panel.grid.minor.y = ggplot2::element_blank(),
+ panel.grid.major.y = ggplot2::element_line(color="grey45",linewidth = line.w/2))
+
+}
+
+# viridisLite::turbo(n=4,direction = 1)[c(1,3,2,4)]
+
+cluster_rank <- function(data){
+ data |> cox_regression(outcome.var = "clust",use.strata = TRUE) |> ggsurvfit::survfit2(robust=TRUE) |>
+ ggsurvfit::tidy_survfit(type="survival") |>
+ dplyr::group_split(strata) |>
+ purrr::map(\(x){
+ min(x[["estimate"]])
+ }) |> purrr::list_c() |> rank() |> rev()
+}
+
+cox_relevel <- function(data){
+ data |> dplyr::mutate(clust=factor(clust,levels=cluster_rank(data)))
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted)
+complete_preds_data <- function(data){
+ data |>
+ # events_ready() |>
+ fun_impute(ignore = c("pase_0","pase_4"),pase.mod = FALSE) |>
+ mice::complete() |>
+ dplyr::filter((!is.na(pase_0)&!is.na(pase_4)))
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> add_kamila_cluster()
+#' data_kam <- targets::tar_read(df_all_data_formatted) |> add_kamila_cluster()
+#' data_kam |>print_table_summary(by.var = "kam_grp")
+#' data_kam |> cox_regression(outcome.var="kam_grp")|> plot_survival_smooth()
+#' data_kam |> cox_regression(outcome.var="kam_grp",use.strata = FALSE)|> gtsummary::tbl_regression(exponentiate = TRUE, add_estimate_to_reference_rows = TRUE) |> gtsummary::bold_p()
+#' targets::tar_read(df_events_complete) |> kamila_cluster(n.clusters=3)
+kamila_cluster <- function(data, n.clusters=3,include.out=FALSE){
+ # An index number could be added to later join pack. Of input a complete data set from imputation and pooling??
+ data_orig <- data
+
+
+ if (!include.out){
+ data <- data |>
+ dplyr::select(-tidyselect::one_of(c("time","status")))
+ }
+
+
+ catInd <- data |> lapply(\(x) is.character(x)|is.logical(x)) |> purrr::list_c()
+ conInd <- data |> lapply(\(x) is.numeric(x)|is.integer(x)) |> purrr::list_c()
+
+ catVars <- data[,catInd]
+ catVars <- catVars |> lapply(factor) |> dplyr::bind_cols() |> as.data.frame()
+ conVars <- data[,conInd] |> scale()|> as.data.frame()
+
+ if (is.null(n.clusters)){
+ out <- kamila::kamila(conVar = conVars, catFactor = catVars, numClust = 2:7, numInit = 10,
+ calcNumClust = "ps"
+ )
+ }else {
+ out <- kamila::kamila(conVar = conVars, catFactor = catVars, numClust = n.clusters, numInit = 10)
+ }
+
+ ls <- list("out"=out,"data_orig"=data_orig)
+
+ class(ls) <- c("kamila_cluster",class(ls))
+
+ ls
+
+}
+
+
+#' VarSelLCM wrapper
+#'
+#' @param data complete dataset with no missings
+#' @param n.clusters number of clusters (if length 1, n is fixed, in n>1 given clusters are tested)
+#' @param include.out flag to include outcome variables or not
+#' @param memb.out output data frame with final membership or not (then outputs standard model output)
+#'
+#' @return list with VarSelLCM output and original dataset with cluster appended
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' data |> lcm_cluster()
+lcm_cluster <- function(data, n.clusters=3, include.out=FALSE, var.sel=FALSE,out.vars=c("time", "status")){
+ data_orig <- data
+
+ if (!include.out){
+ data <- data |>
+ dplyr::select(-tidyselect::any_of(out.vars))
+ }
+
+
+ set.seed(5432)
+
+ out <- data |>
+ dplyr::mutate(dplyr::across(where(is.logical)|where(is.character),~factor(.x))) |>
+ as.data.frame() |>
+ VarSelLCM::VarSelCluster(
+ gvals=n.clusters,
+ crit.varsel="BIC",
+ vbleSelec = var.sel,
+ nbcores = round(parallel::detectCores()*.8)
+ )
+
+ ls <- list("out"=out,"data_orig"=data_orig)
+
+ class(ls) <- c("lcm_cluster",class(ls))
+
+ ls
+
+}
+
+
+
+#' Kmeans clustering
+#'
+#' @param data
+#' @param n.clusters
+#' @param include.out
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' data |> kmeans_cluster()
+#' data |> kmeans_cluster(n.clusters=3)
+kmeans_cluster <- function(data, n.clusters=3, include.out=FALSE, memb.out=TRUE){
+ data_orig <- data
+
+ if (!include.out){
+ data <- data |>
+ dplyr::select(!tidyselect::one_of(c("time", "status")))
+ }
+
+ out <- data |>
+ dplyr::mutate(dplyr::across(where(is.double),~scale(.x)),
+ dplyr::across(where(is.logical)|where(is.character),~factor(.x)),
+ dplyr::across(where(is.factor),~as.numeric(.x))) |>
+ stats::kmeans(
+ centers=n.clusters
+ )
+
+ ls <- list("out"=out,"data_orig"=data_orig)
+
+ class(ls) <- c("kmeans_cluster",class(ls))
+
+ ls
+
+}
+
+#' dbscan clustering
+#'
+#' @param data
+#' @param n.clusters
+#' @param include.out
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' data |> dbscan_cluster()
+#' data |> dbscan_cluster(n.clusters=3)
+dbscan_cluster <- function(data, n.clusters=3, include.out=FALSE, memb.out=TRUE){
+ data_orig <- data
+
+ if (!include.out){
+ data <- data |>
+ dplyr::select(!tidyselect::one_of(c("time", "status")))
+ }
+
+ data <- data |> na.omit() |> dplyr::mutate(rtreat=rtreat!="Placebo",
+ dplyr::across(dplyr::everything(), as.numeric))
+
+
+ ## This plot indicates that eps should be set around 60, but at this value everything is one cluster.
+ dbscan::kNNdistplot(data,k = 5)
+
+ ## Performing hierachical clustering, it is clear, that the algorithm is not able to seperate clusters.
+ hds <- dbscan::hdbscan(data,minPts = 5)
+
+ plot(hds,show_flat = TRUE)
+
+ ## Clustering with set eps value and minPts
+ ds <- dbscan::dbscan(data,eps = 25,minPts = 2)
+
+ ds[["cluster"]]
+
+ ## dbscan is not an interesting approach, apparently
+
+ #
+ #
+ #
+ #
+ # out <- data |>
+ # dplyr::mutate(dplyr::across(where(is.double),~scale(.x)),
+ # dplyr::across(where(is.logical)|where(is.character),~factor(.x)),
+ # dplyr::across(where(is.factor),~as.numeric(.x))) |>
+ # stats::kmeans(
+ # centers=n.clusters
+ # )
+ #
+ # ls <- list("out"=out,"data_orig"=data_orig)
+ #
+ # class(ls) <- c("kmeans_cluster",class(ls))
+ #
+ # ls
+
+}
+
+#' Title
+#'
+#' @param ls
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' ls <- data |> lcm_cluster()
+#' ls |> final_membership()
+final_membership <- function(ls){
+ cls <- class(ls)
+ if ("kamila_cluster" %in% cls) {
+
+ tibble::tibble(clust=factor(ls$out$finalMemb),
+ ls$data_orig)
+
+ } else if ("lcm_cluster" %in% cls) {
+
+ tibble::tibble(clust=factor(ls$out@partitions@zMAP),
+ ls$data_orig)
+
+ } else if ("kmeans_cluster" %in% cls) {
+
+ tibble::tibble(clust=factor(ls$out$cluster),
+ ls$data_orig)
+
+ } else stop("Class not recognised")
+
+}
+
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' data |> get_clusters()
+#' data |> get_clusters(n.cl=2:7)
+get_clusters <- function(data,n.cl=4,rm.out=TRUE){
+ set.seed(1123)
+
+ if (length(n.cl)>1){
+ list(
+ # "kmeans"=data |> kmeans_cluster(n.clusters = n.cl,include.out = !rm.out),
+ "lcm"= data |> lcm_cluster(n.clusters = n.cl,include.out = !rm.out),
+ "kamila"=data |> kamila_cluster(n.clusters = n.cl,include.out = !rm.out)
+ )
+ } else {
+ list(
+ "kmeans"=data |> kmeans_cluster(n.clusters = n.cl,include.out = !rm.out),
+ "lcm"= data |> lcm_cluster(n.clusters = n.cl,include.out = !rm.out),
+ "kamila"=data |> kamila_cluster(n.clusters = n.cl,include.out = !rm.out)
+ )
+ }
+
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(list_pred_clusters)
+#' data |> final_clusters()
+final_clusters <- function(data,new.levels=NULL){
+ out <- data |> lapply(final_membership) |> lapply(labelling_data)
+
+ if (is.null(new.levels)){
+ out
+ } else {
+ out |>
+ purrr::map2(relevels,function(x,y){
+ # x$clust <- factor(factor(x$clust,levels=y),labels=1:4)
+ x$clust <- factor(x$clust,levels=y)
+ x #|>
+ # dplyr::filter(clust %in% range(as.numeric(clust))) |>
+ # dplyr::mutate(clust=factor(clust))
+ })
+ }
+
+ }
+
+
+
+#' Title
+#'
+#' @param data
+#' @param by
+#'
+#' @return
+#' @export
+#'
+#' @examples
+merged_summary_tbl <- function(data,by="clust"){
+ data |>
+ purrr::map(function(x){
+ x |>
+ # print_table_summary(by.var = by)
+ gtsummary::tbl_summary(by=by) #|>
+ # gtsummary::add_p() |> gtsummary::bold_p()
+ }
+ ) |> (\(x){
+ x |> gtsummary::tbl_merge(tab_spanner = names(x))
+ })()
+}
+
+#' Easy cox regression tbl for uniform results
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+cox2tbl <- function(data,by="clust",all.vars=FALSE){
+data|> cox_regression(outcome.var = by,use.strata = FALSE,all.vars = all.vars) |>
+ gtsummary::tbl_regression(exponentiate =TRUE,
+ statistics=list(gtsummary::all_continuous()~"[{conf.low};{conf.high}]",
+ gtsummary::all_categorical()~"[{conf.low}%;{conf.high}%]")) |>
+ gtsummary::bold_p()
+}
+
+#' Title
+#'
+#' @param data
+#' @param by
+#'
+#' @return
+#' @export
+#'
+#' @examples
+merged_cox_reg_tbl <- function(data,by="clust"){
+ data |>
+ purrr::map(function(x){
+ x |> cox2tbl(by=by)
+ }
+ ) |> (\(x){
+ x |> gtsummary::tbl_merge(tab_spanner = names(x))
+ })()
+}
+
+#' Title
+#'
+#' @param data
+#' @param by
+#'
+#' @return
+#' @export
+#'
+#' @examples
+wrapped_surv_plot <- function(data,by="clust"){
+data |>
+ purrr::map(function(x){
+ x |> cox_regression(outcome.var = by,use.strata = TRUE,all.vars = FALSE) |>
+ plot_survival_smooth()+ggplot2::labs(color="Cluster",fill="Cluster",linetype="Cluster")
+ }
+ ) |> (\(x){
+ x |> patchwork::wrap_plots(ncol=1) + patchwork::plot_annotation(tag_levels = list(names(x)))
+ })()
+}
+
+
+# Ranking by most events
+relevel_by_rank <- function(data){
+ ## Assigning clusters to each dataset
+data <- targets::tar_read(list_pred_clusters) |>
+ final_clusters(new.levels = NULL)
+
+## Calculating cox regressions and ranking by the final point on the survival plot
+relevels <- data |>
+ purrr::map(function(x){
+ x |> cox_regression(outcome.var = "clust",use.strata = TRUE,all.vars = FALSE) |>
+ ggsurvfit::survfit2() |>
+ ggsurvfit::tidy_survfit() |>
+ (\(x){
+ split(x,x[["strata"]]) |>
+ purrr::map(function(.y){
+ .y[["estimate"]][nrow(.y)]
+ })
+ })() |> purrr::reduce(c) |> rank()
+ }
+ )
+
+#3 Assigning the new, ranked levels
+targets::tar_read(list_pred_clusters) |>
+ final_clusters(new.levels = relevels)
+}
+
+## TODO
+## Verify definitions
+## Do remaining documentation of functions
+##
+##
+## How does elastic net work with imputed dataset?
+## Functionalise to allow for imputed and non-imputed (both analyses) - in both cases with and without BMI - include department of inclusion to investigate reason of missing BMI data
+##
+## tidymodels does not allow pmm in mice. Thy're out!
+
+##
+
+missing_stats <- function(index,data,glue.mask= "{N_miss} ({round(p_miss*100,dec)}%)",dec){
+ index.var <- unique(data$table_body$variable)[index]
+
+ table_body <- data$table_body |>
+ dplyr::filter(variable == index.var)
+
+ if ("missing" %in% table_body$row_type){
+ f1 <- grep("stat_\\d+",names(table_body))
+
+ ## This approach
+ masks <- data$meta_data$df_stats |>
+ purrr::pluck(index) |>
+ dplyr::filter(!duplicated(col_name)) |>
+ dplyr::arrange(col_name) |>
+ dplyr::mutate(mask=glue::glue(glue.mask))|>
+ dplyr::pull(mask)
+
+ table_body[table_body$row_type=="missing",f1] <- masks |>
+ as.matrix() |>
+ t() |>
+ tibble::as_tibble(.name_repair = "unique_quiet")
+
+ }
+ table_body
+}
+
+missing_stats_steps <- function(body,ls,glue.mask,dec){
+ seq_along(unique(body$variable)) |>
+ purrr::map(function(.x) {
+ missing_stats(index=.x,data=ls,glue.mask = glue.mask,dec=dec)
+ }) |>
+ dplyr::bind_rows()
+}
+
+add_missing_stats <- function(data,glue.mask= "{N_miss} ({round(p_miss*100,dec)}%)",dec=1){
+ data |>
+ gtsummary::modify_table_body(
+ ~ .x |> missing_stats_steps(ls=data,glue.mask = glue.mask,dec=dec)
+ )
+}
+
+variable_masks <- function(index, data, cut.off,glue.mask= "<{n} (<{p}%)",dec=dec) {
+ index.var <- unique(data$table_body$variable)[index]
+
+ table_body <- data$table_body |>
+ dplyr::filter(variable == index.var)
+
+
+ ## Filtering bu two different approaches
+ if (table_body$var_type[1] %in% c("dichotomous", "categorical")) {
+ if (any(grepl("^stat_[1-9]|[1-9]\\d",names(table_body)))){
+ masked <- micro_n_masks(
+ ## Handling nominal/binary
+
+ body = table_body |>
+ dplyr::filter(row_type!="missing"),
+ n.all = data$meta_data$df_stats |>
+ purrr::pluck(index) |>
+ dplyr::select(n),
+ N.all=data$meta_data$df_stats |>
+ purrr::pluck(index) |>
+ dplyr::select(N),
+ cut.off=cut.off,
+ glue.mask = glue.mask
+ )
+ } else {
+ masked <- table_body |> dplyr::filter(row_type!="missing")
+ }
+
+
+ if ("stat_0" %in% names(masked)){
+ body <- masked
+ tb <- body |> dplyr::filter(row_type!="missing",!is.na(stat_0))
+ f1 <- grep("^stat_0", names(tb))
+
+ meta.index <- data$meta_data$df_stats |>
+ purrr::pluck(index)
+
+ if ("by" %in% names(meta.index)) {
+ meta.index <- meta.index |> dplyr::filter(is.na(by))
+ }
+
+ masked <- masking(body=body,
+ tb=tb,
+ f1=f1,
+ ns = meta.index |>
+ dplyr::select(n)|>
+ dplyr::slice(seq_len(length(f1) * nrow(tb))) |>
+ unlist(use.names = FALSE) |>
+ matrix(ncol = length(f1), byrow = TRUE) |>
+ tibble::as_tibble(.name_repair = "unique_quiet"),
+ Ns= meta.index |>
+ dplyr::select(N_obs) |>
+ dplyr::slice(1)|>
+ unlist(use.names = FALSE),
+ cut.off=cut.off,
+ glue.mask=glue.mask,
+ dec=dec)
+ }
+
+ out <- rbind(
+ masked,
+ table_body |> dplyr::filter(row_type=="missing"))
+
+ } else {
+ out <- table_body
+ }
+
+ if ("missing" %in% out$row_type) {
+ ## Handling missings n is N_miss, and N is N_obs
+
+ missings <- micro_n_masks(
+ body = out |>
+ dplyr::filter(row_type == "missing"),
+ n.all = data$meta_data$df_stats |>
+ purrr::pluck(index) |>
+ dplyr::select(N_miss),
+ N.all=data$meta_data$df_stats |>
+ purrr::pluck(index) |>
+ dplyr::select(N_obs),
+ cut.off=cut.off,
+ glue.mask=glue.mask
+ )
+
+ if ("stat_0" %in% names(missings)) {
+ ## Handling overall column
+ body <- missings
+ tb <- body |> dplyr::filter(row_type=="missing")
+ f1 <- grep("^stat_0", names(tb))
+
+ masking(body=body,
+ tb=tb,
+ f1=f1,
+ ns = data$meta_data$df_stats |>
+ purrr::pluck(index) |>
+ dplyr::filter(is.na(by)) |>
+ dplyr::select(N_miss) |>
+ dplyr::slice(1) |>
+ unlist(use.names = FALSE) |>
+ matrix(ncol = length(f1), byrow = TRUE) |>
+ tibble::as_tibble(.name_repair = "unique_quiet"),
+ Ns=data$meta_data$df_stats |>
+ purrr::pluck(index) |>
+ dplyr::filter(is.na(by)) |>
+ dplyr::select(N_obs) |>
+ dplyr::slice(1) |>
+ unlist(use.names = FALSE),
+ cut.off=cut.off*2,
+ glue.mask=glue.mask,
+ dec=dec)
+
+ }
+
+ out <- rbind(
+ out |>
+ dplyr::filter(row_type != "missing"),
+ missings)
+
+
+
+
+
+ }
+
+ out
+}
+
+micro_n_masks <- function(body, n.all, N.all, cut.off, glue.mask,dec=1) {
+ if (nrow(body) > 1) {
+ # First row removed in case of categorical
+ # Possibly change to include in filter, to have whole df, or just rbind in the end
+ tb <- body |> dplyr::filter(row_type!="label")
+ } else { # last option is "dichotomous"
+ tb <- body
+ }
+
+ ## Supports any number of stat columns (overkill!)
+ f1 <- grep("^stat_[1-9]|[1-9]\\d", names(tb))
+
+ masking(body=body,
+ tb=tb,
+ f1 = f1,
+ ns=n.all |>
+ dplyr::slice(seq_len(length(f1) * nrow(tb))) |>
+ unlist(use.names = FALSE) |>
+ matrix(ncol = length(f1), byrow = TRUE) |>
+ tibble::as_tibble(.name_repair = "unique_quiet"),
+ Ns=N.all |>
+ dplyr::slice(seq_len(length(f1))) |>
+ unlist(use.names = FALSE),
+ cut.off=cut.off,
+ glue.mask=glue.mask,
+ dec=dec
+ )
+
+}
+
+
+#' Title
+#'
+#' @param body full table body
+#' @param tb filtered table body
+#' @param f1 Subsets indexes of relevant columns
+#' @param ns Relevant ns arranged in matrix
+#' @param Ns All Ns
+#' @param cut.off
+#' @param glue.mask
+#' @param dec
+#'
+#' @return
+#' @export
+masking <- function(body,
+ tb=NULL,
+ f1,
+ ns,
+ Ns,
+ cut.off=cut.off,
+ glue.mask=glue.mask,
+ dec=dec
+ ){
+
+ if (is.null(tb)) tb <- body
+
+ ## Logical matrix of relevant ns to mask
+ f2 <- ns |>
+ purrr::map(\(.x) .x %in% 1:(cut.off - 1)) |>
+ dplyr::bind_cols() |>
+ as.matrix()
+
+ ## Number of cells with zero observations in each matrix row
+ n0 <- apply(ns == 0, 1, sum)
+
+ ## Number of cells with ns to mask in each matrix row
+ ns.low <- apply(f2, 1, sum)
+
+
+ if (all(ns.low==0)){
+ out <- body
+ } else {
+
+ ls.rows <- seq_len(nrow(f2)) |>
+ purrr::map(\(.i){
+
+ ds <- tb[.i, ]
+ # Creating masked matrix to record maskings
+ masked <- matrix(FALSE, ncol = ncol(f2))
+
+ # Only modify in case of low, handle one col matrices
+ if (apply(f2, 1, any)[.i]) {
+ n <- cut.off
+ N <- Ns[f2[.i,]]
+ p <- round(100 * n / N, dec)
+
+ ds[f1[f2[.i,]]] <- glue::glue(glue.mask) |>
+ as.matrix() |>
+ t() |>
+ tibble::as_tibble(.name_repair = "unique_quiet")
+ masked[f2[.i,]] <- TRUE
+
+ ## loop to add masks until satisfied
+ while (sum(masked)==1 & # The case of only one low
+ nrow(masked)>1 | # But ignored in case of ncol==1
+ sum(ns[.i,][masked]) <= cut.off &
+ (sum(masked) + n0[.i]) < ncol(masked)) {
+ # in the case that sum of smalls is below cutoff, another field is added.
+
+ ranked <- apply(ns[.i,], 1, rank, ties.method = "first") |> t()
+
+ ranked.i <- ranked == sum(masked) + n0[.i] + 1
+ n <- ns[.i,][ranked.i] |> plyr::round_any(accuracy = cut.off, f = ceiling)
+ N <- Ns[ranked.i]
+ p <- round(100 * n / N, dec)
+
+ ds[f1[ranked.i]] <- glue::glue(glue.mask)
+ masked[ranked.i] <- TRUE
+ }}
+
+ list(
+ ds = ds,
+ masked = masked
+ )
+ })
+
+ # The case for dichotomous
+ if (nrow(tb) == 1) {
+ out <- ls.rows |>
+ purrr::map(purrr::pluck, "ds") |>
+ dplyr::bind_rows()
+
+ # Handling categorical data
+ } else if (nrow(tb) > 1) {
+ masks <- ls.rows |>
+ purrr::map(purrr::pluck, "masked") |>
+ purrr::reduce(rbind)
+
+ out <- ls.rows |>
+ purrr::map(purrr::pluck, "ds") |>
+ dplyr::bind_rows()
+
+ ## Indices by row
+ col.i <- seq_len(nrow(masks)) |> purrr::map(\(.j){
+ which(masks[.j,])
+ })
+
+ col.i.vec <- purrr::list_c(col.i) |> unique()
+
+ if (purrr::compact(col.i) |> length() == 1){
+ # As this is only the case with overall column
+ # This should be reworked
+
+ # This was the approach, to just select the first
+ # which(purrr::map_lgl(col.i,is_empty))[1]
+
+ # This will select the cell with the second lowest number
+ col.i[[which(rank(ns,ties.method = "first")==2)]] <- c("")
+ }
+
+ out <- col.i |>
+ purrr::map(\(.y){
+ # length(.y)
+ if (length(.y) > 0) {
+ cols <- col.i.vec[!col.i.vec %in% .y]
+ if (length(cols)==0){
+ cols <- ""
+ } else {
+ cols
+ }
+ } else {
+ .y
+ }
+ }) |>
+ purrr::imap(\(.y, .i){
+ ds <- out[.i, ]
+ if (length(.y) > 0 & all(.y!="")) {
+ n <- ns[.i, .y] |>
+ purrr::map_dfr(plyr::round_any,accuracy = cut.off, f = ceiling)
+ N <- Ns[.y]
+ p <- round(100 * n / N, dec)
+ if (n==0) glue.mask <- "{n}"
+
+ ds[f1[.y]] <- glue::glue(glue.mask)|>
+ as.matrix() |>
+ t() |>
+ tibble::as_tibble(.name_repair = "unique_quiet")
+ ds
+ } else {
+ ds
+ }
+ }) |>
+ dplyr::bind_rows()
+
+ out <- rbind(
+ body |>
+ dplyr::filter(row_type=="label"),
+ out
+ )
+ }
+ }
+ out
+
+}
+
+
+summary_masks <- function(body,ls,cut.off=5,dec=dec){
+ seq_along(unique(body$variable)) |>
+ purrr::map(function(.x) {
+ variable_masks(index=.x,data=ls,cut.off=cut.off,dec=dec)
+ }) |>
+ dplyr::bind_rows()
+}
+
+mask_micro_summary <- function(data,micro.n=5){
+ data |>
+ gtsummary::modify_table_body(
+ ~ .x |> summary_masks(ls=data,cut.off = micro.n,dec=1)
+ )
+}
+
+#' Title
+#'
+#' @param mask
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' minimal_mask(mask=tibble::as_tibble(matrix(c(FALSE,FALSE,TRUE,TRUE),nrow=1),.name_repair="unique_quiet"),
+#' data=tibble::as_tibble(matrix(c(20,12,8,4),nrow=1),.name_repair="unique_quiet"),micro.n=5)
+minimal_mask <- function(mask,data,micro.n){
+ ## Function assumes monotonous data
+ ## Use with column_diffs() for risk tables
+
+ ## FUnction works in practice, but example doesn't??
+
+ out <- mask
+
+ for (i in seq_len(nrow(mask))){
+ if (i>1){
+ for (j in seq_len(ncol(mask))){
+ if(dplyr::pull(mask[i,j])){
+ n <- max(which(which(!out[i,])
+#' events_dataset(impute = FALSE) |>
+#' cox_regression(all.vars = FALSE) |>
+#' ggsurvfit::survfit2() |>
+#' ggsurvfit::tidy_survfit(times = c(0, 2, 4, 6, 8.5))|>
+#' tidyr::pivot_wider(id_cols = strata, names_from = time, values_from = cum.event)
+#' data |> mask_micro_table(col.sel=-strata)
+#' data.sel <- data |> dplyr::select(-strata)
+mask_micro_table <- function(data, micro.n = 5, down = TRUE, col.sel) {
+ data.sel <- data |>
+ dplyr::select({{ col.sel }})
+
+ ## List of the two selection matrices
+ masked <- list(
+ data.sel, # The actual data
+ data.sel |>
+ column_diffs(include.first = TRUE) # Row differences (incl first row)
+ ) |>
+ purrr::map(\(.y){ # For each element in the list, do colwise test
+ .y |>
+ purrr::map_dfr(\(.x) .x %in% 1:(micro.n-1))
+ }) |>
+ purrr::imap(\(.y,.i){ # apply minimal masking to last list object
+ if (.i==2){
+ .y |> minimal_mask(data = data.sel,micro.n=micro.n)
+ }else {
+ .y
+ }
+ }) |>
+ purrr::reduce(`|`) |> # Combine matrices
+ tibble::as_tibble() |> # To tibble
+ purrr::map2(data.sel, \(.x, .y){ # Apply masking based on combined selection
+ ifelse(.x, rounded_interval(.y, round = micro.n, down = down), .y)
+ }) |>
+ dplyr::bind_cols()
+
+ ## Bind masked data to original columns
+ dplyr::bind_cols(
+ data |>
+ dplyr::select(-{{ col.sel }}),
+ masked|>
+ # Converts new to character for uniform data
+ dplyr::mutate(dplyr::across(dplyr::everything(), ~ as.character(.x)))
+ ) |>
+ dplyr::select(colnames(data)) # Order columns as original input data
+}
+
+rounded_interval <- function(data, round = 5, down = TRUE) {
+ # Handle "ties"
+ sub <- ifelse(down, -1, 1)
+ data <- ifelse(data %% round == 0 & data != 0, data + 1, data)
+
+ c(floor, ceiling) |>
+ purrr::map(\(.x) {
+ plyr::round_any(x = data, accuracy = round, f = .x)
+ }) |>
+ dplyr::bind_cols(.name_repair = "unique_quiet") |>
+ setNames(c("l", "h")) |>
+ dplyr::transmute(mask = glue::glue("{l}-{h}")) |>
+ dplyr::pull(mask)
+}
+
+column_diffs <- function(data, prefix.pattern = NULL, include.first = TRUE, suffix.out = "_diff") {
+ if (!is.null(prefix.pattern)) {
+ data <- data |>
+ dplyr::select(tidyselect::starts_with(prefix.pattern))
+ }
+
+ index <- seq_along(data)[-1]
+
+ diff <- index |>
+ purrr::map(\(.y){
+ abs(data[.y - 1] - data[.y])
+ }) |>
+ dplyr::bind_cols() |>
+ (\(.x) setNames(.x, paste0(names(.x), suffix.out)))()
+
+ if (include.first) {
+ out <- dplyr::bind_cols(data[1], diff)
+ } else {
+ out <- diff
+ }
+ out
+}
+
+
+collect_calibration<-function(data){
+ data|>
+ purrr::map(\(.y) {
+ .y |>
+ purrr::pluck("model") |>
+ purrr::pluck("TestProb") |>
+ dplyr::bind_rows()
+ })
+}
+
+collect_calibration_mids<-function(data){
+ data|>
+ purrr::map(\(.z) {
+ .z |>
+ purrr::map(\(.y) {
+ .y |>
+ purrr::pluck("model") |>
+ purrr::pluck("TestProb") |>
+ dplyr::bind_rows()
+ }) |>
+ dplyr::bind_rows()
+ })
+}
+
+plot_calibration<-function(data,name) {
+ predtools::calibration_plot(
+ data = as.data.frame(
+ dplyr::select(data, y, pred) |>
+ dplyr::mutate(y = as.numeric(y) -
+ 1)
+ ),
+ obs = "y",
+ pred = "pred"#,
+ # x_lim = c(0, 1),
+ # y_lim = c(-.1, 1.1)
+ ) |>
+ purrr::pluck("calibration_plot") +
+ ggplot2::labs(title = name)+
+ ggplot2::scale_x_continuous(breaks=seq(0,1,.25),limits=c(0, 1))+
+ ggplot2::scale_y_continuous(breaks=seq(0,1,.25),limits = c(-.1, 1.1))
+}
+
+print_calibration<-function(data,file){
+ ggplot2::ggsave(filename =file,plot = data,device = "png",dpi = 600,width = 84,height = 150,units = "mm")
+}
+
+map_summary_results <- function(data){
+ data |> lapply(\(.x){
+ .x |>
+ multi_summary() |>
+ print_model_resutls()
+ })
+}
+
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' list("Raw dec/inc quartiles" = targets::tar_read(ls_pred_models)) |> map_summary_results() |> minimal_performance_table()
+minimal_performance_table <- function(data){
+ data |>
+ purrr::imap(\(.x, .i){
+ df_perf <- lapply(.x[[3]], \(.y){
+ Reduce(c, .y)
+ }) |> dplyr::bind_rows()
+
+ df_ns <- .x[[2]] |>
+ purrr::map(\(.y) {
+ tibble::tibble(N=sum(.y),
+ n=sum(.y[2,]))
+ }) |>
+ dplyr::bind_rows()
+
+
+ df_auc <- .x[[4]] |>
+ purrr::map(\(.y) .y[["Median"]]) |>
+ purrr::reduce(c)
+
+ ## Here should follow a block to add median alpha and lambda to the table overview
+
+ df_tune <- purrr::map(.x[[5]], \(.y){
+ .y |>
+ purrr::map(\(.z){
+ .z[["Median"]]
+ }) |>
+ purrr::reduce(c)
+ }) |> dplyr::bind_cols()
+
+ tibble::tibble(
+ group = .i,
+ model = names(.x[[3]]),
+ df_ns,
+ df_perf,
+ "Median AUC" = df_auc,
+ setNames(df_tune, paste("Median", names(df_tune)))
+ )
+ }) |>
+ dplyr::bind_rows() |>
+ dplyr::select(group, model, N,n,Sensitivity, Specificity, `Pos Pred Value`, `Neg Pred Value`, tidyselect::starts_with("Median"))
+}
+
+data_prep_mmrm <- function(data){
+ data |>
+ dplyr::mutate(id = factor(dplyr::row_number())) |>
+ dplyr::select(id, dplyr::everything(), -reg_bmi) |>
+ tidyr::pivot_longer(
+ cols = dplyr::starts_with("pase_"),
+ values_to = "pase", names_to = "time"
+ ) |>
+ dplyr::mutate(time = factor(time), ) |>
+ dplyr::mutate(dplyr::across(dplyr::where(is.logical), \(.x) as.numeric(.x)))
+}
+
+split_sex <- function(data,var="reg_female"){
+ data |>
+ (\(.x){
+ split(dplyr::select(.x,-tidyselect::all_of(var)),.x[[var]]) |>
+ setNames(c("male","female"))
+ })()
+}
+
+simple_multi_mmrm <- function(data,vars.out=c("pase", "time", "id")){
+ vars <- names(data)[!names(data) %in% c("pase", "time", "id")]
+
+ ## mmrm doesn't work too well with gtsummary as variable sorting is lost
+ mmrm::mmrm(as.formula(paste0("pase~", paste(vars, collapse = "+"), "+us(time|id)")), data = data)
+}
+
+simple_uni_mmrm <- function(data,vars.out=c("pase", "time", "id")){
+ vars <- names(data)[!names(data) %in% c("pase", "time", "id")]
+
+ ## mmrm doesn't work too well with gtsummary as variable sorting is lost
+ vars |> purrr::map(\(.x){
+ mmrm::mmrm(as.formula(paste0("pase~", .x, "+us(time|id)")), data = data)
+ })
+
+}
+
+mmrm_summary <- function(data){
+ gtsummary::tbl_regression(data,
+ add_header_row = TRUE,
+ show_single_row = tidyselect::where(is.logical),
+ tidy_fun = broom.helpers::tidy_parameters
+ ) |>
+ fix_labels() |>
+ gtsummary::modify_table_styling(column = p.value,
+ hide=TRUE)
+}
+
+
+df_mega_list <- function(
+ strategies=c(
+ "bin_original",
+ "bin_anyupdown",
+ "bin_relupdown",
+ "bin_absupdown",
+ "bin_quantile",
+ "bin_clusterlcm",
+ "bin_percentage")){
+ purrr::map(strategies, \(.z){
+ if (.z == "bin_original") {
+ f <- eval(str2expression(.z))
+ list(c(list(binning.fun = f), list(var.excl = c("pase_4", "pase_0_quartile", "pase_4_quartile", "pase_split", "pase_dif", "pase_rel_dif")), list(name = "original_change")))
+ } else if (.z == "bin_anyupdown") {
+ f <- eval(str2expression(.z))
+ purrr::map(c("_q1", "_half"), \(.y){
+ if (.y == "_q1") {
+ out <- list(binning.fun = f, low.q = 1, high.q = 2:4)
+ } else if (.y == "_half") {
+ out <- list(binning.fun = f, low.q = 1:2, high.q = 3:4)
+ }
+ c(out, list(var.excl = c("pase_4", "pase_0_quartile", "pase_4_quartile", "pase_split", "pase_dif", "pase_rel_dif")), list(name = glue::glue("any_change{.y}")))
+ }) # |> purrr::list_flatten()
+ } else if (.z == "bin_relupdown") {
+ f <- eval(str2expression(.z))
+ purrr::map(c(20, 50, 75), \(.x){
+ out <- purrr::map(c("_q1", "_half"), \(.y){
+ if (.y == "_q1") {
+ out <- list(binning.fun = f, rel.bin = .x, low.q = 1, high.q = 2:4)
+ } else if (.y == "_half") {
+ out <- list(binning.fun = f, rel.bin = .x, low.q = 1:2, high.q = 3:4)
+ }
+ c(out, list(var.excl = c("pase_4", "pase_0_quartile", "pase_4_quartile", "pase_split", "pase_dif", "pase_rel_dif")), list(name = glue::glue("rel_change_{.x}{.y}")))
+ })
+ }) |> purrr::list_flatten()
+ } else if (.z == "bin_absupdown") {
+ f <- eval(str2expression(.z))
+ purrr::map(seq(40, 100, 20), \(.x){
+ out <- purrr::map(c("_q1", "_half"), \(.y){
+ if (.y == "_q1") {
+ out <- list(binning.fun = f, abs.bin = .x, low.q = 1, high.q = 2:4)
+ } else if (.y == "_half") {
+ out <- list(binning.fun = f, abs.bin = .x, low.q = 1:2, high.q = 3:4)
+ }
+ c(out, list(var.excl = c("pase_4", "pase_0_quartile", "pase_4_quartile", "pase_split", "pase_dif", "pase_rel_dif")), list(name = glue::glue("abs_change_{.x}{.y}")))
+ })
+ }) |> purrr::list_flatten()
+ } else if (.z == "bin_percentage") {
+ f <- eval(str2expression(.z))
+ purrr::map(c(5, 15), \(.x){
+ out <- list(binning.fun = f, percentage = .x)
+ c(out, list(var.excl = c("pase_4", "pase_0_quartile", "pase_4_quartile", "pase_split", "pase_dif", "pase_rel_dif","pase_0_cut","pase_4_cut")), list(name = glue::glue("lowest_percentage_{.x}")))
+ })
+ } else if (.z == "bin_quantile") {
+ f <- eval(str2expression(.z))
+ purrr::map(seq(6, 10, 2), \(.x){
+ purrr::map(seq_len(floor(.x/2)), \(.y){
+ purrr::map(c(FALSE,TRUE),\(.any){
+ out <- list(binning.fun = f, quantiles = .x, lowest = .y, any = .any)
+
+ c(out,
+ list(var.excl = c("pase_4", "pase_0_quartile", "pase_4_quartile", "pase_split", "pase_dif", "pase_rel_dif"
+ ,
+ "pase_0_quantile", "pase_4_quantile"
+ )),
+ list(name = glue::glue("quantile_change_{.x}_{.y}{ifelse(.any,'_ANY','')}"))
+ )
+
+ })
+
+ })|> purrr::list_flatten()
+ }) |> purrr::list_flatten()
+ } else if (.z == "bin_clusterlcm") {
+ f <- eval(str2expression(.z))
+ list(c(
+ list(binning.fun = f),
+ list(var.excl=c("pase_0_quartile","pase_4_quartile","pase_split","pase_dif","pase_rel_dif")), #Returns all false, which crashes the function
+ list(name = "cluster_lcm")
+ ))
+ }
+ }) |> purrr::list_flatten()
+}
+
+
+multi_grouping_wrapper <- function(name, ...) {
+ .f <- function(...) {
+ data |>
+ group_format(...)
+ }
+
+ list(.f(...)) |> setNames(name)
+}
+
+# ls <- df_mega_list()
+
+# ls <- c(list(binning.fun = bin_quantile, quantiles = 5, lowest = 2, any=FALSE), list(var.excl = c("pase_4", "pase_0_quartile", "pase_4_quartile", "pase_split", "pase_dif", "pase_rel_dif")), list(name = glue::glue("quantile_change_5_2")))
+# # , "pase_0_quantile", "pase_4_quantile"
+# multi_grouping_df_list(data=targets::tar_read(df_all_data_formatted),list(ls)) |> purrr::pluck(1) |> View()
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> multi_grouping_df_list(args.list=df_mega_list())
+multi_grouping_df_list <- function(data,args.list,remove=NULL){
+ purrr::map(args.list, \(.x){
+ if ("mids" %in% class(data)){
+ out <- data |>
+ mice::complete(action = "long", include = TRUE) |>
+ (\(.y){
+ do.call(multi_grouping_wrapper, c(list(data = .y), .x))
+ })() |>
+ purrr::map(\(.z){
+ .z |>
+ dplyr::select(-tidyselect::any_of(remove)) |>
+ mice::as.mids()
+ })
+ } else {
+ out <- do.call(multi_grouping_wrapper, c(list(data = data), .x))|>
+ purrr::map(\(.z){
+ .z |>
+ dplyr::select(-tidyselect::any_of(remove))
+ })
+ }
+ out
+ }) |> purrr::list_flatten()
+ }
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(list_df_multi_grouping)[24] |> multi_results_list()
+multi_results_list <- function(data){
+ data |>
+ purrr::map(\(.x){
+ list(summary=.x |> gtsummary::tbl_summary(by = pase_change),
+ cox = .x |>
+ # dplyr::select(-pase_0,-pase_4,-pase_rel_dif) |>
+ cox_regression(all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_change") |>
+ tbl_regression_standard(),
+ plot=.x |>
+ # dplyr::select(-pase_0,-pase_4,-pase_rel_dif) |>
+ cox_regression() |>
+ ggsurvfit::survfit2() |>
+ ggsurvfit::ggsurvfit() + ggsurvfit::add_confidence_interval() +
+ ggsurvfit::scale_ggsurvfit() +
+ ggsurvfit::add_risktable()
+ )
+ })}
+
+multi_cox_performance_test <- function(data,...){
+ data |>
+ purrr::imap(\(.x,.i){
+ out <- .x |>
+ cox_regression(...) |>
+ performance::model_performance()
+ tibble::tibble(Name=.i,out)
+ })|>
+ dplyr::bind_rows() |>
+ dplyr::mutate(rank=rank(AIC,ties.method = "min"))
+ # performance::compare_performance(rank = TRUE)
+}
+
+
+mids_model_aic <- function(data){
+ sapply(data[["analyses"]],AIC) |>
+ median()
+}
+
+pick_non_duplicated <- function(data,name,aic,i){
+ data[[name]][!duplicated(data[[aic]])][i]
+}
diff --git a/2 Longterm/260315/glmnet-reg.R b/2 Longterm/260315/glmnet-reg.R
new file mode 100755
index 0000000..72b6eec
--- /dev/null
+++ b/2 Longterm/260315/glmnet-reg.R
@@ -0,0 +1,340 @@
+## ItMLiHSmar2022
+## regular_fun.R, child script
+## Regularisation model building function
+## Andreas Gammelgaard Damsbo, agdamsbo@clin.au.dk
+##
+## Now modified to use in publication
+##
+
+regular_fun <- function(X, y, K, lambdas, alpha) {
+ n <- nrow(X)
+ set.seed(321)
+
+ # Using caret function to ensure both levels represented in all folds
+ c <- caret::createFolds(y = y, k = K, list = FALSE, returnTrain = TRUE)
+
+ B <- yhatTestProbKeep <- list()
+ accTrain <- accTest <- err_train <- err_test <- auc_train <- auc_test <- matrix(nrow = K, ncol = length(lambdas))
+
+ TrainProb <- TestProb <- list()
+
+ catinfo <- levels(y)
+
+ cMatTrain <- cMatTest <- table(true = factor(c(0, 0), levels = catinfo), pred = factor(c(0, 0), levels = catinfo))
+
+
+ ## Iterate over partitions
+ for (idx1 in 1:K) {
+ # Status
+ cat("Processing fold", idx1, "of", K, "\n")
+
+ # idx1=1
+ # Get training- and test sets
+ I_train <- c != idx1 ## Creating selection vector of TRUE/FALSE
+ I_test <- !I_train
+
+ Xtrain <- X[I_train, ]
+ ytrain <- y[I_train]
+ Xtest <- X[I_test, ]
+ ytest <- y[I_test]
+
+
+ ## Model matrices for glmnet
+ ## Using the complicated approach not to include first level.
+ # Xmat.train<-model.matrix(~ .-1, data=Xtrain,
+ # contrasts.arg = lapply(Xtrain[,sapply(Xtrain, is.factor)],
+ # contrasts, contrasts=T))
+ # Xmat.test<-model.matrix(~ .-1, data=Xtest,
+ # contrasts.arg = lapply(Xtest[,sapply(Xtest, is.factor)],
+ # contrasts, contrasts=T))
+
+ # Xmat.train<-model.matrix(~.-1,Xtrain)
+ # Xmat.test<-model.matrix(~.-1,Xtest)
+
+ # Weights
+ ytrain_weight <- as.vector(1 - (table(ytrain)[ytrain] / length(ytrain)))
+ # ytest_weight<-as.vector(1 / (table(ytest)[ytest] / length(ytest)))
+
+ # Fit regularized linear regression model
+ mod <- glmnet::glmnet(Xtrain, ytrain,
+ alpha = alpha, ## Alpha = 1 for lasso
+ lambda = lambdas, ## Setting lambdas
+ standardize = TRUE, ## Scales and centers
+ weights = ytrain_weight,
+ family = "binomial"
+ )
+
+ # Keep coefficients for plot
+ B[[idx1]] <- as.matrix(coef(mod))
+
+ # TrainProb[[idx1]] <- list()
+ TestProb[[idx1]] <- list()
+
+ # Iterate over regularization strengths to compute training- and test
+ # errors for individual regularization strengths.
+ for (idx2 in 1:length(lambdas)) {
+ # idx2=1
+
+ # Predict
+ yhatTrainProb <- predict(mod,
+ s = lambdas[idx2],
+ newx = data.matrix(Xtrain),
+ type = "response"
+ )
+
+ yhatTestProb <- predict(mod,
+ s = lambdas[idx2],
+ newx = data.matrix(Xtest),
+ type = "response"
+ )
+
+ # Compute training and test error
+ yhatTrain <- round(yhatTrainProb)
+ yhatTest <- round(yhatTestProb)
+
+ TestProb[[idx1]][[idx2]] <- dplyr::bind_cols(data.matrix(Xtest),y=ytest,pred=yhatTestProb,.name_repair = "unique_quiet")
+
+ # Make predictions categorical again (instead of 0/1 coding)
+ yhatTrainCat <- factor(round(yhatTrainProb), levels = c("0", "1"), labels = catinfo, ordered = TRUE)
+ yhatTestCat <- factor(round(yhatTestProb), levels = c("0", "1"), labels = catinfo, ordered = TRUE)
+
+ # Evaluate classifier performance
+ # Accuracy
+ # accTrain[idx1,idx2] <- sum(yhatTrainCat==ytrain)/length(ytrain)
+ # accTest [idx1,idx2] <- sum(yhatTestCat==ytest)/length(ytest)
+ # #
+ # # Error rate
+ # err_train[idx1,idx2] = 1 - accTrain[idx1,idx2]
+ # err_test [idx1,idx2] = 1 - accTest[idx1,idx2]
+
+ # AUROC
+ suppressMessages(
+ auc_train[idx1, idx2] <- pROC::auc(ytrain, yhatTrainCat)
+ )
+ suppressMessages(
+ auc_test[idx1, idx2] <- pROC::auc(ytest, yhatTestCat)
+ )
+
+ # Compute confusion matrices
+ cMatTrain <- cMatTrain + table(true = ytrain, pred = yhatTrainCat)
+ cMatTest <- cMatTest + table(true = ytest, pred = yhatTestCat)
+ }
+ }
+ list(mod = mod, B = B, auc_train = auc_train, auc_test = auc_test, cMatTrain = cMatTrain, cMatTest = cMatTest,
+ TrainProb=TrainProb,
+ TestProb=TestProb)
+}
+
+
+## ItMLiHSmar2022
+## regularisation_steps.R, child script
+## Regularised model building and analysation for assignment
+## Andreas Gammelgaard Damsbo, agdamsbo@clin.au.dk
+##
+## Now modified to use in publication
+##
+
+
+
+#' Title
+#'
+#' @param data
+#' @param outcome.var
+#' @param weighted
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_pred_data) |>
+#' pred_ls_split(excluded.vars = "reg_bmi")
+#'
+#' data <- data[[1]]
+#' mod <- data |> regularisation_steps(auto.l=TRUE)
+regularisation_steps <- function(data, outcome.var = "pase_bin", weighted = FALSE, auto.l = FALSE) {
+ n <- nrow(data)
+
+ y <- data |> dplyr::select({{ outcome.var }})
+ X <- data |> dplyr::select(-{{ outcome.var }})
+
+ ## ====================================================================
+ ## Step 0: data import and wrangling
+ ## ====================================================================
+
+ # setwd("/Users/au301842/PhysicalActivityandStrokeOutcome/1 PA Decline/")
+
+ # source("data_format.R")
+ y1 <- factor(as.integer(y[[1]])) ## Outcome is required to be factor of 0 or 1.
+ # summary(y1)
+
+ ## ====================================================================
+ ## Step 1: settings
+ ## ====================================================================
+
+ ## Folds
+ K <- 10
+ set.seed(3)
+ c <- caret::createFolds(
+ y = y1,
+ k = K,
+ list = FALSE,
+ returnTrain = TRUE
+ ) # Fold IDs for tuning
+
+ ## Defining tuning parameters
+ if (auto.l){
+ lambdas <- NULL
+ } else {
+ lambdas <- 2^seq(-10, 20, 1)
+ }
+
+ alphas <- seq(0, 1, .1)
+
+ ## Weights for models
+ if (weighted) {
+ wght <- as.vector(1 - (table(y1)[y1] / length(y1)))
+ } else {
+ wght <- rep(1, length(y1))
+ }
+
+
+ ## Standardise numeric
+ ## Centered and
+
+
+
+ ## ====================================================================
+ ## Step 2: all cross validations for each alpha
+ ## ====================================================================
+
+ # library(furrr)
+ # library(purrr)
+ # library(doMC)
+ # registerDoMC(cores=6)
+
+ future::plan(strategy = "multisession", workers = 2)
+
+ # Nested CVs with analysis for all lambdas for each alpha
+ #
+ set.seed(3)
+ cvs <- furrr::future_map(alphas, .options = furrr::furrr_options(seed = 3), function(a) {
+ glmnet::cv.glmnet(model.matrix(~ . - 1, X),
+ y1,
+ weights = wght,
+ lambda = lambdas,
+ type.measure = "deviance", # This is standard measure and recommended for tuning
+ foldid = c, # Per recommendation the folds are kept for alpha optimisation
+ alpha = a,
+ standardize = TRUE,
+ family = quasibinomial, # Same as binomial, but not as picky
+ keep = TRUE
+ )
+ })
+
+ ## ====================================================================
+ # Step 3: optimum lambda for each alpha
+ ## ====================================================================
+
+
+ # For each alpha, lambda is chosen for the lowest meassure (deviance)
+ each_alpha <- sapply(seq_along(alphas), function(id) {
+ each_cv <- cvs[[id]]
+ alpha_val <- alphas[id]
+ index_lmin <- match(
+ each_cv$lambda.min,
+ each_cv$lambda
+ )
+ c(
+ lamb = each_cv$lambda.min,
+ alph = alpha_val,
+ cvm = each_cv$cvm[index_lmin]
+ )
+ })
+
+ if (auto.l){
+ # Best (min) lambda
+ best_lamb <- min(each_alpha["lamb", ])
+
+ # Alpha is chosen for best lambda with lowest model deviance, each_alpha["cvm",]
+ best_alph <- each_alpha["alph", ][each_alpha["cvm", ] == min(each_alpha["cvm", ]
+ [each_alpha["lamb", ] %in% best_lamb])]
+
+ # BEst lamb is set to NULL to allow glm.net to use the optimal method, which is bult in.
+ # best_lamb <- NULL
+
+ } else {
+ # Best (min) lambda
+ best_lamb <- min(each_alpha["lamb", ])
+
+ # Alpha is chosen for best lambda with lowest model deviance, each_alpha["cvm",]
+ best_alph <- each_alpha["alph", ][each_alpha["cvm", ] == min(each_alpha["cvm", ]
+ [each_alpha["lamb", ] %in% best_lamb])]
+ }
+
+
+ ## https://stackoverflow.com/questions/42007313/plot-an-roc-curve-in-r-with-ggplot2
+ # df_roc <- glmnet::roc.glmnet(cvs[[match(best_alph, alphas)]]$fit.preval, newy = y1)[match(best_lamb, lambdas)]# |> # Plots performance from model with best alpha
+ #
+ # df_roc |> plot_roc_curve()
+
+ ## ====================================================================
+ # Step 4: Creating the final model
+ ## ====================================================================
+
+ # source(here::here("R/regular_fun.R")) # Custom function
+ optimised_model <- regular_fun(X = X, y = y1, K = K, lambdas = best_lamb, alpha = best_alph)
+ # With lambda and alpha specified, the function is just a k-fold cross-validation wrapper,
+ # but keeps model performance figures from each fold.
+
+ # list2env(optimised_model, .GlobalEnv)
+ # Function outputs a list, which is unwrapped to Env.
+ # See source script for reference.
+
+ ## ====================================================================
+ # Step 5: creating table of coefficients for inference
+ ## ====================================================================
+
+ # reg_coef_tbl <- optimised_model$B |> purrr::reduce(cbind)
+
+ # Bmatrix <- optimised_model$B |> purrr::reduce(cbind)
+ # Bmedian <- apply(Bmatrix, 1, median)
+ # Bmean <- apply(Bmatrix, 1, mean)
+ #
+ # reg_coef_tbl <- dplyr::tibble(
+ # name = rownames(Bmatrix),
+ # medianX = round(Bmedian, 5),
+ # ORmed = round(exp(Bmedian), 5),
+ # meanX = round(Bmean, 5),
+ # ORmea = round(exp(Bmean), 5)
+ # ) # |>
+ # arrange(desc(abs(medianX)))%>%
+ # gt::gt()
+
+ ## ====================================================================
+ # Step 6: plotting predictive performance
+ ## ====================================================================
+
+ # reg_cfm <- caret::confusionMatrix(optimised_model$cMatTest)
+ # reg_cfm <- optimised_model$cMatTest
+ # reg_auc_sum <- optimised_model$auc_test[, 1]
+
+ ## ====================================================================
+ # Step 7: Packing list to save in loop
+ ## ====================================================================
+
+ list(
+ "IncludedN" = n,
+ "model" = optimised_model,
+ "alphas" = alphas,
+ "bestA" = best_alph,
+ "lambdas" = lambdas,
+ "bestL" = best_lamb,
+ # "TestTable" = reg_cfm,
+ # "AUROC" = reg_auc_sum,
+ # "ROC curve" = df_roc,
+ "y1" = y1,
+ "X" = X,
+ "data" = data,
+ "cvs" = cvs
+ )
+}
diff --git a/2 Longterm/260315/last_sensitivity.R b/2 Longterm/260315/last_sensitivity.R
new file mode 100755
index 0000000..3ebd40d
--- /dev/null
+++ b/2 Longterm/260315/last_sensitivity.R
@@ -0,0 +1,172 @@
+targets::tar_read("df_all_data_formatted") |>
+ events_ready() |>
+ dplyr::filter(!is.na(pase_0), !is.na(pase_4)) |>
+ (\(data){
+ c("pase_0", "pase_4") |>
+ purrr::map(\(exp){
+ list(
+ "Univariable" = cox_regression(data = data, all.vars = FALSE, use.strata = FALSE, outcome.var = exp),
+ "Multivariable" = cox_regression(data = data, all.vars = TRUE, use.strata = FALSE, outcome.var = exp)
+ ) |>
+ purrr::map(\(.x){
+ .x |>
+ gtsummary::tbl_regression(exponentiate = TRUE) |>
+ fix_labels()
+ }) |>
+ tbl_merged_named()
+ })
+ })() |>
+ gtsummary::tbl_stack()
+
+
+targets::tar_read("df_all_data_formatted") |>
+ pase_cutter(drop.nas = TRUE) |>
+ events_ready(v.groups = c("clin", "lifestyle.events", "ses", "assess.events", "quartiles")) |>
+ dplyr::select(-dplyr::any_of(c("pase_0", "pase_4", "pase_change"))) |>
+ (\(data){
+ c("pase_0_quartile", "pase_4_quartile") |>
+ purrr::map(\(exp){
+ list(
+ "Univariable" = cox_regression(data = data, all.vars = FALSE, use.strata = FALSE, outcome.var = exp),
+ "Multivariable" = cox_regression(data = data, all.vars = TRUE, use.strata = FALSE, outcome.var = exp)
+ ) |>
+ purrr::map(\(.x){
+ .x |>
+ gtsummary::tbl_regression(exponentiate = TRUE) |>
+ fix_labels()
+ }) |>
+ tbl_merged_named()
+ })
+ })() |>
+ gtsummary::tbl_stack()
+
+
+targets::tar_read("df_all_data_formatted") |>
+ pase_cutter(drop.nas = TRUE) |>
+ get_vars(vars.groups = c("clin", "lifestyle.events", "ses", "assess.events", "quartiles"), vars.vec = c("inc_time")) |>
+ dplyr::mutate(time = time + inc_time / 365) |>
+ dplyr::select(-dplyr::any_of(c("pase_0", "pase_4", "pase_change", "inc_time", "event.include", "pase_4_quartile"))) |>
+ (\(data){
+ list(
+ "Univariable" = cox_regression(data = data, all.vars = FALSE, use.strata = FALSE, outcome.var = "pase_0_quartile"),
+ "Multivariable" = cox_regression(data = data, all.vars = TRUE, use.strata = FALSE, outcome.var = "pase_0_quartile")
+ ) |>
+ purrr::map(\(.x){
+ .x |>
+ gtsummary::tbl_regression(exponentiate = TRUE) |>
+ fix_labels()
+ }) |>
+ tbl_merged_named()
+ })()
+
+ls_sens <- list(
+ pase_0_all_quartile = list(
+ data = targets::tar_read("df_all_data_formatted") |>
+ pase_cutter(drop.nas = FALSE) |>
+ get_vars(vars.groups = c("clin", "lifestyle.events", "ses", "assess.pred", "quartiles"), vars.vec = c("inc_time",
+ "time",
+ "status")) |>
+ dplyr::mutate(time = time + inc_time / 365) |>
+ dplyr::select(-dplyr::any_of(c("pase_0", "pase_4", "pase_change", "inc_time", "event.include", "pase_4_quartile"))),
+ main.exp = "pase_0_quartile"
+ ),
+ # pase_0_all_contin = list(
+ # data = targets::tar_read("df_all_data_formatted") |>
+ # get_vars(vars.groups = c("clin", "lifestyle.events", "ses", "assess.pred", "quartiles"), vars.vec = c("inc_time",
+ # "time",
+ # "status")) |>
+ # dplyr::mutate(time = time + inc_time / 365) |>
+ # dplyr::select(-dplyr::any_of(c("pase_4", "pase_change", "inc_time", "event.include", "pase_0_quartile", "pase_4_quartile"))),
+ # main.exp = "pase_0"
+ # ),
+ pase_0_excl_quartile = list(
+ data = targets::tar_read("df_all_data_formatted") |>
+ pase_cutter(drop.nas = TRUE,drop.pase = FALSE) |>
+ events_ready(v.groups = c("clin", "lifestyle.events", "ses", "assess.pred", "quartiles"), vars.vec = c("inc_time",
+ "time",
+ "status")) |>
+ dplyr::select(-dplyr::any_of(c("pase_0","pase_4", "pase_change", "inc_time", "event.include", "pase_4_quartile"))),
+ main.exp = "pase_0_quartile"
+ ),
+ # pase_0_excl_contin = list(
+ # data = targets::tar_read("df_all_data_formatted") |>
+ # events_ready(v.groups = c("clin", "lifestyle.events", "ses", "assess.pred", "quartiles"), vars.vec = c("inc_time",
+ # "time",
+ # "status")) |>
+ # dplyr::filter(!is.na(pase_0), !is.na(pase_4)) |>
+ # dplyr::select(-pase_4),
+ # main.exp = "pase_0"
+ # ),
+ pase_4_quartile = list(
+ data = targets::tar_read("df_all_data_formatted") |>
+ dplyr::mutate(pase_4_quartile=cut(x = pase_4, breaks = quantile(pase_4, na.rm = TRUE), labels = 1:4, include.lowest = TRUE)) |>
+ get_vars(vars.groups = c("clin", "lifestyle.events", "ses", "assess.events", "quartiles"))|>
+ dplyr::filter(!is.na(pase_4_quartile),event.include) |>
+ dplyr::select(-dplyr::any_of(c("pase_0","pase_4", "pase_change", "inc_time", "event.include", "pase_0_quartile"))),
+ main.exp = "pase_4_quartile"
+ ),
+ # pase_4_contin = list(
+ # data = targets::tar_read("df_all_data_formatted") |>
+ # events_ready() |>
+ # dplyr::filter(!is.na(pase_0), !is.na(pase_4)) |>
+ # dplyr::select(-pase_0),
+ # main.exp = "pase_4"
+ # ),
+ pase_4_change_late_cut = list(
+ data = targets::tar_read("df_all_data_formatted") |>
+ events_ready() |>
+ dplyr::filter(!is.na(pase_0), !is.na(pase_4)) |>
+ pase_cutter(drop.pase = TRUE),
+ main.exp = "pase_change"
+ # ),
+ # pase_4_change_earliest_cut = list(
+ # data = targets::tar_read("df_all_data_formatted") |>
+ # pase_cutter(drop.pase = TRUE)|>
+ # events_ready(vars.vec = c("pase_change")) |>
+ # dplyr::filter(!is.na(pase_change)) ,
+ # main.exp = "pase_change"
+ )
+)
+
+
+
+f <- function(data, main.exp, ...) {
+ set.seed(3023)
+ imp <- fun_impute(data = data, ignore = main.exp)
+
+ list(
+ "Univariable" = cox_regression(data = data, all.vars = FALSE, use.strata = FALSE, outcome.var = main.exp),
+ "Multivariable" = cox_regression(data = data, all.vars = TRUE, use.strata = FALSE, outcome.var = main.exp),
+ "Multivariable Imputed" = cox_regression(data = imp, all.vars = TRUE, use.strata = FALSE, outcome.var = main.exp)
+ )
+}
+
+
+ls_out <- purrr::map(ls_sens, \(.x){
+ do.call(f, .x)
+})
+
+ls_stack <- ls_out |>
+ purrr::imap(\(.x, .i){
+ list(
+ "Group counts" = ls_sens[[.i]][["data"]] |>
+ dplyr::select(ls_sens[[.i]][["main.exp"]]) |>
+ gtsummary::tbl_summary(statistic = list(gtsummary::all_continuous() ~ "{N_nonmiss} ({p_nonmiss}%)", gtsummary::all_categorical() ~ "{n} ({p}%)")) |>
+ fix_labels(),
+ .x |>
+ lapply(\(.y){
+ .y |>
+ tbl_regression_standard() |>
+ # gtsummary::modify_table_styling(columns = tidyselect::starts_with("p.value"), hide = TRUE) |>
+ gtsummary::remove_row_type(variables = -dplyr::any_of(ls_sens[[.i]][["main.exp"]]), type = "all") |>
+ gtsummary::bold_p()
+ })
+ ) |>
+ purrr::list_flatten() |>
+ tbl_merged_named()
+ }) |>
+ tbl_stack_named()
+
+ls_stack <- ls_stack|> gtsummary::as_gt() |> gt::tab_style(style = gt::cell_text(weight="bold"),locations = gt::cells_row_groups(dplyr::everything()))
+
+ls_stack |> gt::gtsave(filename = here::here("out/pase_extra_cox2.docx"))
diff --git a/2 Longterm/260315/sex_events.docx b/2 Longterm/260315/sex_events.docx
new file mode 100755
index 0000000..7a15e78
Binary files /dev/null and b/2 Longterm/260315/sex_events.docx differ
diff --git a/2 Longterm/260315/ssri_events.docx b/2 Longterm/260315/ssri_events.docx
new file mode 100755
index 0000000..68690c0
Binary files /dev/null and b/2 Longterm/260315/ssri_events.docx differ
diff --git a/2 Longterm/DDV 240607/functions.R b/2 Longterm/DDV 240607/functions.R
new file mode 100755
index 0000000..00caaf7
--- /dev/null
+++ b/2 Longterm/DDV 240607/functions.R
@@ -0,0 +1,3389 @@
+# pop <- haven::read_sas(here::here("E:/rawdata/709203/Population/pop_talos.sas7bdat"))
+
+# sst <- list.files(here::here("E:/rawdata/709203/Eksterne data"), pattern = "*.sas7bdat", full.names = TRUE) |>
+# purrr::map(haven::read_sas)
+
+
+
+#' Read all sas files in folder to list
+#'
+#' @param path folder path
+#'
+#' @return list
+sas2list <- function(path) {
+ ls <- list.files(here::here(path), pattern = "*.sas7bdat", full.names = TRUE) |>
+ purrr::map(haven::read_sas)
+ names(ls) <- list.files(here::here(path), pattern = "*.sas7bdat") |>
+ gsub(".sas7bdat", "", x = _) |>
+ toupper()
+ ls
+}
+
+
+#' Flatten multilevel list
+#'
+#' @param paths character vector of folder paths
+#'
+#' @return flattened list
+flatmultiread <- function(paths) {
+ paths |>
+ purrr::map(sas2list) |>
+ purrr::list_flatten()
+}
+
+# ls <- targets::tar_read(reg_data)
+
+# Vectors are kept for compatibility. Calling functions can be done from within other functions. So much easier!
+
+date_cutter <- function() as.Date("2023-01-01")
+date.cut <- date_cutter() # The earliest date will define the overall date cut
+
+censor_cutter <- function() 8.5
+censor.cut <- censor_cutter() # years of maximum follow up, due to small numbers
+
+vasc.diags <- c("I21", "I61", "I63", "I64", "G45", "K28")
+
+#' Extract deaths from Dødsårsagsregiseret
+#'
+#' @param ls
+#' @param max.date
+#' @param diags.vasc
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(reg_data) |> get_deaths()
+get_deaths <- function(ls, max.date = date.cut, diags.vasc = vasc.diags) {
+
+
+ # vasc.death.tilg <- mapply(ls$DAR_T_DODSAARSAG_2[, "C_DODTILGRUNDL_ACME"],
+ # FUN = function(i) { # mapply inside apply call to handle rowvise matching in in matrix
+ # i_3 <- substr(i, 1, 3) # Substr only the 3 first characters to match by group
+ # i_3 %in% diags.vasc # Rowvise matching
+ # }
+ # )
+
+ vasc.death.tilg <- ls$DAR_T_DODSAARSAG_2[["C_DODTILGRUNDL_ACME"]] |> substr(1, 3) %in% diags.vasc
+
+
+ vasc.death.any <- apply(mapply(ls$DAR_T_DODSAARSAG_2[, c("C_DODTILGRUNDL_ACME", "C_DOD_1A", "C_DOD_1B", "C_DOD_1C", "C_DOD_1D")],
+ FUN = function(i) { # mapply inside apply call to handle rowvise matching in in matrix
+ i_3 <- substr(i, 1, 3) # Substr only the 3 first characters to match by group
+ i_3 %in% diags.vasc # Rowvise matching
+ }
+ ), 1, any) # Simplify to TRUE if any
+ #
+ vasc.death.other <- apply(mapply(ls$DAR_T_DODSAARSAG_2[, c("C_DOD_1A", "C_DOD_1B", "C_DOD_1C", "C_DOD_1D")],
+ FUN = function(i) { # mapply inside apply call to handle rowvise matching in in matrix
+ i_3 <- substr(i, 1, 3) # Substr only the 3 first characters to match by group
+ i_3 %in% diags.vasc # Rowvise matching
+ }
+ ), 1, any) # Simplify to TRUE if any
+
+ diag.either <- xor(vasc.death.other, vasc.death.tilg)
+ diag.both <- vasc.death.other & vasc.death.tilg
+
+ vasc.death.diags <-
+ apply(
+ mapply(
+ ls$DAR_T_DODSAARSAG_2[, c(
+ "C_DODTILGRUNDL_ACME",
+ "C_DOD_1A",
+ "C_DOD_1B",
+ "C_DOD_1C",
+ "C_DOD_1D"
+ )],
+ FUN = function(i) {
+ # mapply inside apply call to handle rowvise matching in in matrix
+ substr(i, 1, 3) # Substr only the 3 first characters to match by group
+ }
+ ),
+ 1,
+ paste,
+ collapse = ","
+ )
+
+ deaths.vasc <-
+ ls$DAR_T_DODSAARSAG_2 |>
+ dplyr::select(K_CPR, D_STATDATO) |>
+ dplyr::filter(vasc.death.tilg)
+
+ df.death.all <- ls$CPR3_T_PERSON |>
+ dplyr::filter(C_STATUS == 90) |> # People migrating are filtered (n ~ 1)
+ dplyr::select(c(
+ "V_PNR",
+ "D_STATUS_HEN_START"
+ )) |>
+ dplyr::left_join(deaths.vasc, by = c("V_PNR" = "K_CPR")) |>
+ dplyr::mutate(vasc_death = !is.na(D_STATDATO)) |>
+ dplyr::transmute(
+ PNR = V_PNR,
+ death_date = D_STATUS_HEN_START,
+ vasc_death = vasc_death
+ )
+
+ df.death.all |> dplyr::filter(death_date < max.date)
+}
+
+
+#' Title
+#'
+#' @param ls
+#' @param max.date
+#' @param diags.vasc
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' ls <- targets::tar_read(reg_list)
+get_events <- function(ls, max.date = date.cut, diags.vasc = vasc.diags) {
+ ident.vars <- toupper(c("_recnum", "_cpr"))
+
+ df.vasc.events.lpr <- ls$LPR_T_DIAG |>
+ dplyr::mutate(dia.f = substr(C_DIAG, 2, 4)) |> # Subsets only 2:4 chars, to get main group
+ dplyr::filter(
+ dia.f %in% diags.vasc
+ # & # Filters to only include pre-defined diagnoses
+ # C_DIAGTYPE=="A"
+ ) |> # Filters to only include if main diagnosis
+ dplyr::select(
+ ends_with(ident.vars),
+ "C_DIAG",
+ "C_DIAGTYPE"
+ ) |>
+ dplyr::left_join(
+ ls$LPR_T_ADM |> dplyr::select(
+ tidyselect::ends_with(ident.vars),
+ "D_INDDTO",
+ "C_INDM",
+ "D_UDDTO",
+ "C_UDM",
+ "C_SGH",
+ "C_AFD",
+ "C_ADIAG"
+ ),
+ by = c("V_RECNUM" = "K_RECNUM")
+ )
+
+ ## LPR-F - LPR 3
+
+ ident.vars.lpr3 <- toupper(c("cpr", "_kontakt", "DW_EK_FORLOEB"))
+
+ df.vasc.events.lpr3 <- ls$LPR_F_DIAGNOSER |>
+ dplyr::mutate(dia.f = substr(DIAGNOSEKODE, 2, 4)) |> # Subsets only 2:4 chars, to get main group
+ dplyr::filter(
+ dia.f %in% diags.vasc
+ # & # Filters to only include pre-defined diagnoses
+ # DIAGNOSETYPE=="A"
+ ) |> # Filters to only include if main diagnosis
+ dplyr::select(
+ ends_with(ident.vars.lpr3),
+ "DIAGNOSEKODE",
+ "DIAGNOSETYPE"
+ ) |>
+ dplyr::left_join(
+ ls$LPR_F_KONTAKTER |> dplyr::select(
+ ends_with(ident.vars.lpr3),
+ "DATO_START",
+ "DATO_SLUT",
+ "PRIORITET"
+ ),
+ by = c("DW_EK_KONTAKT")
+ ) |>
+ dplyr::mutate(PRIORITET = as.character((PRIORITET == "ATA1") + 1)) # If ATA1 then 1, if not (ATA3) then 2, cowboy coding
+
+ df.vasc.events <- dplyr::full_join(df.vasc.events.lpr, df.vasc.events.lpr3, by = c(
+ "V_CPR" = "CPR",
+ "C_DIAG" = "DIAGNOSEKODE",
+ "C_DIAGTYPE" = "DIAGNOSETYPE",
+ "D_INDDTO" = "DATO_START",
+ "D_UDDTO" = "DATO_SLUT",
+ "C_INDM" = "PRIORITET"
+ )) |>
+ dplyr::mutate(date.event = D_INDDTO)
+
+ df.vasc.events |> dplyr::filter(date.event < max.date)
+}
+
+
+# deaths <- targets::tar_read(df_deaths)
+# events <- targets::tar_read(df_events)
+# clinical <- targets::tar_read(pop_df)
+
+
+#' Filter only truly considered events
+#'
+#' @param data
+#'
+#' @return tibble
+define_events <- function(data) {
+ data |> dplyr::filter(
+ C_DIAGTYPE == "A", # Primary diagnosis
+ C_INDM == "1", # Acutely admitted
+ difftime(date.event, rdate, units = "days") > 5 # More than five (5) days after randomisation/primary stroke
+ )
+}
+
+#' The big merger and filter of events
+#'
+#' @param ls list of events, deaths and clinical
+#'
+#' @return tibble
+#'
+#' @examples
+#' ls <- list(events = targets::tar_read(df_events), deaths = targets::tar_read(df_deaths), clinical = targets::tar_read(pop_df))
+#' ls |> all_events()
+all_events <- function(ls) {
+ # ls <- list(events = targets::tar_read(df_events), deaths = targets::tar_read(df_deaths), clinical = targets::tar_read(pop_df))
+ df.events <- dplyr::full_join(
+ purrr::pluck(ls, "events"),
+ purrr::pluck(ls, "deaths") |>
+ dplyr::mutate(
+ # These are just added to ease later filtering
+ C_DIAGTYPE = "A",
+ C_INDM = "1"
+ ), # Ads diagtype=A, C_INDM=1 for easier sorting later
+ by = c(
+ "V_CPR" = "PNR",
+ "date.event" = "death_date",
+ "C_DIAGTYPE",
+ "C_INDM"
+ )
+ ) |>
+ dplyr::full_join(dplyr::select(purrr::pluck(ls, "clinical"), c("PNR", "rdate", "enddate")),
+ by = c("V_CPR" = "PNR")
+ ) |>
+ dplyr::arrange(date.event) |> # Sort by event date
+ dplyr::mutate(event.type = dplyr::if_else(
+ is.na(C_DIAG),
+ dplyr::if_else(vasc_death, "death.vasc", "death.other"),
+ substr(C_DIAG, 1, 4)
+ ))
+
+ df.events |>
+ dplyr::group_split(V_CPR) |> # Splits by CPR
+ purrr::map(define_events) |> # Custom function to specify criteria for events
+ purrr::discard(\(x) nrow(x) == 0) |> # Discard empty elements
+ purrr::map(dplyr::transmute, # Saving only relevant variables
+ CPR = V_CPR,
+ date.event,
+ event.type)
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' ls <- list(events = targets::tar_read(df_events), deaths = targets::tar_read(df_deaths), clinical = targets::tar_read(pop_df))
+#' ls |> merge_events()
+merge_events <- function(data){
+ data|>
+ all_events() |>
+ purrr::modify(\(x) x[1, ]) |> # Select first event
+ purrr::list_rbind()
+}
+
+
+#' Count number of prescriptions of given ATC group for each CPR
+#'
+#' @param atc.code atc group
+#' @param data dataset from LMS
+#'
+#' @return tibble
+count_treat <- function(atc.code, data) {
+ data |>
+ dplyr::filter(grepl(atc.code, ATC)) |>
+ dplyr::count(CPR) |>
+ dplyr::filter(n > 1)
+}
+
+
+#' Get LMS data
+#'
+#' @param ls list of datasets
+#' @param max.date filter date for max inclusion
+#' @param atc.tbl tibble of atc codes
+#'
+#' @return tibble
+get_lms <- function(ls, max.date, atc.tbl) {
+ ls$LMS_EPIKUR |>
+ dplyr::filter(grepl(atc.tbl[1], ATC)) |>
+ dplyr::left_join(ls$LMS_LAEGEMIDDELOPLYSNINGER) |>
+ dplyr::filter(as.Date(ACTDATE) < max.date)
+}
+
+#' Get count of treated patients from LMS data
+#'
+#' @param ls list of datasets
+#' @param max.date filter date for max inclusion
+#' @param atc.tbl tibble of atc codes
+#'
+#' @return tibble
+get_treated <- function(ls,
+ max.date = date.cut,
+ atc.tbl = c(
+ atc.antidep = "N06A",
+ atc.ssri = "N06AB"
+ )) {
+ df <- atc.tbl |>
+ purrr::map(count_treat, get_lms(ls, max.date, atc.tbl)) |>
+ purrr::reduce(dplyr::full_join, by = "CPR")
+ colnames(df) <- c("CPR", paste0("n.", names(atc.tbl)))
+ df
+}
+
+#' BMI calc, drops
+#'
+#' @param w weight in kg
+#' @param h height in cm
+#' @param data data set
+#'
+#' @return tibble
+bmi_calc <- function(data, drop = TRUE) {
+ # After inspection, both h+w are missing if any is missing
+ out <- data |> dplyr::mutate(reg_bmi = suppressWarnings(as.numeric(dplyr::if_else(reg_vaegt == "NA", reg_vaegt_anslaaet, reg_vaegt)) / ((as.numeric(reg_hojde) / 100)^2)))
+
+ if (drop) {
+ out <- out |>
+ dplyr::select(-dplyr::all_of(c("reg_vaegt", "reg_vaegt_anslaaet", "reg_hojde")))
+ }
+ out
+}
+
+is_equal <- function(data, test) {
+ data == test
+}
+
+#' Load clinical population data
+#'
+#' @return tibble
+#' @examples
+#' get_clinical() |> colnames()
+#'
+get_clinical <- function() {
+ sas2list("E:/rawdata/709203/Population")[[2]] |>
+ correct_na() |>
+ dplyr::mutate(
+ reg_smoker = dplyr::case_match(
+ reg_rygning, "1" ~ TRUE,
+ c("2", "3", "4") ~ FALSE,
+ "9" ~ NA
+ ),
+ # Living alone defined as not together with somebody
+ reg_alone = dplyr::case_match(
+ reg_civil, "1" ~ FALSE,
+ c("2", "3") ~ TRUE,
+ "9" ~ NA
+ ),
+ reg_more_alc = dplyr::case_match(
+ reg_alkohol, "1" ~ FALSE,
+ "2" ~ TRUE,
+ "9" ~ NA
+ ),
+ reg_female = sex == "Kvinde",
+ dplyr::across(
+ .cols = c(
+ "reg_hyperten",
+ "reg_diabetes",
+ "reg_atriefli",
+ "reg_perifer_arteriel",
+ "reg_tidl_tci",
+ "reg_ami"
+ ),
+ ~ dplyr::case_match(
+ .x, "1" ~ TRUE,
+ "2" ~ FALSE,
+ "9" ~ NA
+ )
+ ),
+ dplyr::across(
+ .cols = c(
+ "reg_trombolyse",
+ "reg_trombektomi"
+ ),
+ ~ dplyr::case_match(
+ .x, "1" ~ TRUE,
+ c("3","4") ~ FALSE,
+ "9" ~ NA
+ )
+ ),
+ reg_any_perf = reg_trombolyse | reg_trombektomi
+ ) |>
+ bmi_calc()
+}
+
+# get_clinical() |> pragmatic_imputation() |> skimr::skim()
+
+# get_clinical <- function() {
+# sas2list("E:/rawdata/709203/Population")[[2]] |>
+# dplyr::mutate(
+# reg_smoker = reg_rygning == 1,
+# reg_cohabiting = reg_civil == 1,
+# reg_more_alc = reg_alkohol == 2,
+# reg_female = sex == "Kvinde",
+# dplyr::across(.cols = c("reg_hyperten", "reg_diabetes", "reg_atriefli", "reg_perifer_arteriel", "reg_tidl_tci", "reg_ami", "reg_trombolyse", "reg_trombektomi"), ~ .x == 1),
+# reg_any_perf = reg_trombolyse | reg_trombektomi
+# ) |>
+# bmi_calc()
+# }
+
+pragmatic_imputation <- function(data, vec=c("reg_smoker","reg_cohabiting","reg_more_alc","reg_hyperten", "reg_diabetes", "reg_atriefli", "reg_perifer_arteriel", "reg_tidl_tci", "reg_ami", "reg_trombolyse", "reg_trombektomi","reg_any_perf")) {
+ # Assumes, if not TRUE, then FALSE (gets rid of NAs)
+ data |> dplyr::mutate(dplyr::across(.cols = tidyselect::any_of(vec), ~dplyr::if_else(.x,TRUE,FALSE,missing = FALSE)))
+}
+
+#' Load all registry tables to list
+#'
+#' @return list
+get_reg_ls <- function() {
+ flatmultiread(c("E:/rawdata/709203/Eksterne data", "E:/rawdata/709203/Grunddata"))
+}
+
+
+#' Definition of relevant variables from DST tables
+#'
+#' @return
+define_dst_vars <- function() {
+ list(
+ bef = c("PNR", "FAMILIE_ID"),
+ faik = c("FAMILIE_ID", "FAMAEKVIVADISP_13", "FAMSOCIOGRUP_13"),
+ ras = c("PNR", "SOC_STATUS_KODE"),
+ uddf = c("PNR", "HFAUDD")
+ )
+}
+
+#' Simple wrapper of dplyr::select
+#'
+#' @param data
+#' @param vars
+#'
+#' @return
+select_vars <- function(data, vars) {
+ data |> dplyr::select({{ vars }})
+}
+
+#' Subset DST tables to only include relvant variables.
+#'
+#' @param ls List of all registry tables
+#'
+#' @return
+get_dst_tables <- function(ls) {
+ dst_vars <- define_dst_vars()
+ dst_tbl <- toupper(names(dst_vars))
+ ls.all <- purrr::map(seq_along(dst_vars), function(i) {
+ ls.reg <- ls[grepl(paste0("^", dst_tbl[i]), names(ls))] |> purrr::map(select_vars, vars = dst_vars[[i]])
+ names(ls.reg) <- paste0("y", stringr::str_extract(names(ls.reg), "[0-9]{4}"))
+ ls.reg
+ })
+ names(ls.all) <- dst_tbl
+ ls.all
+}
+
+#' Wrapper to generate string matching pattern for stringr::str_detect()
+#'
+#' @param data
+#'
+#' @return
+match_str <- function(data) {
+ paste0("[", paste0(data, collapse = ","), "]")
+}
+
+#' Wrapper to generate string matching pattern for grepl()
+#'
+#' @param data character vector
+#'
+#' @return
+match_str_grepl <- function(data) {
+ paste0("(", paste0(data, collapse = "|"), ")")
+}
+
+# get_dst_tables(ls)
+
+#' Generate sequence of previous N length
+#'
+#' @param data numeric vector of length 1
+#'
+#' @return
+#'
+#' @examples
+#' last5y(10)
+#' last5y(c(10, 6, 3))
+lastNy <- function(data, n = 5) {
+ paste0("y", seq((data - n), data) - 1)
+}
+
+#' Filter PNR (cpr) across list elements
+#'
+#' @param data list of tibbles to pass through
+#' @param index index number (PNR/CPR)
+#'
+#' @return tibble
+filterCPRacross <- function(data, index) {
+ data |>
+ purrr::map(function(i) {
+ i[i$PNR == index, ]
+ }) |>
+ purrr::list_rbind()
+}
+
+#' Summarise data from last 5 years prior to inclusion
+#'
+#' @param data list with
+#' @param v.median variables to get median
+#' @param v.latest variables to get latest
+#' @param v.mean variables to get mean
+#'
+#' @return tibble
+previousNyears <- function(data, data.clin, n.years = 5, v.median = NULL, v.latest = c("FAMSOCIOGRUP_13", "SOC_STATUS_KODE"), v.mean = c("FAMAEKVIVADISP_13")) {
+ df.cpryear <- data.clin |> dplyr::transmute(
+ CPR = PNR,
+ year = as.numeric(format(as.Date(rdate), "%Y"))
+ )
+
+ seqs <- purrr::map(df.cpryear$year, lastNy, n = n.years)
+
+ seq_along(seqs) |>
+ purrr::map(function(i) {
+ df <- data[c(seqs[[i]])] |>
+ filterCPRacross(index = df.cpryear$CPR[i]) |>
+ dplyr::group_by(PNR) |>
+ dplyr::summarise(
+ dplyr::across(tidyselect::any_of(v.latest), \(x) tail(x, n = 1), .names = "{.col}.latest"),
+ dplyr::across(tidyselect::any_of(v.mean), \(x) mean(x, na.rm = TRUE), .names = "{.col}.{n.years}.mean"),
+ dplyr::across(tidyselect::any_of(v.median), \(x) median(x, na.rm = TRUE), .names = "{.col}.{n.years}.median")
+ )
+ }) |>
+ purrr::list_rbind()
+}
+
+
+#' Extract relevant and summarised data from BAF and FAIK
+#'
+#' @param data list of dst data tables
+#'
+#' @return tibble
+#'
+#' @examples
+#' get_reg_ls() |>
+#' get_dst_tables() |>
+#' get_beffaikras()
+get_beffaikras <- function(data, clin.data = get_clinical()) {
+ data <- data[stringr::str_detect(match_str(c("BEF", "FAIK", "RAS")), names(data))] |> purrr::list_flatten()
+
+ years <- stringr::str_extract(names(data), "y[0-9]{4}")
+
+ years[duplicated(years)] |>
+ purrr::map(grep, years) |>
+ purrr::map(function(i) {
+ data[c(i)] |> purrr::reduce(dplyr::full_join)
+ }) |>
+ purrr::set_names(years[duplicated(years)]) |>
+ previousNyears(data.clin = clin.data)
+
+ ## BEF
+ ## # Befolkningsoversigt. Data skal bruges for at kunne udtrække husstandsindkomst.
+ ## FAIK
+ ## # Familieindkomst. Familie id skal flættes med ID fra BEF for hvert år for at tage hensyn til evt skifte i status.
+ ## FAMAEKVIVADISP_13 er relevante variabel for ækvivaleret indkomst
+ ## Der findes også familiesocioøkonomisk status. Gør som Sine. Be done with it!
+}
+
+#' Title
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- read_edu_level()
+#' data |> dplyr::count(ISCED)
+read_edu_level <- function() {
+ haven::read_dta("E:/Formater/SAS formater i Danmarks Statistik/STATA_datasaet/Disced/c_audd_level_l1l4_k.dta") |>
+ dplyr::transmute(
+ HFAUDD = start,
+ ISCED = AUDD_LEVEL_L1L4_K
+ )
+}
+
+haven::read_dta(
+ "E:/Formater/SAS formater i Danmarks Statistik/STATA_datasaet/Disced/c_audd_level_l1l3_k.dta") |>
+ dplyr::count(AUDD_LEVEL_L1L3_K)
+
+# ls <- get_reg_ls() |> get_dst_tables()
+
+get_uddf <- function(ls) {
+ ls |>
+ purrr::pluck("UDDF") |>
+ purrr::pluck(1) |>
+ dplyr::mutate(HFAUDD = as.character(HFAUDD)) |>
+ dplyr::left_join(read_edu_level()) |>
+ dplyr::group_by(PNR) |>
+ dplyr::summarise(ISCED = max(ISCED), .groups = "keep") |>
+ dplyr::mutate(
+ ISCED = as.numeric(ISCED),
+ ISCED_lvl = dplyr::case_match(ISCED, 0:2 ~ "low",
+ 3:4 ~ "medium",
+ 5:9 ~ "high",
+ .default = NA
+ ),
+ ISCED_bin = dplyr::case_match(ISCED, 0:3 ~ "low",
+ 4:9 ~ "high",
+ .default = NA
+ )
+ )
+}
+
+
+#' Collects all relevant variables from DST tables
+#'
+#' @param ls list of all registry tables
+#' @param df.clin clinical data set
+#'
+#' @return tibble
+#' @examples
+#' get_reg_ls() |> get_dst(df.clin = get_clinical())
+get_dst <- function(ls, df.clin) {
+ ls_dst <- get_dst_tables(ls)
+ ls_dst |>
+ ## BEFxFAIKxRAS
+ get_beffaikras(clin.data = df.clin) |>
+ dplyr::full_join(
+ ## UDDF
+ get_uddf(ls_dst)
+ )
+}
+
+#' Eases pipe renaming of columns
+#'
+#' @param data tibble, list or other object, for which names() makes sense. see ?setNames
+#' @param prefix prefix to add
+#' @param exclude names not to modify
+#' @param new.names character vector of all new names
+#'
+#' @return object of same class as data
+#'
+#' @examples
+#' set_colnames(data = mtcars, prefix = "WOW", exclude = "mpg")
+set_colnames <- function(data, new.names = NULL, prefix = NULL, exclude = c("PNR", "CPR"), prefix.sep = "_") {
+ if (is.null(new.names)) {
+ nms <- names(data)
+ } else {
+ nms <- new.names
+ }
+
+ if (is.null(prefix)) {
+ nms.mod <- nms
+ } else {
+ nms.mod <- paste(prefix, nms, sep = prefix.sep)
+ }
+
+ setNames(
+ object = data,
+ nm = dplyr::if_else(stringr::str_detect(match_str(exclude), nms),
+ nms,
+ nms.mod
+ )
+ )
+}
+
+
+#' Store of variable names for data sub-setting
+#'
+#' @return list
+#' @examples
+#' define_variables()
+define_variables <- function() {
+ list(
+ clin = c(
+ "age",
+ "reg_female",
+ "nihss_0",
+ "reg_trombolyse",
+ "reg_trombektomi",
+ # "rtreat",
+ "rtreat_placebo"),
+ lifestyle=c(
+ "pase_0",
+ "pase_4",
+ "reg_alone",
+ "reg_bmi",
+ # "reg_hojde",
+ # "reg_vaegt_alt",
+ "reg_smoker",
+ "reg_more_alc",
+ "reg_hyperten",
+ "reg_diabetes",
+ "reg_tidl_tci",
+ "reg_atriefli",
+ "reg_ami",
+ "reg_perifer_arteriel"),
+ lifestyle.events=c(
+ "pase_0",
+ "pase_4",
+ "reg_alone",
+ "reg_bmi",
+ # "reg_hojde",
+ # "reg_vaegt_alt",
+ "reg_smoker",
+ "reg_more_alc",
+ "reg_hyperten",
+ "reg_diabetes",
+ # "reg_tidl_tci",
+ "reg_atriefli",
+ # "reg_perifer_arteriel",
+ "reg_ami"),
+ ses=c(
+ # "soc_status",
+ # "soc_status_work",
+ "soc_status_nowork",
+ # "fam_indk",
+ "fam_indk_hl",
+ # "fam_indk_high",
+ # "fam_indk_low",
+ # "edu_level",
+ # "edu_high",
+ # "edu_low",
+ "edu_level_hl"
+ ),
+ assess.events = c(
+ "who_4",
+ "mdi_4",
+ "mfi_gen_4",
+ "mrs_4_above1",
+ "time",
+ "status",
+ "event.include"
+ ),
+ assess.pred = c(
+ "who_0",
+ "mrs_0_above0"
+ ),
+ extra = c(
+ "soc_status",
+ "pase_0",
+ "pase_4" ,
+ "event"
+ ),
+ cpr = "PNR"
+ )
+}
+
+#' Get var names in vector from group names. Possibility to keep all vars for as log as possible. Can be supplied to `gtsummary` functions
+#'
+#' @param groups vector of group names. See names(define_variables()) for options
+#'
+#' @return
+#' @export
+#'
+#' @examples
+get_var_vec <- function(v.groups){
+ define_variables()[{{ v.groups }}] |> purrr::list_c()
+}
+
+#' SUbsets dataset based on variable group names as defined
+#'
+#' @param vector character vector of category names
+#'
+#' @return character vector
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> get_vars(c("universal", "events"))
+get_vars <- function(data, vars.groups) {
+ data |> dplyr::select(tidyselect::all_of(get_var_vec(vars.groups)))
+}
+
+
+
+#' Collect all relevant data for the events analysis data set
+#'
+#' @param ls ls of tibbles
+#'
+#' @return tibble
+#'
+#' @examples
+#' ls <- targets::tar_read(list_filtered)
+#'
+collectall <- function(ls) {
+ purrr::pluck(ls, "clinical") |>
+ dplyr::left_join(purrr::pluck(ls, "all_events") |> set_colnames(prefix = "event"), by = c("PNR" = "CPR")) |>
+ dplyr::left_join(purrr::pluck(ls, "dst") |> set_colnames(prefix = "dst"), by = "PNR")
+}
+
+
+## Formatting for analysis
+
+#' Function to cut and group PASE data
+#'
+#' @param data data set including pase_0 and _4
+#'
+#' @return tibble
+pase_cutter <- function(data, pase.rev = TRUE, drop.pase = FALSE, drop.nas=FALSE) {
+ data.classes <- class(data)
+ if ("mids" %in% data.classes) {
+ data <- data |> mice::complete(action = "long", include = TRUE)
+ }
+
+ data <- data |>
+ dplyr::mutate(dplyr::across(.cols = c("pase_0", "pase_4"), \(i) {
+ cut(x = i, breaks = quantile(pase_0, na.rm = TRUE), labels = 1:4, include.lowest = TRUE)
+ }, .names = "{.col}_quartile")) |>
+ dplyr::mutate(pase_change = factor(dplyr::case_when(
+ pase_0_quartile == 1 & pase_4_quartile == 1 ~ "Persistent low",
+ pase_0_quartile %in% 2:4 &
+ pase_4_quartile %in% 2:4 ~ "Persistent high",
+ pase_0_quartile == 1 &
+ pase_4_quartile %in% 2:4 ~ "Increase",
+ pase_0_quartile %in% 2:4 &
+ pase_4_quartile == 1 ~ "Decrease"
+ ), ordered = FALSE),
+ pase_change=factor(pase_change,levels=c("Persistent low", "Increase", "Decrease", "Persistent high")))
+
+
+ if (drop.pase) {
+ data <- data |> dplyr::select(-tidyselect::all_of(c("pase_0_quartile", "pase_4_quartile", "pase_0", "pase_4")))
+ }
+
+
+ if (pase.rev) {
+ data <- data |> dplyr::mutate(
+ pase_change = factor(pase_change, levels = c("Persistent high", "Decrease", "Increase", "Persistent low"))
+ )
+ }
+
+ if (drop.nas) {
+ data <- data |>
+ dplyr::filter(!is.na(pase_change))
+ }
+
+
+ if ("mids" %in% data.classes) {
+ data |> mice::as.mids()
+ } else {
+ data
+ }
+}
+
+# as.Date(data$event_date.event)
+define_status_time <- function(data) {
+ data |> dplyr::mutate(dplyr::across(c("rdate", "enddate", "event_date.event"), ~ as.Date(.x)),
+ time = difftime(dplyr::if_else(is.na(event_date.event), date_cutter(), event_date.event), enddate) |> lubridate::time_length("years"),
+ status = as.integer(!is.na(event_event.type)),
+ time = dplyr::if_else(time > censor_cutter(), censor_cutter(), time),
+ status = dplyr::if_else(time > censor_cutter(), FALSE, status),
+ # status= dplyr::if_else(status,1,0),
+ event.include = time > 0
+ )
+}
+
+# as.integer(c(TRUE,FALSE))
+
+#' Grouping soc status
+#'
+#' @param data tibble
+#'
+#' @return tibble
+group_soc_status <- function(data) {
+ data |>
+ dplyr::mutate(
+ soc_status = factor(dplyr::case_when(
+ soc_status < 200 ~ "work",
+ soc_status == 200 ~ "off",
+ # only ~4 in the data set off work
+ soc_status >= 200 ~ "outside"
+ )),
+ soc_status_work = soc_status == "work",
+ soc_status_nowork = !soc_status_work
+ )
+}
+
+#' Correction of character NA
+#'
+#' @param data tibble
+#' @param char.missing character vector of entries to consider as NA
+#'
+#' @return tibble
+correct_na <- function(data, char.missing = "NA") {
+ data |> dplyr::mutate(dplyr::across(dplyr::where(is.character), ~ dplyr::na_if(.x, char.missing)))
+}
+
+#' Formatting the complete data set
+#'
+#' @param data the merged raw data set
+#'
+#' @return tibble
+#' @examples
+#' ds <- targets::tar_read(df_all_data) |>
+#' data_formatting() |>
+#' subset_df("mdi")
+#' ds |> skimr::skim()
+#' ds |> View()
+data_formatting <- function(data) {
+ to_logical <- grep(match_str_grepl(c("missings", "incompletes")), names(data))
+
+ suppressWarnings(
+ data |>
+ correct_na() |>
+ dplyr::mutate(dplyr::across(all_of(to_logical), ~ .x == "TRUE")) |>
+ dplyr::mutate(
+ # This uses the work-corrected score
+ # pase_0 = dplyr::if_else(pase_score_missings_w_0 | is.na(talos_pase10_0), NA, pase_score_sum_w_0),
+ # pase_4 = dplyr::if_else(pase_score_missings_w_4 | is.na(talos_pase10_4), NA, pase_score_sum_w_4),
+ # Below is the plain PASE scor used according to the manual used with TALOS
+ pase_0 = dplyr::if_else(pase_score_missings_0, NA,pase_score_sum_0),
+ pase_4 = dplyr::if_else(pase_score_missings_4, NA,pase_score_sum_4),
+ who_0 = as.numeric(talos_who07_0),
+ who_4 = as.numeric(talos_who07_4),
+ mrs_0 = factor(substr(talos_mrs01_0, 1, 1), ordered = FALSE),
+ mrs_0_above0 = (as.numeric(mrs_0) - 1) > 0,
+ mrs_4 = factor(substr(talos_mrs01_4, 1, 1), ordered = FALSE),
+ mrs_4_above1 = (as.numeric(mrs_4) - 1) > 1,
+ mdi_4 = as.numeric(talos_mdi12_4),
+ mfi_gen_4 = as.numeric(talos_mfi_gen_4),
+ nihss_0 = as.numeric(talos_nihss16_0),
+ soc_status = dst_SOC_STATUS_KODE.latest,
+ fam_indk = cut(dst_FAMAEKVIVADISP_13.5.mean,
+ breaks = quantile(dst_FAMAEKVIVADISP_13.5.mean, probs = seq(0, 1, 1 / 3), na.rm = TRUE),
+ ordered_results = FALSE,
+ labels = c("low", "medium", "high"),
+ include.lowest = TRUE
+ ),
+ fam_indk_bin = cut(dst_FAMAEKVIVADISP_13.5.mean,
+ breaks = quantile(dst_FAMAEKVIVADISP_13.5.mean, probs = seq(0, 1, 1 / 2), na.rm = TRUE),
+ ordered_results = FALSE,
+ labels = c("low", "high"),
+ include.lowest = TRUE
+ ),
+ fam_indk_hl=forcats::fct_rev(fam_indk),
+ fam_indk_high = dplyr::if_else(fam_indk_bin=="high",TRUE,FALSE),
+ fam_indk_low = dplyr::if_else(fam_indk_bin=="low",TRUE,FALSE),
+ edu_level = factor(dst_ISCED_lvl, ordered = FALSE, levels = c("low", "medium", "high")),
+ edu_high = dplyr::if_else(dst_ISCED_bin=="high",TRUE,FALSE),
+ edu_low = dplyr::if_else(dst_ISCED_lvl=="low",TRUE,FALSE),
+ edu_level_hl=forcats::fct_rev(edu_level),
+ rtreat_placebo=rtreat=="Placebo",
+ event = factor(event_event.type)
+ ) |>
+ group_soc_status() |>
+ define_status_time()
+ )
+}
+
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |>
+#' events_ready() |>
+#' View()
+events_ready <- function(data,v.groups=c("clin","lifestyle.events","ses", "assess.events")) {
+ data |>
+ get_vars(vars.groups = v.groups) |>
+ dplyr::filter(event.include) |>
+ # dplyr::filter(!is.na(pase_0),!is.na(pase_4))|>
+ dplyr::select(-tidyselect::all_of("event.include"))# |>
+ # labelling_data()
+}
+
+#' Title
+#'
+#' @param data
+#' @param v.groups
+#'
+#' @return
+#' @export
+#'
+#' @examples
+events_ready_small <- function(data,v.groups=c("clin","lifestyle.events","ses", "assess.events")) {
+ data |>
+ get_vars(vars.groups = v.groups) |>
+ dplyr::filter(event.include) |>
+ dplyr::filter(!is.na(pase_0),!is.na(pase_4))|>
+ dplyr::select(-tidyselect::all_of("event.include"))# |>
+ # labelling_data()
+}
+
+#' Title
+#'
+#' @param date
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted)
+#'
+#' data |>
+#' prediction_ready() |>
+#' View()
+prediction_ready <- function(data) {
+ data |>
+ get_vars(c("clin","lifestyle","ses", "assess.pred"))|>
+ dplyr::filter(!is.na(pase_0),!is.na(pase_4))#|>
+ # labelling_data()
+}
+
+## Data inspection and exploration
+##
+##
+#' Title
+#'
+#' @param data
+#' @param subdf
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data) |>
+#' subset_df() |>
+#' View()
+subset_df <- function(data, subdf = "pase") {
+ data[grepl(paste0("^(", paste("PNR", subdf, paste0("talos_", subdf), sep = "|"), ")"), names(data))]
+}
+
+#' Imputation as a function, includes "pragmatic imputation"
+#'
+#' @param data
+#' @param outcome.vars
+#' @param ignore
+#' @param pragmatic.reg
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted) |> events_ready()
+#' data |> labelling_data() |> fun_impute()
+fun_impute <- function(data, outcome.vars = c("status", "time"), ignore = NULL,pragmatic.reg=TRUE,pase.mod=FALSE) {
+ # data |> mice::md.pattern()
+ if (pragmatic.reg){
+ data <- data |> pragmatic_imputation()
+ }
+
+ ## Excluding entries with missing outcome measures
+ data <- data |>
+ dplyr::filter(!dplyr::if_any(tidyselect::all_of(c(outcome.vars)), ~ is.na(.x)))
+
+ init <- data |>
+ mice::mice(maxit = 0)
+
+ meth <- init$method
+ meth[ignore] <- ""
+
+ pred <- init$predictorMatrix
+ pred[, c(outcome.vars)] <- 0
+
+ # data_out <- data |> mice::futuremice(
+ # pred = pred,
+ # method = meth,
+ # print = FALSE,
+ # parallelseed = 8123,
+ # use.logical = FALSE,
+ # maxit = 20,
+ # m = 10
+ # )
+
+ data_out <- data |> mice::mice(
+ pred = pred,
+ method = meth,
+ print = FALSE,
+ seed = 8123,
+ maxit = 20,
+ m = 10
+ )
+
+ if (pase.mod){
+ data_out <- data_out |> pase_cutter_mids()
+ }
+
+ data_out
+
+ # lattice::densityplot(imp_data)
+ # Regarding EVENTS
+ #
+ # On inspection/eye-balling densityplots looks reasonable with the current settings
+ #
+}
+
+#' Function to cut PASE in mids object
+#'
+#' @param data mids object
+#'
+#' @return mids object
+#' @export
+#'
+pase_cutter_mids <- function(data){
+data |>
+ mice::complete(action = "long", include = TRUE) |>
+ pase_cutter(drop.pase = TRUE, drop.nas = TRUE)|>
+ mice::as.mids()
+ }
+
+
+#' Completes events data set, option to impute
+#'
+#' @param data
+#' @param impute
+#'
+#' @return mids or tibble
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> events_dataset() |>
+#' targets::tar_read(df_all_data_formatted) |>
+events_dataset <- function(data, impute = TRUE, uv=FALSE) {
+ # data <- data |> events_ready()
+ if (impute) {
+ data |>
+ fun_impute(ignore = c("pase_0","pase_4"),pase.mod = TRUE)
+ } else if (uv){
+ data |>
+ pase_cutter(drop.pase = TRUE,drop.nas = TRUE)
+ } else {
+ data |>
+ dplyr::select(-tidyselect::all_of("reg_bmi")) |>
+ pase_cutter(drop.pase = TRUE,drop.nas = TRUE)
+ }
+}
+
+#' Title
+#'
+#' @param data
+#' @param all.vars
+#' @param outcome.var
+#' @param use.strata
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> events_ready() |> subset_df("pase")
+#' data <- targets::tar_read(df_event_data) |> events_dataset(impute = FALSE)
+
+cox_regression <- function(data, all.vars = TRUE,outcome.var="pase_change",use.strata=TRUE) {
+ if ("mids" %in% class(data)) {
+ nms <- names(data$data)
+ } else {
+ nms <- names(data)
+ data <- data |>
+ labelling_data()
+ # BMI meassure is excluded from non-imputed dataset
+ # data <- data |> dplyr::select(-tidyselect::all_of(c("reg_bmi")))
+ }
+
+ vars <- nms[!nms %in% c("time", "status", outcome.var)]
+
+ form.prefix <- "survival::Surv(time, status) ~"
+
+ if (use.strata) {
+ reg.form <- glue::glue("{form.prefix} strata({outcome.var})")
+ } else {
+ reg.form <- glue::glue("{form.prefix} {outcome.var}")
+ }
+
+ if (all.vars) reg.form <- paste0(reg.form, " + ", paste(vars, collapse = " + "))
+
+ require(survival)
+ out <- with(data, survival::coxph(
+ as.formula(reg.form)
+ ))
+
+ out$call$formula <- as.formula(reg.form)
+
+ out
+}
+
+#' Creates UV cox models for all variables in data set (but time and status)
+#'
+#' @param data
+#' @param include
+#'
+#' @return
+#' @export
+#'
+#' @examples
+splitdf4uvcox <- function(data,include=c("pase_change","time","status")){
+ names(data)[!names(data)%in%include] |>
+ purrr::map(\(.x){
+ data |> dplyr::select(tidyselect::all_of(c(.x,include))) |>
+ cox_regression(outcome.var = .x,use.strata=FALSE,all.vars = FALSE)
+
+ })
+}
+
+#' Creates and prints UV Cox analyses
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_event_data) |> uv_cox_table()
+uv_cox_table <- function(data){
+ data |>
+ events_dataset(impute = FALSE,uv = TRUE) |>
+ dplyr::select(pase_change,dplyr::everything()) |>
+ splitdf4uvcox(include=c("time","status")) |>
+ purrr::map(\(.x){
+ .x |> tbl_regression_standard()
+ }) |>
+ gtsummary::tbl_stack()
+ }
+
+tbl_merged_named <- function(data){
+ data |> gtsummary::tbl_merge(tab_spanner = names(data))
+}
+
+tbl_regression_standard <- function(data){
+ data |> gtsummary::tbl_regression(exponentiate = TRUE,
+ add_estimate_to_reference_rows = TRUE,
+ show_single_row = where(is.logical),
+ statistics=list(gtsummary::all_continuous()~"[{conf.low};{conf.high}]",
+ gtsummary::all_categorical()~"[{conf.low}%;{conf.high}%]")
+ ) |>
+ fix_labels()
+}
+
+#' Wrapper to print summary table with extended info
+#'
+#' @param data formatted and subset data set
+#' @param by.var stratify by
+#'
+#' @return
+#' @examples
+#' targets::tar_read(df_pred_data)|>print_table_summary(by="reg_female")
+print_table_summary <- function(data, by.var = "pase_change") {
+ data |>
+ labelling_data() |>
+ # pase_cutter(drop.pase = TRUE) |>
+ gtsummary::tbl_summary(
+ missing = "no",
+ by = tidyselect::all_of(by.var),
+ value = list(where(is.logical) ~ TRUE)
+ ) |>
+ gtsummary::add_overall() |>
+ gtsummary::add_n()
+}
+
+print_table_summary_explorer <- function(data, by.var = "pase_change") {
+ data |>
+ labelling_data() |>
+ # pase_cutter(drop.pase = TRUE) |>
+ gtsummary::tbl_summary(
+ missing = "no",
+ by = tidyselect::all_of(by.var),
+ value = list(where(is.logical) ~ TRUE),
+ type = list(gtsummary::all_continuous() ~ "continuous2"),
+ statistic = list(gtsummary::all_continuous() ~ c(
+ # "{N_nonmiss} ({p_nonmiss}%)",
+ "{median} ({p25}, {p75})",
+ # "{min}, {max}",
+ "{mean} ({sd})"#,
+ # "{N_miss} ({p_miss}%)"
+ )#,
+ # gtsummary::all_categorical() ~ c(
+ # "{N_obs} ({p_nonmiss}%)"#,
+ # # "{N_miss} ({p_miss})"
+ # )
+ )
+ ) |>
+ gtsummary::add_overall() |>
+ gtsummary::add_n() #|>
+ # gtsummary::add_p()
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted)
+#' targets::tar_read(df_all_data_formatted) |> events_tblone()
+events_tblone <- function(data) {
+ data |>
+ # events_ready() |>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::select(-tidyselect::all_of(c("status", "time"))) |>
+ dplyr::filter(!is.na(pase_change)) |>
+ print_table_summary()
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> View()
+#' targets::tar_read(df_pred_data)|>
+#' dplyr::transmute(stRoke::quantile_cut(pase_0,4,group.names = 1:4),soc_status_work,fam_indk,edu_level) |>
+#' summary_tblone()
+summary_tblone <- function(data,by=names(data)[1]) {
+ # data <- targets::tar_read(df_pred_data)
+ data |>
+ labelling_data() |>
+ # prediction_ready() |>
+ # dplyr::select(-reg_bmi) |>
+ # pase_cutter(drop.pase = TRUE) |>
+ # dplyr::filter(!is.na(pase_change)) |>
+ # dplyr::mutate(pase_change=forcats::fct_rev(pase_change)) |>
+ print_table_summary(by.var = by)
+}
+
+#
+#' Summaries of DST data for PASE quartiles at 0 and 4
+#'
+#' @param data
+#' @param vars
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_pred_data) |> sum_pase_tables()
+sum_pase_tables <- function(data,vars=c("pase_0","pase_4")){
+ vars |> lapply(function(.x){
+ dplyr::tibble(stRoke::quantile_cut(data[[.x]],y=data[["pase_0"]],4,group.names = 1:4),
+ dplyr::select(data,soc_status_nowork,fam_indk_hl,edu_level_hl)) |>
+ summary_tblone()
+ })
+}
+
+
+#' Creating a truthful stratified table for predictions
+#'
+#' @param data data frame
+#'
+#' @return list
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_pred_data) |> true_pred_sum_plot()
+true_pred_sum_plot <- function(data){
+ true_sum <- data |>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::mutate(pase_change=forcats::fct_rev(pase_change))
+
+ list(true_sum,true_sum |> (function(.x){
+ split(.x,.x$pase_change %in% c("Persistent low","Increase"))
+ })() |> purrr::map(function(.y){.y |> dplyr::mutate(pase_change=factor(pase_change))})) |>
+ purrr::list_flatten() |> purrr::map(summary_tblone,by="pase_change") |>
+ gtsummary::tbl_merge()
+}
+
+#' Get quick summary of missing vs non-missing for each given variable
+#'
+#' @param data data set
+#' @param var variable to summarise over
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_pred_data) |> dplyr::select(soc_status_work,fam_indk,edu_level) |> who_is_missing()
+#' targets::tar_read(df_pred_data) |> who_is_missing(var="reg_bmi")
+who_is_missing <- function(data, var = "edu_level") {
+ data |>
+ dplyr::mutate(log = factor(c("non-missing","missing")[is.na(data[[var]])+1])) |>
+ dplyr::select(log, tidyselect::everything(),-tidyselect::all_of(var)) |>
+ summary_tblone() #|> gtsummary::bold_p()
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted)
+#' targets::tar_read(df_all_data_formatted) |> View()
+#' targets::tar_read(df_pred_data) |> preds_tblone()
+preds_tblone <- function(data) {
+ data |>
+ labelling_data() |>
+ # prediction_ready() |>
+ # dplyr::select(-reg_bmi) |>
+ pase_cutter(drop.pase = TRUE) |>
+ dplyr::filter(!is.na(pase_change)) |>
+ dplyr::mutate(pase_change=forcats::fct_rev(pase_change)) |>
+ print_table_summary()
+}
+
+#' Title
+#'
+#' @param data
+#' @param b.cols
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' gt <- targets::tar_read(ls_pred_summary)[[1]]
+#' gt |> add_var_groups_gt()
+#'
+#' # For this to work, the function would need to handle labels and levels
+#' gt <- targets::tar_read(tbl_pred_summary)|> gtsummary::as_gt()
+#' gt |> add_var_groups_gt()
+add_var_groups_gt <- function(gt){
+ # gt <- sex_ls |> purrr::pluck(2) |> gtsummary::as_gt()
+ # gt <- fix_labels(gt)
+ cls <- class(gt)
+
+ b.cols <- names(gt$`_data`)
+
+ if (b.cols[[1]]!="variable"){
+ # Flag to indicate if format is native gt or not. Simple assumption
+ # class(gt) gt is not enough
+ labels <- gt$`_data`[[1]]
+ group.var <- names(gt$`_data`[[1]])
+ } else {
+ labels <- gt$`_data`[["label"]][gt$`_data`[["row_type"]]=="label"]
+ group.var <- gt$`_data`[["variable"]]
+ }
+
+
+
+ groups <- matrix(ncol=length(labels)) |>
+ data.frame() |>
+ setNames(ifelse(labels=="","unknown_var",labels)) |>
+ tibble::as_tibble() |> groups_in_ds(labels = TRUE)
+
+ group.labels <- names(groups) |> subset_named_labels(labels.raw = group_labels())
+
+ labels.all <- group.labels |> purrr::imap(function(.x,.y){
+ c(.x,groups[[.y]][["label"]])
+ }) |> purrr::list_c()
+
+ for (i in rev(seq_along(group.labels))){
+ gt <- gt |> gt::tab_row_group(label=gt::md(glue::glue("*{group.labels[[i]]}*")),
+ rows=which(group.var %in% groups[[names(group.labels)[[i]]]][["var"]]))
+
+ }
+
+ class(gt) <- cls
+ gt
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(tbl_preds_lin_imp_reg)
+#' data |> fix_labels()
+fix_labels <- function(data){
+ cls <- class(data)
+ data[[1]][["variable"]][data[[1]][["row_type"]]=="label"] |>
+ subset_named_labels(var_labels()) |>
+ unname() -> data[[1]][["label"]][data[[1]][["row_type"]]=="label"]
+ class(data) <- cls
+ data
+}
+
+
+#' Title
+#'
+#' @param data
+#' @param b.cols
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' tbl <- targets::tar_read(ls_pred_summary)[[1]]
+add_var_groups_pre_calc <- function(data,b.cols){
+
+ groups <- data |> groups_in_ds()
+
+ group.labels <- names(groups) |> subset_named_labels(labels.raw = group_labels())
+
+ t0 <- data.frame(matrix(ncol=length(b.cols))) |>
+ setNames(b.cols) |>
+ tibble::tibble()
+ list(ext = group.labels |> purrr::imap(function(.x,.y){
+ t0 |> dplyr::mutate(
+ variable=.y,
+ val_label=.x,
+ row_type="group",
+ label=.x
+ )
+ }) |> dplyr::bind_rows(),
+ lvls = group.labels |> purrr::imap(function(.x,.y){
+ c(.y,groups[[.y]][["var"]])
+ }) |> purrr::list_c()
+ )
+}
+
+#' Adds variable grouping and formatting to gtsummary tables
+#'
+#' @param tbl
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#'
+#' tbl <- targets::tar_read(tbl_pred_summary)
+#' targets::tar_read(tbl_pred_summary) |> add_var_groups()
+#'
+add_var_groups <- function(tbl,
+ pre_ls=add_var_groups_pre_calc(tbl$inputs$data,
+ names(tbl$table_body))){
+
+
+ tbl |> gtsummary::modify_table_body(
+ ~.x |> dplyr::bind_rows(pre_ls[["ext"]]) |>
+ dplyr::arrange(factor(variable,levels=pre_ls[["lvls"]]))
+ ) |>
+ gtsummary::modify_table_styling(columns=label,
+ rows= row_type%in%"level",text_format = "indent2") |>
+ gtsummary::modify_table_styling(columns=label,rows= row_type%in%"label",text_format = "indent")|>
+ gtsummary::modify_table_styling(columns=label,rows= row_type%in%"group",text_format = c("italic"))
+}
+
+#' Functionalised character vector of all labels
+#'
+#' @return
+#' @export
+#'
+#' @examples
+var_labels <- function(){
+ c(
+ age = "Age",
+ reg_female = "Female sex",
+ reg_bmi = "Body mass index",
+ reg_smoker = "Current smoker",
+ reg_alone = "Living alone",
+ reg_more_alc = "High alcohol consumption",
+ reg_hyperten = "Hypertension",
+ reg_diabetes = "Diabetes",
+ reg_atriefli = "Atrial fibrillation",
+ reg_perifer_arteriel = "Peripheral arterial disease",
+ reg_tidl_tci = "Previous TIA",
+ reg_ami = "Previous MI",
+ reg_trombolyse = "Treated with IVT",
+ reg_trombektomi = "Treated with EVT",
+ # reg_any_perf,
+ # rtreat = "Study group allocation",
+ rtreat_placebo = "Placebo trial treatment",
+ pase_0 = "Pre-stroke PASE score",
+ pase_4 = "6 months post-stroke PASE score",
+ # pase_change,
+ nihss_0 = "Admission NIHSS",
+ # soc_status,
+ soc_status_work = "Employed",
+ soc_status_nowork = "Not employed",
+ fam_indk = "Family income group",
+ fam_indk_hl = "Lower family income",
+ fam_indk_high = "Higher family income",
+ fam_indk_low = "Lower family income",
+ edu_level = "Educational level group",
+ edu_level_hl = "Lower educational level",
+ edu_high = "Higher educational level",
+ edu_low = "Low educational level",
+ who_4 = "WHO-5 score 6 months post-stroke",
+ mdi_4 = "MDI score 6 months post-stroke",
+ mrs_4_above1 = "mRS > 1 at 6 months post-stroke",
+ mfi_gen_4 = "General fatigue (MFI domain) 6 months post-stroke",
+ time = "Time",
+ status = "Status",
+ event.include = "Include event",
+ who_0 = "Pre-stroke WHO-5 score",
+ mrs_0_above0 = "Pre-stroke mRS > 0",
+ pase_change = "PA change group"
+ )
+}
+
+
+group_labels <- function(data){
+ c("clin" = "Clinical data",
+ "lifestyle" = "Lifestyle and chronic diseases",
+ "ses" = "Socio-economic factors",
+ "assess.events" = "Assessments",
+ "assess.pred" = "Assessments",
+ "extra" = "extras")
+}
+
+rev_naming <- function(x){
+ setNames(names(x),x)
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_pred_data)
+groups_in_ds <- function(data, labels=FALSE){
+ groups <- define_variables() |> purrr::imap(function(.x,.y){
+ tibble::tibble(group=.y,var=.x)
+ }) |>
+ dplyr::bind_rows()
+
+ if (labels){
+ matching <- subset_named_labels(names(data),
+ rev_naming(var_labels()))
+ }else {
+ matching <- names(data)
+ }
+ groups[match(matching,groups[["var"]]),] |>
+ (\(.x){
+ .x |> dplyr::mutate(group=factor(group,levels=unique(.x[["group"]])))
+ })() |>
+ cbind(
+ tibble::tibble(
+ label=labelling_data(data) |> labelled::var_label() |> purrr::list_c()
+ )
+ )|>
+ (\(.x){
+ split(.x,.x[["group"]])
+ })()
+}
+
+
+#' Subset labels
+#'
+#' @param data
+#' @param labels.raw
+#'
+#' @return character vector
+#' @export
+#'
+subset_named_labels <- function(data,labels.raw){
+ labels.raw[match(data,names(labels.raw))]
+}
+
+#' Assign labels to data.frame or tibble
+#'
+#' @param data
+#' @param labels
+#'
+#' @return
+#' @export
+#'
+#' @examples
+assign_labels <- function(data,labels){
+ # data |> labelled::set_variable_labels(labels)
+
+ labelled::var_label(data) <- labels
+
+ data
+}
+
+#' Flexible labelling using labelled for nicer tables
+#'
+#' @param data data set
+#'
+#' @return
+#' @export labelled data.frame/tibble
+#'
+#' @examples
+#' data <- targets::tar_read(df_pred_data)
+#' data <- data |> dplyr::mutate(test="test")
+#' data |> labelling_data() |> labelled::var_label()
+labelling_data <- function(data,label.list=var_labels()){
+
+ labs <- subset_named_labels(names(data),label.list)
+ labs[is.na(labs)] <- names(data)[is.na(labs)]
+
+ data |> assign_labels(labels = labs)
+}
+
+
+
+#' Print regression table
+#'
+#' @param data cox regression ready data set
+#'
+#' @return gtsummary tbl_regression list object
+#' @examples
+#' data <- targets::tar_read(df_event_data)
+#' targets::tar_read(df_event_data) |> show_table_regression(use.mice=FALSE)
+show_table_regression <- function(data, use.mice=FALSE, by.var="pase_change") {
+ data |>
+ events_dataset(impute = use.mice) |>
+ cox_regression(all.vars = TRUE, use.strata = FALSE,outcome.var = by.var) |>
+ tbl_regression_standard()
+ # gtsummary::add_n() #|>
+ # gtsummary::bold_p()
+}
+
+
+
+
+#' Splitting df to list by PA trajectory
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_pred_data) |> pred_ls_split()
+pred_ls_split <- function(data, excluded.vars = "reg_bmi"){
+ data |>
+ pase_cutter(drop.pase = FALSE) |>
+ dplyr::select(-tidyselect::all_of(c("pase_4","pase_0_quartile","pase_4_quartile"))) |>
+ dplyr::group_split(pase_split = pase_change %in% c("Increase", "Persistent low")) |>
+ setNames(c("drop", "hop")) |>
+ purrr::map2(.y = c("Decrease", "Increase"), .f = \(x, y){
+ x |>
+ dplyr::mutate(pase_bin = pase_change == y) |>
+ dplyr::select(-tidyselect::all_of(c(excluded.vars, c("pase_change", "pase_split")))) |>
+ na.omit()
+ })
+}
+
+#' Run regularisation steps for split data set
+#'
+#' @param data selected data set
+#'
+#' @return list
+#'
+#' @examples
+#' data <- targets::tar_read(df_pred_data)
+#' targets::tar_read(df_pred_data) |> pred_models()
+pred_models <- function(data, excludes = "reg_bmi") {
+ ls <- data |>
+ pred_ls_split(excluded.vars = excludes) |>
+ purrr::map(regularisation_steps)
+
+ class(ls) <- c("regular_list", class(ls))
+ ls
+}
+
+cross_mean_median_exp_table <- function(data) {
+ nms <- paste0("v", seq_len(ncol(data)))
+
+ cross_calcs <- data |>
+ as.data.frame() |>
+ setNames(nms) |>
+ dplyr::rowwise() |>
+ dplyr::transmute(
+ median = median(dplyr::c_across(tidyselect::all_of(nms))),
+ medianOR = exp(median),
+ mean = mean(dplyr::c_across(tidyselect::all_of(nms))),
+ meanOR = exp(mean)
+ )
+
+ dplyr::tibble(names = rownames(data), cross_calcs) |>
+ dplyr::select(-tidyselect::all_of(c("mean","median")))
+}
+
+
+gather_coefs_step1 <- function(data) {
+ data |>
+ list3levelpluck(lvl1 = "model", lvl2 = "B") |>
+ purrr::map(purrr::reduce, cbind)
+}
+
+gather_coefs <- function(data) {
+ # imputed.list <- "mids_regular_list" %in% class(data)
+
+ if ("mids_regular_list" %in% class(data)) {
+ data_step1 <- data |>
+ purrr::map(gather_coefs_step1) |>
+ purrr::map(purrr::reduce, cbind)
+ } else if ("regular_list" %in% class(data)) {
+ data_step1 <- data |> gather_coefs_step1()
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data_step1 |>
+ purrr::map(cross_mean_median_exp_table) |>
+ purrr::reduce(dplyr::full_join, by = "names", suffix = paste0("_", names(data)))
+}
+
+
+#' Merge and print model coefficients. Pools datafrom mids analyses.
+#'
+#' @param data list
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(ls_pred_models)
+#' targets::tar_read(ls_pred_models) |> print_pred_coefs()
+#' targets::tar_read(ls_pred_mids_reg) |> print_pred_coefs() |> add_var_groups_gt()
+print_pred_coefs <- function(data) {
+ # data <- targets::tar_read(ls_pred_mids_reg)
+ # nms <- names(data)
+
+ if ("mids_regular_list" %in% class(data)) {
+ type.table <- "Pooled regularised models"
+ } else if ("regular_list" %in% class(data)) {
+ type.table <- "Single regularised model"
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ merged_tbl <- data |>
+ gather_coefs() |>
+ ## Leaving out the intercept
+ (function(.x) .x[-1,])()
+
+ sel_mean_med <- colnames(merged_tbl)[!grepl(pattern = "OR",colnames(merged_tbl))][-1]
+ sel_or <- colnames(merged_tbl)[grepl(pattern = "OR",colnames(merged_tbl))]
+
+ news <- subset_named_labels(merged_tbl$names,var_labels())
+
+ merged_tbl <- merged_tbl |> dplyr::mutate(names=dplyr::if_else(is.na(news),names,news))
+
+ gt_merged_tbl <- merged_tbl|>
+ gt::gt() |>
+ gt::fmt_number(decimals = 5)
+
+ merged_tbl_log <- merged_tbl |> dplyr::mutate(dplyr::across(tidyselect::all_of(sel_or), ~.x!=1),
+ dplyr::across(tidyselect::all_of(sel_mean_med), ~.x!=0))
+
+ for (j in colnames(merged_tbl)[-1]) {
+
+ i <- merged_tbl_log[[j]]
+
+ gt_merged_tbl <- gt_merged_tbl |> gt::tab_style(style = list(
+ gt::cell_text(weight="bold")
+ ),
+ locations = gt::cells_body(
+ columns=j,
+ rows = i
+ )
+ )}
+
+ for (i in names(data)) {
+ gt_merged_tbl <- gt_merged_tbl |>
+ gt::tab_spanner(label = i, columns = tidyselect::ends_with(i))
+ }
+
+ gt_merged_tbl |> gt::tab_spanner(
+ label = type.table,
+ columns = -1
+ )
+}
+
+#' Calculates confusionMatrix from contingency tables. Pools if object class is .
+#'
+#' @param data
+#'
+#' @return list
+#'
+#' @examples
+#' targets::tar_read(ls_pred_mids_reg) |> multi_table_cfm()
+#' targets::tar_read(ls_pred_models) |> multi_table_cfm()
+multi_table_cfm <- function(data) {
+ # data <- targets::tar_read(ls_pred_mids_reg)
+ if ("mids_regular_list" %in% class(data)) {
+ data <- data |> purrr::map(\(x){
+ x |>
+ # Test tables are plucked
+ # purrr::map(\(y) y |> purrr::pluck("model") |> purrr::pluck("cMatTest"))|>
+ list3levelpluck(lvl1 = "model", lvl2 = "cMatTest") |>
+ # All tables are add together
+ purrr::reduce(\(i, j) i + j)
+ })
+ } else if ("regular_list" %in% class(data)) {
+ data <- data |> list3levelpluck(lvl1 = "model", lvl2 = "cMatTest")
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data |>
+ purrr::map(caret::confusionMatrix)
+}
+
+#' Collect and summarise auc meassures. Pools if "mids_regular_list" object
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(ls_pred_mids_reg) |> multi_auc_summary()
+#' targets::tar_read(ls_pred_models) |> multi_auc_summary()
+multi_auc_summary <- function(data) {
+ if ("mids_regular_list" %in% class(data)) {
+ data_step <- data |> purrr::map(\(x){
+ x |>
+ # Test tables are plucked
+ list3levelpluck(lvl1 = "model", lvl2 = "auc_test") |>
+ # All tables are add together
+ purrr::reduce(c)
+ })
+ } else if ("regular_list" %in% class(data)) {
+ data_step <- data |>
+ list3levelpluck(lvl1 = "model", lvl2 = "auc_test") |>
+ purrr::map(c)
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data_step |>
+ purrr::map(summary)
+}
+
+#' Map and 2 level recursive purrr::pluck to ease regular_list subsetting
+#'
+#' @param data
+#' @param lvl1
+#' @param lvl2
+#'
+#' @return
+#' @export
+#'
+#' @examples
+list3levelpluck <- function(data, lvl1 = "model", lvl2 = "cMatTest") {
+ data |> purrr::map(\(y) y |>
+ purrr::pluck(lvl1) |>
+ purrr::pluck(lvl2))
+}
+
+#' Plot performance curve from glmnet regularisation
+#'
+#' @param data list of cvs.glmnet objects
+#'
+#' @return ggplot list object
+#' @export
+#'
+#' @examples
+plot_roc_curve <- function(data, title.text) {
+ ggplot2::ggplot() +
+ purrr::map(data, function(i) {
+ ggplot2::geom_step(data = i, ggplot2::aes(x = FPR, y = TPR))
+ }) +
+ ggplot2::coord_cartesian(xlim = c(0, 1), ylim = c(0, 1)) +
+ ggplot2::geom_abline() +
+ ggplot2::theme_bw() +
+ ggplot2::ggtitle(title.text)
+}
+
+roc_gather_step <- function(x) {
+ with(x, glmnet::roc.glmnet(cvs[[1]]$fit.preval, newy = y1)[match(bestL, lambdas)])
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(ls_pred_mids_reg) |> multi_roc_plot()
+#' targets::tar_read(ls_pred_models) |> multi_roc_plot()
+multi_roc_plot <- function(data) {
+ if ("mids_regular_list" %in% class(data)) {
+ data_step1 <- data |>
+ purrr::map(purrr::map, roc_gather_step) |>
+ purrr::map(purrr::list_flatten)
+ } else if ("regular_list" %in% class(data)) {
+ data_step1 <- data |> purrr::map(roc_gather_step)
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data_step1 |>
+ purrr::map2(.y = names(data), plot_roc_curve) |>
+ patchwork::wrap_plots()
+}
+
+#' Title
+#'
+#' @param tuning.param
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+multi_tuning_gather <- function(tuning.param = "bestA", data) {
+ if ("mids_regular_list" %in% class(data)) {
+ data_step1 <- data |>
+ purrr::map(purrr::map, \(x) x |> purrr::pluck(tuning.param)) |>
+ purrr::map(purrr::reduce, c)
+ } else if ("regular_list" %in% class(data)) {
+ data_step1 <- data |>
+ purrr::map(purrr::pluck, tuning.param)
+ } else {
+ stop("The supplied list has to be class 'mids_regular_list' or 'regular_list'")
+ }
+
+ data_step1 |> purrr::map(summary)
+}
+
+
+#' Tidied tuning summary call
+#'
+#' @param data
+#'
+#' @return
+#'
+#' @examples
+#' targets::tar_read(ls_pred_mids_reg) |> tuning_summary()
+#' targets::tar_read(ls_pred_models) |> tuning_summary()
+tuning_summary <- function(data) {
+ c(ALPHA = "bestA", LAMBDA = "bestL") |> purrr::map(\(x) x |> multi_tuning_gather(data = data))
+}
+
+#' Apply regularisation steps to MIDS object, output arranged by grouping
+#'
+#' @param data mids object from mice package
+#'
+#' @return list
+#'
+#' @examples
+#' targets::tar_read(df_pred_mids) |> mids_regularisation()
+mids_regularisation <- function(data) {
+ ls <- data |>
+ mice::complete(action = "long") |>
+ dplyr::group_split(.imp) |>
+ purrr::modify(\(x){
+ x |> dplyr::select(-tidyselect::all_of(c(".imp", ".id")))
+ }) |>
+ purrr::map(pred_models)
+
+ nms <- ls |>
+ purrr::map(names) |>
+ unique() |>
+ purrr::reduce(c)
+
+ # As a consequence of the above code each "set" of analyses are together.
+ # Here the same group analyses are subset and grouped
+ ls_n <- purrr::map(nms, function(i) {
+ ls |> purrr::map(purrr::pluck, i)
+ }) |>
+ setNames(nms)
+
+ # Special class is applied to ease future handling
+ class(ls_n) <- c("mids_regular_list", class(ls_n))
+ ls_n
+}
+
+#' A collection of all the summary functions to be applied to list of
+#' pred_models() output
+#'
+#' @param data list of data
+#'
+#' @return list
+#' @export
+#'
+multi_summary <- function(data){
+ list( "coefTable" = print_pred_coefs(data) |>
+ gt::fmt_number(n_sigfig = 3) |>
+ fix_labels() #|> add_var_groups_gt()
+ ,
+ "confusionMatrices" = multi_table_cfm(data),
+ "summaryAUC" = multi_auc_summary(data),
+ "rocPlots" = multi_roc_plot(data),
+ "tuningSummaries" = tuning_summary(data))
+}
+
+# funs <-list(
+# "coefTable" = print_pred_coefs,
+# "confusionMatrices" = multi_table_cfm,
+# "summaryAUC" = multi_auc_summary,
+# "rocPlots" = multi_roc_plot,
+# "tuningSummaries" = tuning_summary
+# )
+
+# multi_summary <- plyr::each(
+# "coefTable" = print_pred_coefs,
+# "confusionMatrices" = multi_table_cfm,
+# "summaryAUC" = multi_auc_summary,
+# "rocPlots" = multi_roc_plot,
+# "tuningSummaries" = tuning_summary
+# )
+
+#' Subset multiple elements from list
+#'
+#' @param data list
+#' @param indices numeric or character vector
+#'
+#' @return list
+#' @examples
+#' targets::tar_read(ls_pred_summary)$confusionMatrices |> purrr::map(list_subset)
+list_subset <- function(data,indices=c("overall","byClass")){
+ data[indices]
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(ls_pred_summary) |> print_model_resutls()
+print_model_resutls <- function(data){
+ par(mfrow=c(1,2))
+
+ list(data$coefTable,
+ invisible(data$confusionMatrices |> purrr::map(\(x) x |> purrr::pluck("table"))),
+ data$confusionMatrices |> purrr::map(list_subset),
+ data$summaryAUC,
+ data$tuningSummaries
+ )
+}
+
+
+#' Classic logistic regression on prediction covariates
+#'
+#' @param data data frame
+#'
+#' @return
+#' @export
+#'
+#' @examples gtsummary list elemnt
+#' targets::tar_read(df_pred_data) |> pred_log_reg()
+#' targets::tar_read(df_pred_data) |> pred_ls_split()
+pred_log_reg <- function(data){
+ data |> pred_ls_split() |>
+ purrr::map(\(x) {
+ gtsummary::tbl_regression(glm(pase_bin~.,family = binomial,data = x),
+ exponentiate= TRUE)#|>
+ # gtsummary::bold_p()
+ }
+ ) |> (\(x){gtsummary::tbl_merge(tbls = x,
+ tab_spanner = names(x))})() }
+
+#' Small wrapper to format CI with square brackets
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+square_ci <- function(data){
+ gsub("(-?\\d*\\.?\\d*)(, )(-?\\d*\\.?\\d*)",
+ "\\[\\1; \\3\\]",data)}
+
+#' Apply CI formatting across gtsummary table including merged tables
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+fix_ci <- function(data){
+ data |> gtsummary::modify_table_body(~ .x |>
+ dplyr::mutate(dplyr::across(dplyr::starts_with("ci"),
+ function(.y){square_ci(.y)})))
+}
+
+#' Classic linear regression on 6 months PASE score. Uni and multi.
+#'
+#' @param data data frame
+#'
+#' @return
+#' @export
+#'
+#' @examples gtsummary list elemnt
+#' data <- targets::tar_read(df_pred_data)
+#' data <- targets::tar_read(df_pred_mids)
+#' targets::tar_read(df_pred_data) |> pred_lin_reg()
+#' targets::tar_read(df_pred_mids) |> pred_lin_reg()
+pred_lin_reg <- function(data){
+
+ # list("tbl_regression-str:ref_row_text"="Reference") |>
+ # gtsummary::set_gtsummary_theme()
+
+ if ("mids" %in% class(data)){
+ cols <- names(data$data)
+
+ } else {
+ cols <- names(data)
+ data <- data |>
+ labelling_data()
+ }
+
+ vars <- cols[cols!="pase_4"]
+
+ formula_pase <- paste("pase_4",paste(vars,collapse = "+"),sep="~" )
+
+ # multi <- with(data=data,lm(pase_4~.)) |>
+ # gtsummary::tbl_regression(add_estimate_to_reference_rows = TRUE)|>
+ # gtsummary::bold_p() |> gtsummary::add_n()
+
+ if (!"mids" %in% class(data)){
+ ls <- list("Univariate"=data |>
+ gtsummary::tbl_uvregression(method=lm, show_single_row = dplyr::where(is.logical),
+ y=pase_4,
+ add_estimate_to_reference_rows = TRUE,pvalue_fun = NULL)#|> gtsummary::bold_p()
+ ,
+ "Multivariate (no BMI)"=lm(pase_4~.,data=dplyr::select(data,-reg_bmi)) |>
+ gtsummary::tbl_regression(add_estimate_to_reference_rows = TRUE, show_single_row = dplyr::where(is.logical))|>
+ # gtsummary::bold_p() |>
+ gtsummary::add_n()
+ ,
+ "Multivariate (ALL)"= lm(pase_4~.,data=data) |>
+ gtsummary::tbl_regression(add_estimate_to_reference_rows = TRUE, show_single_row = dplyr::where(is.logical))|>
+ # gtsummary::bold_p() |>
+ gtsummary::add_n()
+ )
+
+ } else {
+ ls <- list("Multivariate (ALL)"= suppressWarnings(mice::lm.mids(pase_4~.,data=data) |>
+ gtsummary::tbl_regression(add_estimate_to_reference_rows = TRUE, show_single_row = dplyr::where(is.logical))|>
+ # gtsummary::bold_p() |>
+ gtsummary::add_n()))
+ }
+
+ ls |> (\(x){gtsummary::tbl_merge(tbls = x,
+ tab_spanner = names(x))})() |>
+ fix_ci()
+}
+
+
+#' Simple standard plot
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_event_data) |> events_dataset(impute = FALSE)|> cox_regression() |> plot_survival()
+plot_survival <- function(data){
+ data |>
+ ggsurvfit::survfit2() |>
+ ggsurvfit::ggsurvfit(linetype_aes = TRUE, size = 0.8) +
+ ggsurvfit::add_confidence_interval() +
+ ggsurvfit::add_risktable(
+ risktable_stats = c("n.risk", "cum.event"),
+ stats_label = list(cum.event = "Cumulative Observed Events",
+ n.risk = "Number at Risk"),
+ theme =
+ list(
+ ggsurvfit::theme_risktable_default(axis.text.y.size = 11,
+ plot.title.size = 11),
+ ggplot2::theme(plot.title = ggplot2::element_text(face = "bold"))
+ )
+ ) +
+ ggplot2::scale_y_continuous(
+ limits = c(0, 1),
+ labels = scales::percent,
+ expand = c(0.01, 0)
+ ) +
+ ggplot2::scale_x_continuous(breaks = 0:9, expand = c(0.02, 0))
+}
+
+
+#' Smooth tidy survfit object
+#'
+#' @param data survfit object
+#'
+#' @return tibble
+#' @export
+#'
+#' @examples
+#' ls <- targets::tar_read(df_event_data) |> events_dataset(impute = FALSE)|> cox_regression()
+#' data <- ls |> ggsurvfit::survfit2(robust=TRUE) |>
+#' ggsurvfit::tidy_survfit(type="survival") |>
+#' dplyr::group_split(strata) |> purrr::pluck(1)
+#'
+#' ls |> ggsurvfit::survfit2(robust=TRUE) |>
+#' ggsurvfit::tidy_survfit(type="survival") |>
+#' dplyr::group_split(strata) |>
+#' purrr::map(smooth_col)
+smooth_col <- function(data, force_mono=TRUE){
+ smoothed <- lapply(c("estimate","conf.high","conf.low"),function(i){
+ # stats::predict(cobs::cobs(x = data$time,
+ # y = data[i],
+ # constraint = "decrease",
+ # nknots=4,
+ # pointwise = rbind(c(0,min(data$time),1)),
+ # degree = 2,)) |>
+ # tibble::as_tibble() |> dplyr::select(fit) |>
+ stats::predict(mgcv::gam(data=data,formula = as.formula(glue::glue("{i}~s(time,bs='cs')")))) |>
+ tibble::as_tibble()|>
+ setNames(glue::glue("{i}_smooth"))
+ }) |> purrr::list_cbind()
+
+ if (force_mono){
+ ## Forcing starting point to be 1
+ smoothed[1,1] <- 1
+
+ smoothed[1] <- force_decrease(smoothed[1]) ## Only monotonize the esitimate
+ }
+
+ dplyr::tibble(data,
+ smoothed)
+
+}
+
+#' Forces the direction
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+force_decrease <- function(data){
+ data |> purrr::imap(function(.x,.n){
+ s <- c()
+ for (i in seq_along(.x)){
+ if (i == 1) {
+ s[1] <- .x[1]
+ } else {
+ if (.x[i]>s[i-1]){
+ s[i] <- s[i-1]
+ } else {
+ s[i] <- .x[i]
+ }
+ }
+ }
+ s
+ }) |>
+ dplyr::bind_cols()
+}
+
+
+#' Prepare cox regression for smooth survival plot
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> events_dataset(impute = FALSE)|> cox_regression() |> smooth_cox_data()
+smooth_cox_data <- function(data){
+ data |>
+ ggsurvfit::survfit2(robust=TRUE) |>
+ ggsurvfit::tidy_survfit(type="survival") |>
+ dplyr::group_split(strata) |>
+ purrr::map(smooth_col) |>
+ purrr::list_rbind()
+}
+
+#' Plot smooth survival plot
+#'
+#' @param data df from cox regression
+#'
+#' @return ggplot list object
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_event_data) |> events_dataset(impute = FALSE) |> cox_regression()
+#' data <- targets::tar_read(df_events_mids) |> cox_regression()
+#' data |> plot_survival_smooth()
+plot_survival_smooth <- function(data){
+ if ("mira" %in% class(data)) stop("Only plots non-imputed survival data")
+
+ n.level <- length(data$xlevels[[1]])
+
+ # data |>
+ # ggsurvfit::survfit2() |>
+ # ggsurvfit::tidy_survfit()
+
+ if (data |> ggsurvfit::survfit2() |> purrr::pluck("n") |> length() ==1 ){
+ ds <- data |>
+ ggsurvfit::survfit2() |>
+ ggsurvfit::tidy_survfit()
+ p <- ds |>
+ ggplot2::ggplot(ggplot2::aes(x=time, y=estimate))+
+ ggplot2::geom_smooth(se=TRUE, method="loess", formula = "y~x", linewidth=2, color="grey10")
+ # Added auto max for y axis removed again to ensure same y axis
+ # max_y <- max(ds$conf.high)
+
+ } else {
+ ds <- data |>
+ smooth_cox_data()
+ p <- ds |>
+ ggplot2::ggplot()+
+ ggplot2::geom_line(ggplot2::aes(x=time, y=estimate_smooth, color=strata, linetype=strata), linewidth=2)+
+ ggplot2::geom_ribbon(ggplot2::aes(x=time, ymin=conf.low_smooth,ymax=conf.high_smooth, fill=strata), alpha=.2)
+ # Added auto max for y axis removed again to ensure same y axis
+ # max_y <- max(ds$conf.high_smooth)
+
+ }
+
+ if (n.level==4){
+ colors <- viridisLite::turbo(n=n.level,direction = 1)[c(1,3,2,4)]
+ } else {
+ colors <- viridisLite::turbo(n=n.level,direction = 1)
+ }
+
+ p+
+ ggplot2::scale_y_continuous(limits = c(0,1.02),
+ breaks = seq(0,1,.25),
+ labels = scales::percent,
+ expand = c(0.01, 0)
+ ) +
+ ggplot2::scale_x_continuous(breaks = 0:9, expand = c(0.02, 0))+
+ ggplot2::scale_fill_manual(values=colors)+
+ ggplot2::scale_color_manual(values=colors)+
+ ggplot2::theme_minimal()+
+ ggplot2::theme(axis.title.x = ggplot2::element_blank(),
+ axis.title.y = ggplot2::element_blank(),
+ # axis.text = ggplot2::element_blank(),
+ # legend.position = "none",
+ panel.grid.minor.y = ggplot2::element_blank(),
+ panel.grid.major.y = ggplot2::element_line(color="grey45",linewidth = 1))
+
+}
+
+# viridisLite::turbo(n=4,direction = 1)[c(1,3,2,4)]
+
+cluster_rank <- function(data){
+ data |> cox_regression(outcome.var = "clust",use.strata = TRUE) |> ggsurvfit::survfit2(robust=TRUE) |>
+ ggsurvfit::tidy_survfit(type="survival") |>
+ dplyr::group_split(strata) |>
+ purrr::map(\(x){
+ min(x[["estimate"]])
+ }) |> purrr::list_c() |> rank() |> rev()
+}
+
+cox_relevel <- function(data){
+ data |> dplyr::mutate(clust=factor(clust,levels=cluster_rank(data)))
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_all_data_formatted)
+complete_preds_data <- function(data){
+ data |>
+ # events_ready() |>
+ fun_impute(ignore = c("pase_0","pase_4"),pase.mod = FALSE) |>
+ mice::complete() |>
+ dplyr::filter((!is.na(pase_0)&!is.na(pase_4)))
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' targets::tar_read(df_all_data_formatted) |> add_kamila_cluster()
+#' data_kam <- targets::tar_read(df_all_data_formatted) |> add_kamila_cluster()
+#' data_kam |>print_table_summary(by.var = "kam_grp")
+#' data_kam |> cox_regression(outcome.var="kam_grp")|> plot_survival_smooth()
+#' data_kam |> cox_regression(outcome.var="kam_grp",use.strata = FALSE)|> gtsummary::tbl_regression(exponentiate = TRUE, add_estimate_to_reference_rows = TRUE) |> gtsummary::bold_p()
+#' targets::tar_read(df_events_complete) |> kamila_cluster(n.clusters=3)
+kamila_cluster <- function(data, n.clusters=3,include.out=FALSE){
+ # An index number could be added to later join pack. Of input a complete data set from imputation and pooling??
+ data_orig <- data
+
+
+ if (!include.out){
+ data <- data |>
+ dplyr::select(-tidyselect::one_of(c("time","status")))
+ }
+
+
+ catInd <- data |> lapply(\(x) is.character(x)|is.logical(x)) |> purrr::list_c()
+ conInd <- data |> lapply(\(x) is.numeric(x)|is.integer(x)) |> purrr::list_c()
+
+ catVars <- data[,catInd]
+ catVars <- catVars |> lapply(factor) |> dplyr::bind_cols() |> as.data.frame()
+ conVars <- data[,conInd] |> scale()|> as.data.frame()
+
+ if (is.null(n.clusters)){
+ out <- kamila::kamila(conVar = conVars, catFactor = catVars, numClust = 2:7, numInit = 10,
+ calcNumClust = "ps"
+ )
+ }else {
+ out <- kamila::kamila(conVar = conVars, catFactor = catVars, numClust = n.clusters, numInit = 10)
+ }
+
+ ls <- list("out"=out,"data_orig"=data_orig)
+
+ class(ls) <- c("kamila_cluster",class(ls))
+
+ ls
+
+}
+
+
+#' VarSelLCM wrapper
+#'
+#' @param data complete dataset with no missings
+#' @param n.clusters number of clusters (if length 1, n is fixed, in n>1 given clusters are tested)
+#' @param include.out flag to include outcome variables or not
+#' @param memb.out output data frame with final membership or not (then outputs standard model output)
+#'
+#' @return list with VarSelLCM output and original dataset with cluster appended
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' data |> lcm_cluster()
+lcm_cluster <- function(data, n.clusters=3, include.out=FALSE, var.sel=FALSE){
+ data_orig <- data
+
+ if (!include.out){
+ data <- data |>
+ dplyr::select(-c("time", "status"))
+ }
+
+
+ set.seed(5432)
+
+ out <- data |>
+ dplyr::mutate(dplyr::across(where(is.logical)|where(is.character),~factor(.x))) |>
+ as.data.frame() |>
+ VarSelLCM::VarSelCluster(
+ gvals=n.clusters,
+ crit.varsel="BIC",
+ vbleSelec = var.sel,
+ nbcores = round(parallel::detectCores()*.8)
+ )
+
+ ls <- list("out"=out,"data_orig"=data_orig)
+
+ class(ls) <- c("lcm_cluster",class(ls))
+
+ ls
+
+}
+
+#' Kmeans clustering
+#'
+#' @param data
+#' @param n.clusters
+#' @param include.out
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' data |> kmeans_cluster()
+#' data |> kmeans_cluster(n.clusters=3)
+kmeans_cluster <- function(data, n.clusters=3, include.out=FALSE, memb.out=TRUE){
+ data_orig <- data
+
+ if (!include.out){
+ data <- data |>
+ dplyr::select(!tidyselect::one_of(c("time", "status")))
+ }
+
+ out <- data |>
+ dplyr::mutate(dplyr::across(where(is.double),~scale(.x)),
+ dplyr::across(where(is.logical)|where(is.character),~factor(.x)),
+ dplyr::across(where(is.factor),~as.numeric(.x))) |>
+ stats::kmeans(
+ centers=n.clusters
+ )
+
+ ls <- list("out"=out,"data_orig"=data_orig)
+
+ class(ls) <- c("kmeans_cluster",class(ls))
+
+ ls
+
+}
+
+#' dbscan clustering
+#'
+#' @param data
+#' @param n.clusters
+#' @param include.out
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' data |> dbscan_cluster()
+#' data |> dbscan_cluster(n.clusters=3)
+dbscan_cluster <- function(data, n.clusters=3, include.out=FALSE, memb.out=TRUE){
+ data_orig <- data
+
+ if (!include.out){
+ data <- data |>
+ dplyr::select(!tidyselect::one_of(c("time", "status")))
+ }
+
+ data <- data |> na.omit() |> dplyr::mutate(rtreat=rtreat!="Placebo",
+ dplyr::across(dplyr::everything(), as.numeric))
+
+
+ ## This plot indicates that eps should be set around 60, but at this value everything is one cluster.
+ dbscan::kNNdistplot(data,k = 5)
+
+ ## Performing hierachical clustering, it is clear, that the algorithm is not able to seperate clusters.
+ hds <- dbscan::hdbscan(data,minPts = 5)
+
+ plot(hds,show_flat = TRUE)
+
+ ## Clustering with set eps value and minPts
+ ds <- dbscan::dbscan(data,eps = 25,minPts = 2)
+
+ ds[["cluster"]]
+
+ ## dbscan is not an interesting approach, apparently
+
+ #
+ #
+ #
+ #
+ # out <- data |>
+ # dplyr::mutate(dplyr::across(where(is.double),~scale(.x)),
+ # dplyr::across(where(is.logical)|where(is.character),~factor(.x)),
+ # dplyr::across(where(is.factor),~as.numeric(.x))) |>
+ # stats::kmeans(
+ # centers=n.clusters
+ # )
+ #
+ # ls <- list("out"=out,"data_orig"=data_orig)
+ #
+ # class(ls) <- c("kmeans_cluster",class(ls))
+ #
+ # ls
+
+}
+
+#' Title
+#'
+#' @param ls
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' ls <- data |> lcm_cluster()
+#' ls |> final_membership()
+final_membership <- function(ls){
+ cls <- class(ls)
+ if ("kamila_cluster" %in% cls) {
+
+ tibble::tibble(clust=factor(ls$out$finalMemb),
+ ls$data_orig)
+
+ } else if ("lcm_cluster" %in% cls) {
+
+ tibble::tibble(clust=factor(ls$out@partitions@zMAP),
+ ls$data_orig)
+
+ } else if ("kmeans_cluster" %in% cls) {
+
+ tibble::tibble(clust=factor(ls$out$cluster),
+ ls$data_orig)
+
+ } else stop("Class not recognised")
+
+}
+
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(df_events_complete)
+#' data |> get_clusters()
+#' data |> get_clusters(n.cl=2:7)
+get_clusters <- function(data,n.cl=4,rm.out=TRUE){
+ set.seed(1123)
+
+ if (length(n.cl)>1){
+ list(
+ # "kmeans"=data |> kmeans_cluster(n.clusters = n.cl,include.out = !rm.out),
+ "lcm"= data |> lcm_cluster(n.clusters = n.cl,include.out = !rm.out),
+ "kamila"=data |> kamila_cluster(n.clusters = n.cl,include.out = !rm.out)
+ )
+ } else {
+ list(
+ "kmeans"=data |> kmeans_cluster(n.clusters = n.cl,include.out = !rm.out),
+ "lcm"= data |> lcm_cluster(n.clusters = n.cl,include.out = !rm.out),
+ "kamila"=data |> kamila_cluster(n.clusters = n.cl,include.out = !rm.out)
+ )
+ }
+
+}
+
+#' Title
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' data <- targets::tar_read(list_pred_clusters)
+#' data |> final_clusters()
+final_clusters <- function(data,new.levels=NULL){
+ out <- data |> lapply(final_membership) |> lapply(labelling_data)
+
+ if (is.null(new.levels)){
+ out
+ } else {
+ out |>
+ purrr::map2(relevels,function(x,y){
+ # x$clust <- factor(factor(x$clust,levels=y),labels=1:4)
+ x$clust <- factor(x$clust,levels=y)
+ x #|>
+ # dplyr::filter(clust %in% range(as.numeric(clust))) |>
+ # dplyr::mutate(clust=factor(clust))
+ })
+ }
+
+ }
+
+
+
+#' Title
+#'
+#' @param data
+#' @param by
+#'
+#' @return
+#' @export
+#'
+#' @examples
+merged_summary_tbl <- function(data,by="clust"){
+ data |>
+ purrr::map(function(x){
+ x |>
+ # print_table_summary(by.var = by)
+ gtsummary::tbl_summary(by=by) #|>
+ # gtsummary::add_p() |> gtsummary::bold_p()
+ }
+ ) |> (\(x){
+ x |> gtsummary::tbl_merge(tab_spanner = names(x))
+ })()
+}
+
+#' Easy cox regression tbl for uniform results
+#'
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+cox2tbl <- function(data,by="clust",all.vars=FALSE){
+data|> cox_regression(outcome.var = by,use.strata = FALSE,all.vars = all.vars) |>
+ gtsummary::tbl_regression(exponentiate =TRUE,
+ statistics=list(gtsummary::all_continuous()~"[{conf.low};{conf.high}]",
+ gtsummary::all_categorical()~"[{conf.low}%;{conf.high}%]")) |>
+ gtsummary::bold_p()
+}
+
+#' Title
+#'
+#' @param data
+#' @param by
+#'
+#' @return
+#' @export
+#'
+#' @examples
+merged_cox_reg_tbl <- function(data,by="clust"){
+ data |>
+ purrr::map(function(x){
+ x |> cox2tbl(by=by)
+ }
+ ) |> (\(x){
+ x |> gtsummary::tbl_merge(tab_spanner = names(x))
+ })()
+}
+
+#' Title
+#'
+#' @param data
+#' @param by
+#'
+#' @return
+#' @export
+#'
+#' @examples
+wrapped_surv_plot <- function(data,by="clust"){
+data |>
+ purrr::map(function(x){
+ x |> cox_regression(outcome.var = by,use.strata = TRUE,all.vars = FALSE) |>
+ plot_survival_smooth()+ggplot2::labs(color="Cluster",fill="Cluster",linetype="Cluster")
+ }
+ ) |> (\(x){
+ x |> patchwork::wrap_plots(ncol=1) + patchwork::plot_annotation(tag_levels = list(names(x)))
+ })()
+}
+
+
+# Ranking by most events
+relevel_by_rank <- function(data){
+ ## Assigning clusters to each dataset
+data <- targets::tar_read(list_pred_clusters) |>
+ final_clusters(new.levels = NULL)
+
+## Calculating cox regressions and ranking by the final point on the survival plot
+relevels <- data |>
+ purrr::map(function(x){
+ x |> cox_regression(outcome.var = "clust",use.strata = TRUE,all.vars = FALSE) |>
+ ggsurvfit::survfit2() |>
+ ggsurvfit::tidy_survfit() |>
+ (\(x){
+ split(x,x[["strata"]]) |>
+ purrr::map(function(.y){
+ .y[["estimate"]][nrow(.y)]
+ })
+ })() |> purrr::reduce(c) |> rank()
+ }
+ )
+
+#3 Assigning the new, ranked levels
+targets::tar_read(list_pred_clusters) |>
+ final_clusters(new.levels = relevels)
+}
+
+## TODO
+## Verify definitions
+## Do remaining documentation of functions
+##
+##
+## How does elastic net work with imputed dataset?
+## Functionalise to allow for imputed and non-imputed (both analyses) - in both cases with and without BMI - include department of inclusion to investigate reason of missing BMI data
+##
+## tidymodels does not allow pmm in mice. Thy're out!
+
+##
+
+missing_stats <- function(index,data,glue.mask= "{N_miss} ({round(p_miss*100,dec)}%)",dec){
+ index.var <- unique(data$table_body$variable)[index]
+
+ table_body <- data$table_body |>
+ dplyr::filter(variable == index.var)
+
+ if ("missing" %in% table_body$row_type){
+ f1 <- grep("stat_\\d+",names(table_body))
+
+ ## This approach
+ masks <- data$meta_data$df_stats |>
+ purrr::pluck(index) |>
+ dplyr::filter(!duplicated(col_name)) |>
+ dplyr::arrange(col_name) |>
+ dplyr::mutate(mask=glue::glue(glue.mask))|>
+ dplyr::pull(mask)
+
+ table_body[table_body$row_type=="missing",f1] <- masks |>
+ as.matrix() |>
+ t() |>
+ tibble::as_tibble(.name_repair = "unique_quiet")
+
+ }
+ table_body
+}
+
+missing_stats_steps <- function(body,ls,glue.mask,dec){
+ seq_along(unique(body$variable)) |>
+ purrr::map(function(.x) {
+ missing_stats(index=.x,data=ls,glue.mask = glue.mask,dec=dec)
+ }) |>
+ dplyr::bind_rows()
+}
+
+add_missing_stats <- function(data,glue.mask= "{N_miss} ({round(p_miss*100,dec)}%)",dec=1){
+ data |>
+ gtsummary::modify_table_body(
+ ~ .x |> missing_stats_steps(ls=data,glue.mask = glue.mask,dec=dec)
+ )
+}
+
+variable_masks <- function(index, data, cut.off,glue.mask= "<{n} (<{p}%)",dec=dec) {
+ index.var <- unique(data$table_body$variable)[index]
+
+ table_body <- data$table_body |>
+ dplyr::filter(variable == index.var)
+
+
+ ## Filtering bu two different approaches
+ if (table_body$var_type[1] %in% c("dichotomous", "categorical")) {
+ if (any(grepl("^stat_[1-9]|[1-9]\\d",names(table_body)))){
+ masked <- micro_n_masks(
+ ## Handling nominal/binary
+
+ body = table_body |>
+ dplyr::filter(row_type!="missing"),
+ n.all = data$meta_data$df_stats |>
+ purrr::pluck(index) |>
+ dplyr::select(n),
+ N.all=data$meta_data$df_stats |>
+ purrr::pluck(index) |>
+ dplyr::select(N),
+ cut.off=cut.off,
+ glue.mask = glue.mask
+ )
+ } else {
+ masked <- table_body |> dplyr::filter(row_type!="missing")
+ }
+
+
+ if ("stat_0" %in% names(masked)){
+ body <- masked
+ tb <- body |> dplyr::filter(row_type!="missing",!is.na(stat_0))
+ f1 <- grep("^stat_0", names(tb))
+
+ meta.index <- data$meta_data$df_stats |>
+ purrr::pluck(index)
+
+ if ("by" %in% names(meta.index)) {
+ meta.index <- meta.index |> dplyr::filter(is.na(by))
+ }
+
+ masked <- masking(body=body,
+ tb=tb,
+ f1=f1,
+ ns = meta.index |>
+ dplyr::select(n)|>
+ dplyr::slice(seq_len(length(f1) * nrow(tb))) |>
+ unlist(use.names = FALSE) |>
+ matrix(ncol = length(f1), byrow = TRUE) |>
+ tibble::as_tibble(.name_repair = "unique_quiet"),
+ Ns= meta.index |>
+ dplyr::select(N_obs) |>
+ dplyr::slice(1)|>
+ unlist(use.names = FALSE),
+ cut.off=cut.off,
+ glue.mask=glue.mask,
+ dec=dec)
+ }
+
+ out <- rbind(
+ masked,
+ table_body |> dplyr::filter(row_type=="missing"))
+
+ } else {
+ out <- table_body
+ }
+
+ if ("missing" %in% out$row_type) {
+ ## Handling missings n is N_miss, and N is N_obs
+
+ missings <- micro_n_masks(
+ body = out |>
+ dplyr::filter(row_type == "missing"),
+ n.all = data$meta_data$df_stats |>
+ purrr::pluck(index) |>
+ dplyr::select(N_miss),
+ N.all=data$meta_data$df_stats |>
+ purrr::pluck(index) |>
+ dplyr::select(N_obs),
+ cut.off=cut.off,
+ glue.mask=glue.mask
+ )
+
+ if ("stat_0" %in% names(missings)) {
+ ## Handling overall column
+ body <- missings
+ tb <- body |> dplyr::filter(row_type=="missing")
+ f1 <- grep("^stat_0", names(tb))
+
+ masking(body=body,
+ tb=tb,
+ f1=f1,
+ ns = data$meta_data$df_stats |>
+ purrr::pluck(index) |>
+ dplyr::filter(is.na(by)) |>
+ dplyr::select(N_miss) |>
+ dplyr::slice(1) |>
+ unlist(use.names = FALSE) |>
+ matrix(ncol = length(f1), byrow = TRUE) |>
+ tibble::as_tibble(.name_repair = "unique_quiet"),
+ Ns=data$meta_data$df_stats |>
+ purrr::pluck(index) |>
+ dplyr::filter(is.na(by)) |>
+ dplyr::select(N_obs) |>
+ dplyr::slice(1) |>
+ unlist(use.names = FALSE),
+ cut.off=cut.off*2,
+ glue.mask=glue.mask,
+ dec=dec)
+
+ }
+
+ out <- rbind(
+ out |>
+ dplyr::filter(row_type != "missing"),
+ missings)
+
+
+
+
+
+ }
+
+ out
+}
+
+micro_n_masks <- function(body, n.all, N.all, cut.off, glue.mask,dec=1) {
+ if (nrow(body) > 1) {
+ # First row removed in case of categorical
+ # Possibly change to include in filter, to have whole df, or just rbind in the end
+ tb <- body |> dplyr::filter(row_type!="label")
+ } else { # last option is "dichotomous"
+ tb <- body
+ }
+
+ ## Supports any number of stat columns (overkill!)
+ f1 <- grep("^stat_[1-9]|[1-9]\\d", names(tb))
+
+ masking(body=body,
+ tb=tb,
+ f1 = f1,
+ ns=n.all |>
+ dplyr::slice(seq_len(length(f1) * nrow(tb))) |>
+ unlist(use.names = FALSE) |>
+ matrix(ncol = length(f1), byrow = TRUE) |>
+ tibble::as_tibble(.name_repair = "unique_quiet"),
+ Ns=N.all |>
+ dplyr::slice(seq_len(length(f1))) |>
+ unlist(use.names = FALSE),
+ cut.off=cut.off,
+ glue.mask=glue.mask,
+ dec=dec
+ )
+
+}
+
+
+#' Title
+#'
+#' @param body full table body
+#' @param tb filtered table body
+#' @param f1 Subsets indexes of relevant columns
+#' @param ns Relevant ns arranged in matrix
+#' @param Ns All Ns
+#' @param cut.off
+#' @param glue.mask
+#' @param dec
+#'
+#' @return
+#' @export
+masking <- function(body,
+ tb=NULL,
+ f1,
+ ns,
+ Ns,
+ cut.off=cut.off,
+ glue.mask=glue.mask,
+ dec=dec
+ ){
+
+ if (is.null(tb)) tb <- body
+
+ ## Logical matrix of relevant ns to mask
+ f2 <- ns |>
+ purrr::map(\(.x) .x %in% 1:(cut.off - 1)) |>
+ dplyr::bind_cols() |>
+ as.matrix()
+
+ ## Number of cells with zero observations in each matrix row
+ n0 <- apply(ns == 0, 1, sum)
+
+ ## Number of cells with ns to mask in each matrix row
+ ns.low <- apply(f2, 1, sum)
+
+
+ if (all(ns.low==0)){
+ out <- body
+ } else {
+
+ ls.rows <- seq_len(nrow(f2)) |>
+ purrr::map(\(.i){
+
+ ds <- tb[.i, ]
+ # Creating masked matrix to record maskings
+ masked <- matrix(FALSE, ncol = ncol(f2))
+
+ # Only modify in case of low, handle one col matrices
+ if (apply(f2, 1, any)[.i]) {
+ n <- cut.off
+ N <- Ns[f2[.i,]]
+ p <- round(100 * n / N, dec)
+
+ ds[f1[f2[.i,]]] <- glue::glue(glue.mask) |>
+ as.matrix() |>
+ t() |>
+ tibble::as_tibble(.name_repair = "unique_quiet")
+ masked[f2[.i,]] <- TRUE
+
+ ## loop to add masks until satisfied
+ while (sum(masked)==1 & # The case of only one low
+ nrow(masked)>1 | # But ignored in case of ncol==1
+ sum(ns[.i,][masked]) <= cut.off &
+ (sum(masked) + n0[.i]) < ncol(masked)) {
+ # in the case that sum of smalls is below cutoff, another field is added.
+
+ ranked <- apply(ns[.i,], 1, rank, ties.method = "first") |> t()
+
+ ranked.i <- ranked == sum(masked) + n0[.i] + 1
+ n <- ns[.i,][ranked.i] |> plyr::round_any(accuracy = cut.off, f = ceiling)
+ N <- Ns[ranked.i]
+ p <- round(100 * n / N, dec)
+
+ ds[f1[ranked.i]] <- glue::glue(glue.mask)
+ masked[ranked.i] <- TRUE
+ }}
+
+ list(
+ ds = ds,
+ masked = masked
+ )
+ })
+
+ # The case for dichotomous
+ if (nrow(tb) == 1) {
+ out <- ls.rows |>
+ purrr::map(purrr::pluck, "ds") |>
+ dplyr::bind_rows()
+
+ # Handling categorical data
+ } else if (nrow(tb) > 1) {
+ masks <- ls.rows |>
+ purrr::map(purrr::pluck, "masked") |>
+ purrr::reduce(rbind)
+
+ out <- ls.rows |>
+ purrr::map(purrr::pluck, "ds") |>
+ dplyr::bind_rows()
+
+ ## Indices by row
+ col.i <- seq_len(nrow(masks)) |> purrr::map(\(.j){
+ which(masks[.j,])
+ })
+
+ col.i.vec <- purrr::list_c(col.i) |> unique()
+
+ if (purrr::compact(col.i) |> length() == 1){
+ # As this is only the case with overall column
+ # This should be reworked
+
+ # This was the approach, to just select the first
+ # which(purrr::map_lgl(col.i,is_empty))[1]
+
+ # This will select the cell with the second lowest number
+ col.i[[which(rank(ns,ties.method = "first")==2)]] <- c("")
+ }
+
+ out <- col.i |>
+ purrr::map(\(.y){
+ # length(.y)
+ if (length(.y) > 0) {
+ cols <- col.i.vec[!col.i.vec %in% .y]
+ if (length(cols)==0){
+ cols <- ""
+ } else {
+ cols
+ }
+ } else {
+ .y
+ }
+ }) |>
+ purrr::imap(\(.y, .i){
+ ds <- out[.i, ]
+ if (length(.y) > 0 & all(.y!="")) {
+ n <- ns[.i, .y] |>
+ purrr::map_dfr(plyr::round_any,accuracy = cut.off, f = ceiling)
+ N <- Ns[.y]
+ p <- round(100 * n / N, dec)
+ if (n==0) glue.mask <- "{n}"
+
+ ds[f1[.y]] <- glue::glue(glue.mask)|>
+ as.matrix() |>
+ t() |>
+ tibble::as_tibble(.name_repair = "unique_quiet")
+ ds
+ } else {
+ ds
+ }
+ }) |>
+ dplyr::bind_rows()
+
+ out <- rbind(
+ body |>
+ dplyr::filter(row_type=="label"),
+ out
+ )
+ }
+ }
+ out
+
+}
+
+
+summary_masks <- function(body,ls,cut.off=5,dec=dec){
+ seq_along(unique(body$variable)) |>
+ purrr::map(function(.x) {
+ variable_masks(index=.x,data=ls,cut.off=cut.off,dec=dec)
+ }) |>
+ dplyr::bind_rows()
+}
+
+mask_micro_summary <- function(data,micro.n=5){
+ data |>
+ gtsummary::modify_table_body(
+ ~ .x |> summary_masks(ls=data,cut.off = micro.n,dec=1)
+ )
+}
+
+#' Title
+#'
+#' @param mask
+#' @param data
+#'
+#' @return
+#' @export
+#'
+#' @examples
+#' minimal_mask(mask=tibble::as_tibble(matrix(c(FALSE,FALSE,TRUE,TRUE),nrow=1),.name_repair="unique_quiet"),
+#' data=tibble::as_tibble(matrix(c(20,12,8,4),nrow=1),.name_repair="unique_quiet"),micro.n=5)
+minimal_mask <- function(mask,data,micro.n){
+ ## Function assumes monotonous data
+ ## Use with column_diffs() for risk tables
+
+ ## FUnction works in practice, but example doesn't??
+
+ out <- mask
+
+ for (i in seq_len(nrow(mask))){
+ if (i>1){
+ for (j in seq_len(ncol(mask))){
+ if(dplyr::pull(mask[i,j])){
+ n <- max(which(which(!out[i,])
+#' events_dataset(impute = FALSE) |>
+#' cox_regression(all.vars = FALSE) |>
+#' ggsurvfit::survfit2() |>
+#' ggsurvfit::tidy_survfit(times = c(0, 2, 4, 6, 8.5))|>
+#' tidyr::pivot_wider(id_cols = strata, names_from = time, values_from = cum.event)
+#' data |> mask_micro_table(col.sel=-strata)
+#' data.sel <- data |> dplyr::select(-strata)
+mask_micro_table <- function(data, micro.n = 5, down = TRUE, col.sel) {
+ data.sel <- data |>
+ dplyr::select({{ col.sel }})
+
+ ## List of the two selection matrices
+ masked <- list(
+ data.sel, # The actual data
+ data.sel |>
+ column_diffs(include.first = TRUE) # Row differences (incl first row)
+ ) |>
+ purrr::map(\(.y){ # For each element in the list, do colwise test
+ .y |>
+ purrr::map_dfr(\(.x) .x %in% 1:(micro.n-1))
+ }) |>
+ purrr::imap(\(.y,.i){ # apply minimal masking to last list object
+ if (.i==2){
+ .y |> minimal_mask(data = data.sel,micro.n=micro.n)
+ }else {
+ .y
+ }
+ }) |>
+ purrr::reduce(`|`) |> # Combine matrices
+ tibble::as_tibble() |> # To tibble
+ purrr::map2(data.sel, \(.x, .y){ # Apply masking based on combined selection
+ ifelse(.x, rounded_interval(.y, round = micro.n, down = down), .y)
+ }) |>
+ dplyr::bind_cols()
+
+ ## Bind masked data to original columns
+ dplyr::bind_cols(
+ data |>
+ dplyr::select(-{{ col.sel }}),
+ masked|>
+ # Converts new to character for uniform data
+ dplyr::mutate(dplyr::across(dplyr::everything(), ~ as.character(.x)))
+ ) |>
+ dplyr::select(colnames(data)) # Order columns as original input data
+}
+
+rounded_interval <- function(data, round = 5, down = TRUE) {
+ # Handle "ties"
+ sub <- ifelse(down, -1, 1)
+ data <- ifelse(data %% round == 0 & data != 0, data + 1, data)
+
+ c(floor, ceiling) |>
+ purrr::map(\(.x) {
+ plyr::round_any(x = data, accuracy = round, f = .x)
+ }) |>
+ dplyr::bind_cols(.name_repair = "unique_quiet") |>
+ setNames(c("l", "h")) |>
+ dplyr::transmute(mask = glue::glue("{l}-{h}")) |>
+ dplyr::pull(mask)
+}
+
+column_diffs <- function(data, prefix.pattern = NULL, include.first = TRUE, suffix.out = "_diff") {
+ if (!is.null(prefix.pattern)) {
+ data <- data |>
+ dplyr::select(tidyselect::starts_with(prefix.pattern))
+ }
+
+ index <- seq_along(data)[-1]
+
+ diff <- index |>
+ purrr::map(\(.y){
+ abs(data[.y - 1] - data[.y])
+ }) |>
+ dplyr::bind_cols() |>
+ (\(.x) setNames(.x, paste0(names(.x), suffix.out)))()
+
+ if (include.first) {
+ out <- dplyr::bind_cols(data[1], diff)
+ } else {
+ out <- diff
+ }
+ out
+}
+
diff --git a/2 Longterm/DDV 240607/pa_event_plots.docx b/2 Longterm/DDV 240607/pa_event_plots.docx
new file mode 100755
index 0000000..eb30565
Binary files /dev/null and b/2 Longterm/DDV 240607/pa_event_plots.docx differ
diff --git a/2 Longterm/DDV 240607/pa_events_analyses.docx b/2 Longterm/DDV 240607/pa_events_analyses.docx
new file mode 100755
index 0000000..25cda12
Binary files /dev/null and b/2 Longterm/DDV 240607/pa_events_analyses.docx differ
diff --git a/2 Longterm/DDV 240607/pa_events_summaries.docx b/2 Longterm/DDV 240607/pa_events_summaries.docx
new file mode 100755
index 0000000..a97635a
Binary files /dev/null and b/2 Longterm/DDV 240607/pa_events_summaries.docx differ
diff --git a/2 Longterm/DDV 240607/smooth_surv.png b/2 Longterm/DDV 240607/smooth_surv.png
new file mode 100755
index 0000000..5574760
Binary files /dev/null and b/2 Longterm/DDV 240607/smooth_surv.png differ
diff --git a/2 Longterm/DDV 240607/smooth_surv_tables.png b/2 Longterm/DDV 240607/smooth_surv_tables.png
new file mode 100755
index 0000000..8c0a8f8
Binary files /dev/null and b/2 Longterm/DDV 240607/smooth_surv_tables.png differ
diff --git a/2 Longterm/DDV 240607/~$_events_summaries.docx b/2 Longterm/DDV 240607/~$_events_summaries.docx
new file mode 100644
index 0000000..b367b80
Binary files /dev/null and b/2 Longterm/DDV 240607/~$_events_summaries.docx differ
diff --git a/2 Longterm/DDV 240814/pa_events_analyses.docx b/2 Longterm/DDV 240814/pa_events_analyses.docx
new file mode 100755
index 0000000..209dd15
Binary files /dev/null and b/2 Longterm/DDV 240814/pa_events_analyses.docx differ
diff --git a/2 Longterm/DDV 240814/pa_events_summaries.docx b/2 Longterm/DDV 240814/pa_events_summaries.docx
new file mode 100755
index 0000000..85593d5
Binary files /dev/null and b/2 Longterm/DDV 240814/pa_events_summaries.docx differ
diff --git a/2 Longterm/DDV 240814/smooth_surv.png b/2 Longterm/DDV 240814/smooth_surv.png
new file mode 100755
index 0000000..a64be8d
Binary files /dev/null and b/2 Longterm/DDV 240814/smooth_surv.png differ
diff --git a/2 Longterm/DDV 240814/smooth_surv_tables.png b/2 Longterm/DDV 240814/smooth_surv_tables.png
new file mode 100755
index 0000000..71f85cc
Binary files /dev/null and b/2 Longterm/DDV 240814/smooth_surv_tables.png differ
diff --git a/2 Longterm/DDV 241031/event_sankey_data.csv b/2 Longterm/DDV 241031/event_sankey_data.csv
new file mode 100755
index 0000000..3b2d07d
--- /dev/null
+++ b/2 Longterm/DDV 241031/event_sankey_data.csv
@@ -0,0 +1,17 @@
+pase_0_quartile,pase_4_quartile,n
+1,1,56
+1,2,35
+1,3,14
+1,4,7
+2,1,38
+2,2,41
+2,3,22
+2,4,22
+3,1,15
+3,2,29
+3,3,46
+3,4,39
+4,1,10
+4,2,16
+4,3,34
+4,4,74
diff --git a/2 Longterm/DDV 241031/pa_events_analyses.docx b/2 Longterm/DDV 241031/pa_events_analyses.docx
new file mode 100755
index 0000000..ea23e5a
Binary files /dev/null and b/2 Longterm/DDV 241031/pa_events_analyses.docx differ
diff --git a/2 Longterm/DDV 241031/pa_events_summaries.docx b/2 Longterm/DDV 241031/pa_events_summaries.docx
new file mode 100755
index 0000000..bc648b6
Binary files /dev/null and b/2 Longterm/DDV 241031/pa_events_summaries.docx differ
diff --git a/2 Longterm/DDV 241031/sens_cox.docx b/2 Longterm/DDV 241031/sens_cox.docx
new file mode 100755
index 0000000..eea5cb5
Binary files /dev/null and b/2 Longterm/DDV 241031/sens_cox.docx differ
diff --git a/2 Longterm/DDV 241106/pase_extra_cox.docx b/2 Longterm/DDV 241106/pase_extra_cox.docx
new file mode 100644
index 0000000..036c3e7
Binary files /dev/null and b/2 Longterm/DDV 241106/pase_extra_cox.docx differ
diff --git a/2 Longterm/DDV 241212/coll_mrs0_0.docx b/2 Longterm/DDV 241212/coll_mrs0_0.docx
new file mode 100755
index 0000000..8581d12
Binary files /dev/null and b/2 Longterm/DDV 241212/coll_mrs0_0.docx differ
diff --git a/2 Longterm/DDV 241212/coll_pase_change.docx b/2 Longterm/DDV 241212/coll_pase_change.docx
new file mode 100755
index 0000000..6c8d11d
Binary files /dev/null and b/2 Longterm/DDV 241212/coll_pase_change.docx differ
diff --git a/2 Longterm/DDV 241212/coll_pase_change_mrs0.docx b/2 Longterm/DDV 241212/coll_pase_change_mrs0.docx
new file mode 100755
index 0000000..e27fed9
Binary files /dev/null and b/2 Longterm/DDV 241212/coll_pase_change_mrs0.docx differ
diff --git a/2 Longterm/DDV 241212/coll_prestroke_pase.docx b/2 Longterm/DDV 241212/coll_prestroke_pase.docx
new file mode 100755
index 0000000..d87a394
Binary files /dev/null and b/2 Longterm/DDV 241212/coll_prestroke_pase.docx differ
diff --git a/2 Longterm/DDV 241212/mrs_sensitivity.docx b/2 Longterm/DDV 241212/mrs_sensitivity.docx
new file mode 100755
index 0000000..9bb0ec9
Binary files /dev/null and b/2 Longterm/DDV 241212/mrs_sensitivity.docx differ
diff --git a/2 Longterm/Project B - DAG.Rmd b/2 Longterm/Project B - DAG.Rmd
new file mode 100644
index 0000000..d56a5ed
--- /dev/null
+++ b/2 Longterm/Project B - DAG.Rmd
@@ -0,0 +1,114 @@
+---
+title: "Project B - DAG"
+author: "AGDamsbo"
+date: "`r Sys.Date()`"
+output: html_document
+---
+
+```{r setup, include=FALSE}
+knitr::opts_chunk$set(echo = TRUE)
+```
+
+# Hypothesis
+
+```{r}
+labels_all<-list(rtreat~"Trial treatment",
+ pase_0~"PASE score",
+ age~"Age",
+ sex~"Sex",
+ smoker~"History of smoking",
+ civil~"Cohabitation",
+ diabetes~"Known diabetes",
+ hypertension~"Known hypertension",
+ afli~"Known Atrialfibrillation",
+ ami~"Previos myocardial infarction",
+ tci~"Previos TIA",
+ pad~"Known peripheral artery disease",
+ nihss_0~"Acute NIHSS score",
+ thrombolysis~"Thrombolytic therapy",
+ thrombechtomy~"Endovascular treatment",
+ SES~"Socio economic status",
+ education~"Education",
+ ad_treat~"Anti depression treatment",
+ vasc_event~"Vascular event")
+```
+
+```{r}
+vars <- c(
+ "pase_0",
+ "age",
+ "sex",
+ "civil",
+ "smoker",
+ "rtreat",
+ "alc",
+ "afli",
+ "hypertension",
+ "diabetes",
+ "mrs_0",
+ "nihss_c",
+ "thrombolysis",
+ "pad",
+ "thrombechtomy",
+ "ami",
+ "tci",
+ "compliant",
+ "SES",
+ "education"
+)
+```
+
+```{r}
+library(ggdag)
+library(ggplot2)
+```
+
+```{r}
+
+dag <-
+ dagify(
+ vasc_event ~ pase_0 + age + sex + civil + smoker + rtreat + alc + afli +
+ hypertension + diabetes + mrs_0 + nihss_0 + thrombolysis + pad + thrombechtomy +
+ ami + tci + SES + education + ad_treat + svd,
+ pase_0 ~ sex + civil + alc + pad + SES + education + hypertension + diabetes,
+ diabetes ~ civil,
+ svd~hypertension + diabetes + alc,
+ mrs_0 ~ tci + ami + hypertension + diabetes + svd,
+ age ~ smoker+SES+education,
+ civil ~ sex + age + SES + civil,
+ # smoker~ ,
+ alc ~ sex+SES+education,
+ # afli~ ,
+ hypertension~ alc,
+ nihss_0 ~ hypertension + diabetes + pase_0 + age,
+ thrombolysis ~ mrs_0+nihss_0,
+ # pad~ ,
+ thrombechtomy ~ mrs_0+nihss_0,
+ # ami~ ,
+ # tci~ ,
+ # compliant~ ,
+ # SES~ ,
+ # education,
+ ad_treat~education+SES,
+ # labels = labels_all,
+ latent = c("svd"),
+ exposure = "pase_0",
+ outcome = "vasc_event"
+ )
+```
+
+```{r}
+dag |> ggdag(text = TRUE) + theme_dag(6) + geom_dag_edges_arc()
+```
+
+```{r}
+dag |> ggdag_parents("svd")
+```
+
+```{r}
+dag |> ggdag_paths(text = TRUE, shadow = TRUE)
+```
+
+```{r}
+dag |> ggdag_adjustment_set(text = TRUE, shadow = TRUE,stylized = TRUE)
+```
diff --git a/2 Longterm/Project-B---DAG.html b/2 Longterm/Project-B---DAG.html
new file mode 100644
index 0000000..f151150
--- /dev/null
+++ b/2 Longterm/Project-B---DAG.html
@@ -0,0 +1,496 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Project B - DAG
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Hypothesis
+
labels_all<-list(rtreat~"Trial treatment",
+ pase_0~"PASE score",
+ age~"Age",
+ sex~"Sex",
+ smoker~"History of smoking",
+ civil~"Cohabitation",
+ diabetes~"Known diabetes",
+ hypertension~"Known hypertension",
+ afli~"Known Atrialfibrillation",
+ ami~"Previos myocardial infarction",
+ tci~"Previos TIA",
+ pad~"Known peripheral artery disease",
+ nihss_0~"Acute NIHSS score",
+ thrombolysis~"Thrombolytic therapy",
+ thrombechtomy~"Endovascular treatment",
+ SES~"Socio economic status",
+ education~"Education",
+ ad_treat~"Anti depression treatment",
+ vasc_event~"Vascular event")
+
vars <- c(
+ "pase_0",
+ "age",
+ "sex",
+ "civil",
+ "smoker",
+ "rtreat",
+ "alc",
+ "afli",
+ "hypertension",
+ "diabetes",
+ "mrs_0",
+ "nihss_c",
+ "thrombolysis",
+ "pad",
+ "thrombechtomy",
+ "ami",
+ "tci",
+ "compliant",
+ "SES",
+ "education"
+)
+
library(ggdag)
+
##
+## Attaching package: 'ggdag'
+
## The following object is masked from 'package:stats':
+##
+## filter
+
library(ggplot2)
+
dag <-
+ dagify(
+ vasc_event ~ pase_0 + age + sex + civil + smoker + rtreat + alc + afli +
+ hypertension + diabetes + mrs_0 + nihss_0 + thrombolysis + pad + thrombechtomy +
+ ami + tci + SES + education + ad_treat + svd,
+ pase_0 ~ sex + civil + alc + pad + SES + education + hypertension + diabetes,
+ diabetes ~ civil,
+ svd~hypertension + diabetes + alc,
+ mrs_0 ~ tci + ami + hypertension + diabetes + svd,
+ age ~ smoker+SES+education,
+ civil ~ sex + age + SES + civil,
+ # smoker~ ,
+ alc ~ sex+SES+education,
+ # afli~ ,
+ hypertension~ alc,
+ nihss_0 ~ hypertension + diabetes + pase_0 + age,
+ thrombolysis ~ mrs_0+nihss_0,
+ # pad~ ,
+ thrombechtomy ~ mrs_0+nihss_0,
+ # ami~ ,
+ # tci~ ,
+ # compliant~ ,
+ # SES~ ,
+ # education,
+ ad_treat~education+SES,
+ # labels = labels_all,
+ latent = c("svd"),
+ exposure = "pase_0",
+ outcome = "vasc_event"
+ )
+
dag |> ggdag(text = TRUE) + theme_dag(6) + geom_dag_edges_arc()
+
+
dag |> ggdag_parents("svd")
+
+
dag |> ggdag_paths(text = TRUE, shadow = TRUE)
+
+
dag |> ggdag_adjustment_set(text = TRUE, shadow = TRUE,stylized = TRUE)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/2 Longterm/assigndata.csv b/2 Longterm/assigndata.csv
new file mode 100644
index 0000000..2b7ace8
--- /dev/null
+++ b/2 Longterm/assigndata.csv
@@ -0,0 +1,643 @@
+"pase_0","age","sex","civil","smoke_ever","rtreat","alc","afli","hypertension","diabetes","mrs_0","nihss_c","thrombolysis","pad","thrombechtomy","ami","tci","pase_6","mrs_1","mfi_gen_1","mfi_phys_1","mfi_act_1","mfi_mot_1","mfi_men_1","mdi_1","who5_score_1"
+"356.44","76","male","partner","never","Placebo","guideline","no","yes","no","0","2","yes","no","no","yes","no","260.52","0","10","4","4","4","8","6","84"
+"277","49","male","partner","never","Placebo","guideline","no","no","no","0","4","no","no","no","no","no","113.11","2","12","15","5","6","11","11","64"
+"192.6","43","male","alone","never","Placebo","guideline","no","yes","yes","0","2","yes","no","no","no","no","123.05","4","12","17","7","4","4","3","76"
+"30","89","female","alone","ever","Placebo","guideline","yes","no","no","0","3","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"44.14","80","male","partner","ever","Active","guideline","no","no","no","2","4","no","no","no","no","no","115.15","3","16","20","17","10","6","11","64"
+"128.76","72","male","partner","never","Placebo","guideline","no","yes","no","0","1","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"224.84","71","female","partner","ever","Placebo","guideline","no","yes","no","0","1","no","no","no","no","no","198.08","1","8","8","12","7","9","1","80"
+"100","66","female","alone","never","Active","guideline","no","no","no","0","4","no","no","yes","no","no","32.36","4","17","16","12","12","15","14","52"
+"144.8","64","male","partner","never","Placebo","guideline","no","no","no","0","3","no","no","no","no","no","171.84","1","14","13","14","6","14","3","84"
+"136.8","64","male","partner","never","Placebo","guideline","no","yes","no","0","3","no","yes","no","no","no","9.7","2","10","17","18","9","15","7","36"
+"134.33","65","female","alone","ever","Placebo","guideline","no","yes","yes","0","2","no","no","no","no","no","178.97","2","10","10","6","4","4","4","80"
+"118.2","63","male","partner","never","Active","guideline","no","yes","no","0","9","yes","no","no","no","no","33.14","2","4","16","13","9","14","3","48"
+"99.28","62","male","partner","never","Active","more","no","yes","no","0","1","no","no","no","no","no","209.68","1","15","11","13","12","12","9","48"
+"101.3","73","male","partner","never","Placebo","more","no","no","no","1","16","yes","no","yes","no","no","34.6","1","14","15","15","12","8","12","0"
+"75.5","59","female","alone","never","Placebo","guideline","no","no","no","0","5","no","no","no","no","no","123.97","2","20","20","19","4","20","22","44"
+"81","73","male","partner","never","Active","guideline","no","yes","no","0","2","no","no","no","yes","no","184.6","1","16","15","19","10","9","10","44"
+"79.08","70","male","partner","never","Active","guideline","yes","no","no","0","5","yes","no","no","no","no","235.75","2","17","14","14",NA,NA,"9","60"
+"27.2","83","male","partner","never","Active","guideline","no","yes","no","0","3","no","no","no","no","no","81","0","6","7","8","6","4","3","68"
+"173.25","80","male","partner","ever","Active","guideline","no","yes","no","0","5","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"255.8","63","male","alone","never","Placebo","guideline","no","no","no","0","9","no","no","no","no","no","101.4","1","4","8","8","6","4","5","84"
+"27.2","82","male","alone","never","Active","guideline","no","yes","no","0","3","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"309.51","72","male","partner","ever","Placebo","guideline","yes","no","no","1","11","yes","no","no","no","no","486.35","2","11","4","11","6","15","2","80"
+"199.91","58","female","alone","ever","Active","guideline","no","yes","no","0","0","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"218.09","64","male","partner","ever","Active","guideline","no","no","no","0","2","no","no","no","no","no","117.25","0","4","4","5","6","5","1","92"
+"166.8","49","female","partner","ever","Placebo","guideline","no","no","no","0","5","no","no","no","no","no","183.58","0","5","8","9","7","7","6","76"
+"25","99","female","alone","ever","Placebo","guideline","yes","no","no","0","8","yes","no","no","no","no","9.03","2","12","16","14","6","7","14","52"
+"90","79","female","alone","never","Placebo","guideline","no","yes","no","0","2","yes","no","no","yes","yes","116.4","0","16","4","8","4","12","11","96"
+"232.91","60","male","partner","never","Active","guideline","no","yes","no","0","5","no","no","no","no","no","228.25","2","12","12","12","10","9","9","72"
+"208.24","51","male","alone","never","Placebo","guideline","no","no","no","0","10","no","no","no","no","no","98.35","2","12","11","10","11","6","4","76"
+"28.11","77","male","alone","never","Placebo",NA,"yes","yes","no","0","9","no","no","no","no","no","8.6","4","10","14","16","10","9","14","52"
+"116","54","female","partner","never","Active","guideline","no","yes","no","0","6","no","no","no","no","no","111.28","0",NA,NA,NA,NA,NA,NA,"0"
+"271.5","71","female","partner","ever","Placebo","guideline","no","yes","no","0","16","yes","no","no","no","no","244.88","3","13","4","5","4","10","10","72"
+"155.8","67","female","alone","never","Placebo","more","no","yes","no","0","1","no","yes","no","no","no","187.4","0","6","10","9","4","4","0","100"
+"96.4","31","male","alone","never","Active","guideline","no","no","no","0","5","no","no","no","no","no","81.32","1","4","6","7","6","9","5","92"
+"88.99","72","female","partner","never","Active","guideline","yes","yes","no","1","5","no","no","no","no","no","106.65","1","11","13","14","4","4","8","64"
+"78.92","71","female","partner","never","Active","guideline","no","no","no","1","15","yes","no","no","no","no","152.73","0","4","6","6","7","6","4","80"
+"98.68","75","female","partner","ever","Active","guideline","no","no","no","0","4","no","no","no","no","no","60.83","2","9","11","10","14","6","3","84"
+"183.3","78","male","partner","never","Active","guideline","no","no","no","0","2","no","no","no","no","no","220.04","1","12","7","9","6","4","1","76"
+"192.5","74","male","partner","never","Active","guideline","no","no","no","0","3","yes","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"218.05","62","female","partner","ever","Placebo","guideline","no","yes","no","1","3","yes","no","no","no","no","185.18","1","11","13","11","13","11","6","64"
+"144.7","86","male","partner","ever","Active","guideline","no","yes","no","0","2","yes","no","no","no","no","130.37","1","5","6","9","9","5","5","84"
+"85","82","male","partner","never","Active","guideline","no","yes","no","0","3","yes","no","no","no","no","62.8","0","20","19","19","16","9","18","48"
+"168.87","60","female","partner","never","Active","guideline","no","yes","no","0","0","no","no","no","no","no","230.14","2","15","16","11","6","12","14","40"
+"115.56","63","female","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","168.73","2","13","15","12","13","9","12","60"
+"126","53","male","partner","never","Placebo","guideline","no","no","no","0","3","yes","no","no","no","no","136","1","17","8","8",NA,"14","6","92"
+"58.53","86","female","alone","never","Active","guideline","no","yes","no","0","0","no","no","no","no","no","246.47","0","14","14","13","7","9","4","52"
+"75.8","75","male","partner","never","Placebo","guideline","yes","no","yes","0","2","yes","no","no","no","no","108.2","2","11","13","16","10","7","14","64"
+"133.01","70","female","alone","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","228.24","2","7","8","4","4","4","3","88"
+"114.93","63","male","partner","never","Placebo","guideline","no","no","yes","0","3","no","no","no","no","no","188.05","2","18","18","12","6","12","5","72"
+"243.33","57","male","alone","never","Placebo",NA,"no","no","no","0","6","no","no","yes","no","no","200.09","3","7","5","6","4","10","5","8"
+"218.89","77","male","alone","ever","Placebo","guideline","no","no","no","0","3","no","no","no","no","no","32.09","1","5","13","16","11","5","11","88"
+"116.05","76","female","alone","ever","Active","guideline","no","no","no","0","7","no","no","no","no","no","66.52","4","8","9","4","5","5","6","88"
+"126.31","65","male","partner","never","Active","guideline","yes","yes","no","0","2","yes","no","no","no","no","259.37",NA,NA,NA,NA,NA,NA,NA,"0"
+NA,"82","female","alone","ever","Placebo","guideline","yes","no","no","1","16","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"81.72","77","male","partner","never","Active","more","yes","yes","no","1","1","no","yes","no","no","no","35.91","2",NA,NA,NA,NA,NA,NA,NA
+"155.83","63","female","alone","never","Placebo","guideline","no","no","no","0","0","no","no","no","yes","no","221.5","0","10","8","9","7","4","5","56"
+"136","55","male","alone","never","Placebo","guideline","no","no","no","0","7","yes","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"247.12","53","female","partner","never","Placebo","guideline","no","no","no","0","8","yes","no","no","no","no","203.62","1","17","10","15","6","4","6","60"
+NA,"73","male","alone","never","Active","guideline","no","no","no","0","7","no","no","no","no","no","42.63","3","20","20","16","8","8","29","4"
+"33.6","62","female","alone","never","Active","guideline","no","no","no","1","8","no","no","no","no","no","192.4",NA,NA,NA,NA,NA,NA,NA,NA
+"296","60","male","partner","never","Active","guideline","no","no","no","0","12","no","no","no","no","no","112.82","4","8","12","15","4","4","3","92"
+"59.2","87","female","alone","never","Active","guideline","yes","yes","no","2","4","no","no","no","no","no","99.89","2","14","17","20","10","4","12","72"
+"214.48","74","male","alone","never","Placebo","guideline","no","no","yes","0","4","no","no","no","no","no","337.61","1","6","4","11","5","11","6","80"
+"418.9","54","female","alone","ever","Active","guideline","no","yes","yes","0","3","no","no","no","no","no","295.91","1","18","14","12",NA,"16","8","48"
+"114.5","69","male","partner","never","Placebo","guideline","no","yes","no","0","10","yes","no","no","yes","no","105.8","1","4","6","4","4","8","1","88"
+"56","67","male","partner","never","Active","guideline","no","no","no","0","4","yes","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"292.24","63","male","partner","ever","Active","guideline","no","no","no","0","2","yes","no","no","yes","no","52.5","3","4","8","8","4","4","4","96"
+"155.83","45","male","partner","ever","Active","guideline","no","yes","no","0","4","no","no","no","no","no","335.69","1","9","7","9","8","4","3","92"
+"106","78","male","alone","never","Active","guideline","no","no","no","0","4","no","no","no","no","no",NA,"1","4","5","5","5","8","3","96"
+"114.6","52","male","partner","never","Active","guideline","no","yes","no","0","2","yes","no","no","yes","no","31.4","1","19","13","11","8",NA,"22","44"
+"0","86","female","alone","never","Placebo","guideline","no","no","no",NA,"2","yes","no","no","no","no","35","3","4","20","16","8","4","0","88"
+"55","67","male","partner","never","Active","guideline","no","yes","no","0","7","no","yes","no","no",NA,"3.3","2","10","7","14","10","5","2","88"
+"0","76","male","partner","never","Active","guideline","no","yes","no","0","3","yes","no","no","yes","no",NA,"1","16","19","17","18","4","15","44"
+"158.5","67","male","partner","ever","Active","guideline","no","yes","no","0","16","yes","no","no","no","no","222.07","1","14","8","5","4","16","4","80"
+"246.85","70","male","partner","ever","Placebo","guideline","no","yes","no","0","4","no","no","no","no",NA,"0","1","10","11","8","4","10","10","72"
+"196","81","male","alone","never","Placebo","guideline","no","no","no","0","2","yes","no","no","no","no","33.6","3","4","4","11","4","11","5","88"
+"249.9","62","male","partner","ever","Active","guideline","no","yes","no","0","1","yes","no","no","no","yes",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"61","64","male","partner","never","Active","guideline","no","yes","no","0","3","no","no","no","no","no","35.4","3","17","18","18","4","4","10","72"
+"0","60","male","alone","ever","Active","guideline","no","yes","no","2","3","no","no","no","no","no",NA,"4",NA,NA,NA,NA,NA,"16","52"
+"156.21","68","male","partner","never","Active","guideline","no","no","no","0","2","no","no","no","no","no","158.5","1","12","14","10","5","12","12","72"
+"200.76","69","male","partner","never","Active","guideline","no","yes","no","0","3","yes","no","no","no","no","231.5","0","5","6","9","9","6","12","76"
+"270.6","63","male","partner","never","Placebo","guideline","no","yes","no","0","3","no","no","no","no","no","86.11","3","11","13","11","8","14","9","76"
+"268.72","45","male","alone",NA,"Active","guideline","no","no","no","0","0","no","no","no","no","no","245.77","1","13","10","7","4","5","2","72"
+"215.8","64","male","partner","ever","Placebo","guideline","no","no","no","0","6","yes","no","no","no","no","250.3","1","13","12","15","9","6","5","60"
+"187.4","51","female","partner","ever","Active","more","no","yes","no","0","4","no","no","no","no","no","140.61","2","16","13","12","6","6","5","80"
+"66.04","77","female","alone","ever","Active","guideline","no","no","no","0","2","yes","no","no","no","no","50","0","7","4","4","4","6","2","100"
+"53.97","83","male","partner","never","Placebo","guideline","no","yes","no","0","1","no","no","no","no","no","66.5","2","10","17","18","10","4","4","72"
+"133.8","63","male","partner",NA,"Placebo",NA,"no","yes","yes","0","2","no","no","no","no","no","111","1","8","10","11","8","5","0","80"
+"54.51","71","male","alone","never","Placebo","guideline","no","yes","yes","0","5","no","no","no","no","no","50.02","1","11","13","12","13","11","6","60"
+"327.72","57","male","alone","never","Active","more","no","no","no","0","0","yes","no","no","no","no","206.05","1","16","17","9","5","15","24","44"
+"198.89","81","male","partner","ever","Active","guideline","no","yes","no","1","7","yes","no","no","no","no","164.51","1","10","6","5","5","8","5","80"
+"138.2","76","male","alone","ever","Placebo","guideline","yes","yes","no","1","6","no","no","no","no","no","185.92","2","10","11","4","7","9","2","100"
+"91.9","74","male","alone","never","Placebo","guideline","no","yes","no","0","8","yes","yes","no","no","no",NA,"6","8","9","14","5","4","2","80"
+"68.6","54","female","partner","never","Placebo","guideline","no","no","no","1","1","no","no","no","no","no","117.2","1","14","12","14","12","11","5","68"
+"137","44","male","partner","ever","Placebo","guideline","no","no","no","0","1","yes","no","no","no","no","255.14","0","8","14","16","10","8","5","72"
+"214.2","64","male","partner","never","Active","guideline","no","no","no","0","17","yes","no","yes","no","no","176.57","2","11","14",NA,"9","11","20","40"
+"85.8","52","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","211","2","15","11","8","4","12","10","64"
+"216.47","48","female","partner","never","Placebo","guideline","no","yes","no","0","0","no","no","no","no","no","256.12","1","10","16","13","8","4","5","76"
+"207.53","85","male","partner","never","Placebo","guideline","yes","yes","no","0","6","yes","no","no","no","no","136","3","9","13","7","6","6","4","80"
+"27.2","61","male","alone","never","Placebo","guideline","no","yes","no","0","2","yes","no","no","no","no","65","1","13","17","15","4","6","1","68"
+"189.71","49","female","alone","never","Active","guideline","no","yes","no","0","0","no","no","no","no","no","52.2","2","20","16","16","7","18","18","24"
+"197","63","male","alone","ever","Active","guideline","no","no","no","0","2","no","no","no","no","no","231.73","2","15","7","11","10","11","11","52"
+"116","70","male","partner","never","Active","more","no","no","no","0","4","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"157.4","64","male","partner","ever","Active","guideline","no","yes","no","0","0","no","no","no","no","no","205","2","16","11","12","4","4","9","80"
+"88.2","63","male","partner","never","Placebo","guideline","no","no","no","1","28","yes","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"50","85","female","alone","never","Active","guideline","yes","no","no","0","27","yes","no","no","no","no",NA,"6",NA,NA,NA,NA,NA,NA,NA
+"114.6","83","male","alone","ever","Active","guideline","no","no","yes","0","7","no","no","no","yes","no","106.8","1","8","6","8","8","4","4","80"
+"148.96","75","female","partner","never","Placebo","guideline","no","yes","no","0","1","yes","no","no","no","no","95.8","1","14","8","11","10","16","9","52"
+"100","72","male","partner","never","Active","guideline","no","yes","no","0","4","yes","no","yes","no","no","52.53","3","4","6","9","13","8","6","92"
+"195.92","64","female","alone","ever","Placebo","guideline","no","no","no","0","2","yes","no","no","no","no","158.51","1","6","7","7","4","6","5","80"
+"180.22","69","male","partner","never","Placebo","guideline","yes","no","no","0","5","yes","no","no","no","no","190","1","4","8","5","4","4","0","100"
+"116.12","65","male","partner","never","Active","guideline","no","yes","no","0","17","yes","no","yes","no","no","199.16","2","16","14","19","7","8","9","68"
+NA,"73","male","alone","never","Placebo","guideline","no","yes","yes",NA,NA,"no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"22.2","66","male","partner","ever","Active","guideline","yes","yes","yes","1","4","no","no","no","no","no","64.11","3","14","14","6","8","10","8","84"
+"29.73","79","male","alone","never","Active","guideline","no","yes","no","0","1","no","no","no","no","no","31.4","1","16","6","8","8","4","4","48"
+"216.86","69","male","partner","ever","Active","guideline","yes","no","no","1","6","yes","no","yes","no","no","252.43","1","6","4","4","5","4","3","76"
+"226.8","55","male","partner","never","Active","guideline","no","no","yes","0","0","no","no","no","no","no","142.4","1","10","12","15","8","8","6","92"
+"166","81","male","alone","never","Active","more","no","no","no","0","3","yes","no","no","no","yes","79.7","4","4","9","10","4","5","5","92"
+"131.8","69","male","alone","never","Placebo","guideline","no","yes","no","0","16","yes","no","yes","no","no","9.03","4","17","17","16","8","12","5","100"
+"161.5","53","female","partner","ever","Placebo","guideline","yes","no","no","0","2","no","no","no","no","no","302.77","0","16","10","7","4","6","8","80"
+"256","74","male","partner","ever","Active","guideline","yes","yes","no","0","0","no","no","no","no","no","311.8","1","4","8","6","6","8","1","100"
+"238.6","62","male","partner","ever","Active","more","no","no","no","0","12","yes","no","no","no","no","288.93","1","12","14","13","6","6","7","64"
+"252.8","51","male","partner","never","Placebo","guideline","no","no","no","0","5","yes","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"84.6","45","male","partner","never","Placebo","guideline","no","yes","yes","0","3","no","no","no","no","no","73.61","2","16","17","17","12","10","14","60"
+"341.4","54","male","partner","never","Placebo","more","no","no","no","0","3","no","no","no","no","no",NA,"0","20","14","17","11","12","29","16"
+"117.8","87","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","131.8","2","11","9","13","7","4","4","72"
+"113.21","79","female","partner","ever","Active","more","no","no","no","0","5","yes","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"82.36","69","male",NA,"never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","254.51","0","12","6","9","8","8","2","76"
+"30","62","male","partner","never","Placebo","more","no","no","no","0","2","yes","no","no","no","yes","95","2","10","14","11","9","7","13","60"
+"241.3","45","male","partner","ever","Placebo","guideline","no","no","no","0","32","yes","no","yes","no","no","315.97","2","11","7","8","4","7","14","80"
+"137.4","83","female","partner","ever","Active","guideline","no","no","no","1","4","no","no","no","no","no","155.01","3","13",NA,"9","7",NA,NA,"52"
+"260.5","50","male","partner","ever","Active","guideline","no","no","no","0","4","no","no","no","no","no","238.05","1","11","7","11","10","6","2","76"
+"289","63","male","partner","never","Placebo","more","yes","no","no","0","6","yes","no","no","no","no","253.4","1","14","17","15","9","14","10","64"
+"30","77","female","partner","ever","Active","guideline","no","no","no",NA,"7","no","no","no","no","no","31.72","4","15","20","16","4","4","9","76"
+"25","77","male","alone","never","Active","guideline","yes","yes","yes","2","2","no","no","no","no","no","0","2","8","11","13","12","17","6","92"
+"130.56","37","female","alone","ever","Placebo","guideline","no","no","no","0","1","no","no","no","no","no","288.72","1","16","14","10","8","10","13","32"
+"59.8","81","male","alone","never","Active","more","no","yes","no","0","2","no","no","no","no","no","154.84","1","4","6","6","6","4","0","100"
+"117.13","71","male","partner","ever","Active","guideline","no","yes","no","0","3","yes","no","no","no","no","89.6","2","12","12","10","4","8","1","100"
+"286.47","50","male","partner","never","Active","guideline","no","no","no","0","3","yes","no","no","no","no","306.55","1","12","9","16","11","10","5","56"
+"117.63","72","female","partner","ever","Active","guideline","no","yes","no","1","4","yes","no","no","no","yes","191.4","1","9","8","8","4","4","3","68"
+"27.2","80","female","alone","never","Active","guideline","no","no","no","1","14","no","no","no","no","no","4.84","4","20","19","20","4","4","14","64"
+"211.4","51","male","partner","ever","Active","guideline","no","no","no","0","1","yes","no","no","no","no","288.4","2","14","19","18","8","13","11","52"
+"100","73","female","partner","ever","Active","guideline","no","yes","no","0","3","no","no","no","no","no","102.89","2","15","16","20","12",NA,"19","56"
+"299.19","52","male","partner","ever","Placebo","guideline","no","yes","no","1","7","yes","no","no","no","no","149.05","1","11","10","14","11","8","7","64"
+"75.8","64","male","partner","never","Placebo","more","no","no","no","0","4","no","no","no","no","no","224.62","1","8","4","4","5","8","10","88"
+"25","77","male","partner","never","Active","more","no","yes","no","2","6","no","yes","no","no","no","116.59","3","13","15","9","11","13","16","60"
+"90","58","male","alone","never","Active","guideline","yes","yes","yes","0","0","no","no","no","no","no","55","1","15","18","12","10","9","13","60"
+"147.13","74","male","partner","never","Placebo","more","no","yes","no","0","5","no","no","no","no","no","135.1","2","15","14","11","7","4","5","72"
+"131.8","69","male","partner","never","Placebo","guideline","yes","no","no","2","3","no","no","no","no","no","167.45","2","5","12","10","5","4","1","92"
+"104.16","65","female","partner","ever","Placebo","guideline","yes","yes","no","0","12","yes","no","yes","yes","no","156.58","1","18","14","20","14","4","16","44"
+"54.51","85","male","partner","never","Placebo","more","no","yes","yes","0","2","no","no","no","no","no",NA,"2","20","16","19","20","17","14","16"
+"50","81","male","alone","never","Placebo","guideline","no","no","no","0","2","no","no","no","no","no","115.43","1","14","14","13","11","5","6","72"
+"297.4","71","male","partner","never","Active","guideline","no","no","no","1","5","no","no","no","no","no","149.4","2","9","15","9","6","12","5","88"
+"131.8","67","male","partner","never","Placebo","guideline","no","yes","yes","0","5","yes","no","no","no","no","244.23","0","10","5","6","4","11","2","84"
+"190","61","male","alone","ever","Placebo","guideline","no","no","no","0","2","no","no","no","no","no","230.37","1","10","8","12","8","11","3","88"
+"191.81","58","male","alone","never","Active","more","no","no","no","0","1","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"248.3","52","male","alone","never","Active","guideline","no","no","no","0","1","no","no","no","no","no","161.8","1","14","9","10","7","11","6","64"
+"348.97","49","male","partner","ever","Placebo","guideline","no","no","no","1","1","yes","no","no","no","no","255.66","0","7","4","6","5","5","3","80"
+"252","60","male","partner","ever","Active","guideline","no","yes","no","0","1","no","no","no","no","no","226.08","2","14","9","8","9","14","4","68"
+"85","67","male","partner","never","Placebo","guideline","no","yes","no","0","2","yes","no","no","no","no","225.11","1","4","5","7","7","6","0","92"
+"161","49","male","partner","never","Placebo","guideline","no","no","no","0","2","no","no","no","no","no","259.5","1","5","10","4","4","5","6","84"
+"87.47","45","male","partner","never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","167.07","1","4","7","5","5","4","3","96"
+"167.8","83","male","partner","never","Active","guideline","yes","yes","no","0","5","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"86.72","72","female","partner","ever","Active","guideline","no","no","no","0","2","no","no","no","no","no","109.25","1","10","6","8","9","8","3","64"
+"116.75","67","male","alone","never","Placebo","guideline","no","yes","yes","0","4","no","no","no","yes","no","62.36","3","17","18","20","16","8","15","52"
+"183.91","78","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","72.91","1","5","5","5","4","5","0","92"
+"269.28","63","male","partner","never","Placebo","guideline","no","yes","no","0","13","yes","no","no","no","no","184.72","0","6","6","6","5","7","12","72"
+"215.8","51","female","partner","ever","Active","guideline","yes","no","no","0","2","no","no","no","no","no",NA,"2","17","16","15","15","9","20","48"
+"91","72","female","partner","never","Active","guideline","no","no","no","1","7","yes","no","no","no","no","76.4","0","10","6","10","4","12","3","88"
+"221","44","female","alone","never","Active","guideline","no","no","yes","0","3","yes","no","no","no","no","146","2","18",NA,"16","9",NA,"17","44"
+"49.73","66","female","partner","never","Placebo","more","yes","no","no","0","18","yes","no","yes","no","no","87.09","2","12","9","19","8","8","13","80"
+"184.6","48","female","partner","never","Active","guideline","no","no","no","0","5","yes","no","yes","no","no","146.66","1","14","20","13","8","8","19","60"
+"64.35","76","female","partner","never","Active","guideline","yes","yes","no","2","17","yes","no","yes","no","no","71.48","2","18","18","17","11","6","20","48"
+"132.32","76","female","alone","ever","Active","guideline","no","yes","no","0","3","no","no","no","no","no","70.93","0","9","7","7","4","4","1","88"
+"190.67","54","female","partner","never","Placebo","guideline","no","yes","no","0","4","no","no","no","no","no","243.56","1","12","9","9","5","4","5","56"
+"58.6","83","female","partner","ever","Active","guideline","no","yes","no","0","10","yes","no","no","no","no","19.45","4","11","17","16","4","4","7","88"
+"316.76","44","male","partner","never","Placebo","guideline","no","yes","no","0","4","no","no","no","no","no","281.83","1","4","4","7","4","4","1","100"
+NA,"84","female","partner","ever","Active","guideline","no","yes","yes","0","2","no","no","no","no","no","58.6","2","12","16","20","8","7","7","80"
+"147.1","37","male","partner","ever","Active","guideline","no","no","no","0","2","yes","no","no","no","no","227.83","1","14","9","9","11","12","9","72"
+"132.4","69","male","partner","never","Active","guideline","no","yes","no","0","4","no","no","no","no","no","88.3","1","11","16",NA,"6","12","18","68"
+"192.4","81","male","partner","never","Placebo","guideline","no","no","no","1","3","no","no","no","no","no","108.34","0","10","12","6","5","5","1","92"
+"237.2","80","male","partner","never","Placebo","guideline","no","no","no","0","2","no","no","no","no","no","322.4","1","7","5","4","4","10","4","84"
+"85","75","female","alone","never","Placebo","guideline","no","yes","no","0","7","no","no","no","no","no","60.91","2","14","7","4","4","4","12","88"
+"106.93","84","male","partner","never","Active","more","yes","no","no","0","3","no","no","no","no","no","207.86","2","12","20","4","4","16","5","76"
+"221","57","female","alone","never","Placebo","guideline","no","yes","no","0","11","yes","no","no","yes","no","205.72","3","18","13","6","14","13","7","28"
+"25.8","48","male","partner","ever","Active","guideline","no","no","no","0","1","no","no","no","no","no","281.41","0","9","9","11","6","8","3","68"
+"30","87","female","alone","never","Active","guideline","no","yes","no","1","2","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"179.73","57","female","partner","never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","240.38","1","17","14","16","13","4","15","36"
+"293.12","46","male","partner","ever","Placebo","guideline","yes","no","yes","0","1","yes","no","no","no","no","335.46","1","8","14","10","8","9","7","72"
+"60","65","female","partner","ever","Active","guideline","no","yes","no","0","4","no","no","no","no","no","98.31","1","12","12","14","12","11","5","72"
+"88.77","61","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","243.98","2","10","15","10","5","12","12","84"
+"202.72","45","female","partner","ever","Placebo","guideline","no","no","no","0","1","yes","no","no","no","no","248.13","1","9","4","4","4","7","5","88"
+"147.35","76","male","alone","never","Placebo","guideline","yes","yes","no","0","2","yes","yes","no","yes","no","245.8","2","10","8","9","4","4","13","80"
+"172.2","63","male","alone","never","Placebo","guideline","yes","no","no","0","19","no","no","no","no","no",NA,"6",NA,NA,NA,NA,NA,NA,NA
+"282.7","48","male","partner","ever","Active","guideline","no","no","no","0","18","yes","no","yes","no","no","67.27","3","20","5","14","8","15","14","20"
+"254.6","64","female","partner","never","Placebo","guideline","no","no","no","0","11","yes","no","no","no","no","125.38","4","11","6","5","4","4","1","96"
+"149.71","64","female","alone","never","Placebo","guideline","no","no","no","0","1","no","no","no","no","no",NA,"0","4","8","8","4","4","0","96"
+"141.8","60","male","alone","never","Active","guideline","no","no","yes","1","6","no","no","no","no","no","118.06","4","7","10","4","4","4","2","100"
+"256","54","male","partner","never","Active","guideline","no","yes","no","0","5","yes","no","no","no","no","158.43","0","5","8","10","7","5","7","72"
+"163.55","68","male","partner","never","Active","guideline","yes","yes","no","0","6","no","no","no","yes","no","232.27","1","16","13","13","8","4","3","76"
+"40","66","female","partner","ever","Placebo","guideline","no","yes","no","0","4","yes","no","no","no","no","85","0","9","13","12","9","4","5","64"
+"37.84","84","female","alone","never","Placebo","guideline","no","yes","no","0","1","no","no","no","no","no","98.13","1","12","9","8","7","6","2","80"
+"106.2","72","male","partner","ever","Placebo","guideline","yes","yes","no","0","11","yes","no","no","no","no","93.5","1","12","10","18","8","6","7","40"
+"142.15","33","female","alone","ever","Placebo","guideline","no","no","no","0","2","no","no","no","no","no","56.87","1","19","16","14","14","18","15","44"
+NA,"70","male","partner","ever","Active","guideline","no","no","no","0","19","yes","no","no","no","no","62.87","3","11","9","11","9","10","7","84"
+"52.36","88","male","alone","ever","Active","more","yes","no","no","0","12","no","no","no","no","no","25.8","3","7","18","15","12","10","4","72"
+"191.8","84","male","partner","ever","Placebo","guideline","no","no","no","1","1","no","no","no","no","no","64.6","4","20","20","20","10","16","19","4"
+"75.8","45","male","partner","never","Placebo","guideline","no","no","no","0","3","yes","no","no","yes","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"252","74","male","partner","never","Placebo","guideline","no","yes","no","0","0","no","yes","no","no","no","224.64","0","8","5","4","4","5","3","80"
+"195.5","63","male","alone","never","Active","guideline","no","no","no","0","5","no","no","no","no","no","175.58","3","11","11","6","4","6","5","80"
+"151.4","62","male","partner","never","Placebo","guideline","no","no","yes","0","9","no","no","no","no","no","194.9","3","10","8","8","4","9","3","84"
+"123.29","67","female","partner","never","Active","guideline","no","no","no","0","3","yes","no","no","no","no","223.92","1","8","6","10","8","8","5","76"
+"110.8","66","male","alone","never","Placebo","guideline","no","yes","no","0","3","yes","no","no","no","no","38.27","2",NA,NA,NA,NA,NA,NA,NA
+"0","65","male","alone","never","Placebo","guideline","no","yes","yes",NA,NA,"no","no","no","yes","no","25","4","10","16","10","4","6","2","72"
+NA,"63","male","alone","never","Active","guideline","no","yes","no","0","16","no","yes","no","yes",NA,"21.35","5","16","14","12","7","14",NA,"20"
+"222.8","58","male","partner","never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","377.58","2","12","10","5","8","9","6","80"
+"184.49","79","female","partner","ever","Placebo","guideline","no","yes","no","0","3","yes","no","no","no","no",NA,"0","7","6","6","4","4","1","96"
+"191","60","male","alone","never","Active","guideline","no","yes","no","1","3","yes","no","no","no","no","141.08","2","4","6","6","4","4","1","96"
+"184.47","54","female","partner","ever","Active","guideline","no","yes","no","0","1","no","no","no","no","no","277.76","2","15","18","15","10","4","12","52"
+"225.6","65","female","partner","ever","Active","guideline","no","no","no","0","19","yes","no","yes","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+NA,"52","male",NA,NA,"Placebo",NA,NA,NA,"no","0","10","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+"92.19","77","female","partner","never","Active","guideline","yes","yes","no","0","0","no","no","no","yes","no","56.56","2","9","13","10","8","10","24","40"
+"53.11","72","female","alone",NA,"Placebo","guideline","no","no","no","0","4","yes","no","no","no","no","277.5","1","4","4","5","4","8","0","100"
+"161","61","male","partner","never","Placebo","guideline","yes","yes","no","0","1","no","no","no","no","no","140.83","0","8","11","12","10","8","2","68"
+"75","62","female","partner","never","Placebo",NA,"no","no","no","0","24","no","no","no","no","no","27.09","4","14",NA,"15","9","9","10","64"
+"143.2","66","female","partner","ever","Placebo","guideline","no","no","no","0","9","yes","no","no","no","yes","111.4","2","13","8","8","7","11","1","88"
+"61.72","50","male","alone","never","Active","guideline","no","yes","no","0","0","no","no","no","no","no",NA,"2","12","20","13","16","6","17","60"
+"33.6","82","female","partner","never","Placebo","guideline","no","yes","no","0","19","no","no","no","no","no",NA,"4","15","20","18","10","12","28","4"
+"75","70","female","partner","ever","Placebo","guideline","no","no","no","0","3","no","no","no","no","no","93.14","1",NA,"13","11","11","9","5","76"
+"123","69","male","partner",NA,"Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","58.6","1","7","14","10","6","6","3","84"
+"145","58","male","partner","ever","Placebo","guideline","yes","no","no","0","14","no","no","no","no","no","276.47","2","10","12","6","4","6","7","44"
+"52.2","72","female","alone","never","Active","guideline","no","no","no","0","4","yes","no","no","no","no","31.4","1","4","4","7","5","4","0","100"
+"141.2","79","male","partner","ever","Placebo","guideline","no","no","no","0","4","yes","no","no","no","no","107.3","2","12","16","9","6","10","13","72"
+"144.6","79","male","partner","ever","Placebo","guideline","no","no","no","2","9","no","no","no","no","no",NA,"6","18","14","20","11","16","11","40"
+"65","67","male","alone","never","Placebo","guideline","no","yes","yes","2","2","no","no","no","no","no","97.13","2","16","14","14","12","12","7","56"
+"110.8","87","male","partner","never","Placebo","guideline","no","no","no","0","4","yes","no","no","no","no","33.6","1","10","14","9","12","4","5","68"
+"131.8","67","male","partner","never","Placebo","guideline","yes","yes","no","2","3","yes","no","no","yes","no","70.8","0","7","10","10","13","4","4","76"
+"52.2","19","female","alone","never","Placebo","guideline","no","no","no","0","19","yes","no","yes","no","no","78.85","1","8","8","5","4","5","3","84"
+"106.8","83","female","alone","ever","Active","guideline","no","yes","no",NA,"16","yes","no","no","no","no","27.2","3",NA,NA,NA,NA,NA,NA,NA
+"27.53","72","female","alone","never","Placebo","guideline","no","yes","no",NA,"1","yes","no","no","no","no","39.4","1","14","13","10","6","11","3","64"
+"258.4","72","male","partner","ever","Active","guideline","yes","yes","yes","0","4","yes","no","no","no","no","65","2","6","6","9","4","4","3","84"
+"168.37","76","male","partner","never","Placebo","guideline","no","yes","no","0","1","no","no","no","no","no","164.8","2","11","13","8","8","11","2","100"
+"17.63","83","female","alone","never","Active","guideline","no","yes","no",NA,"2","no","no","no","no","no","8.6","3","12","12","17","8","8","9","72"
+"52.2","91","female","alone","ever","Placebo","guideline","no","yes","no","1","5","no","no","no","no","no","63.13","2","12","14","12","6","7","6","72"
+"51.4","67","male","partner","never","Placebo","guideline","no","no","no","0","5","yes","no","no","no","no","68.43","1","10","12","11","9","4","3","88"
+"144.6","72","male","partner","never","Active","guideline","no","no","no","1","20","yes","no","yes","no","no",NA,"6",NA,NA,NA,NA,NA,NA,NA
+"109.25","89","male","partner","ever","Active","guideline","yes","no","no","0","3","yes","no","no","no","no","33.6","2","11","12","13","8","10","4","84"
+"95.42","64","male","alone","never","Placebo","guideline","no","yes","no","0","1","no","no","no","no","no","85.82","1","15","15","16","8","10","16","60"
+"146","57","female","alone","never","Active","guideline","no","no","no","0","7","no","no","no","no","no","252.8","1","10","7","5","8","9","3","80"
+"179.2","80","male","partner","never","Active","guideline","no","yes","no","0","8","no","no","no","no","no","86","2","13","14","20","11",NA,NA,"48"
+"229.9","76","male","partner","ever","Active","guideline","no","no","no","0","3","yes","no","no","no","no","195.8","1","7","5","6","6","6","2","100"
+"241","57","male","partner","never","Placebo","guideline","no","no","no","0","8","no","no","yes","no","no","282","0","4","9","4","4",NA,"1","92"
+"186.8","60","male","alone","never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","154.18","2","11","8","12","10","9","7","52"
+"163.09","81","female","alone","never","Active","guideline","no","yes","no","0","5","yes","no","no","no","no","121","1","12","7","5","4","4","2","88"
+"152.53","48","male","alone","never","Placebo","guideline","no","no","no","0","5","no","no","no","no","no","108.76","3","15","17","16","10","12","16","52"
+"98.63","86","male","alone","never","Active","guideline","no","yes","yes","2","3","yes","no","no","no","no","41.38","2","12","13","16",NA,"19","34","24"
+"50.8","74","male",NA,NA,"Active",NA,NA,NA,"no","0","1","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+"84.83","67","female","partner","ever","Placebo","guideline","no","no","no","0","6","yes","no","no","no","no","98.85","0","8","8","4","4","9","6","92"
+"254.15","64","male","partner","never","Placebo","guideline","no","no","yes","0","5","yes","no","no","no","no","107.31","2","7","6","4","4","5","2","88"
+"221.4","61","male","partner","never","Active","guideline","no","yes","no","0","3","no","no","no","no","no","117.4","2","9","15",NA,"6","7","5","60"
+"291.47","58","male","partner","never","Placebo","more","no","no","no","0","7","no","no","no","no","no","484.8","1","9","7","4","4","4","3","88"
+"27.2","83","male","partner","never","Placebo","guideline","no","yes","no","1","1","no","no","no","no","no","121.8","2","13","12","7","6","5","2","88"
+"208","68","male","partner","never","Placebo","guideline","no","no","yes","0","2","yes","no","no","yes","no","207.5","0","7","14","8","6","9","4","92"
+"178.6","53","male","alone","never","Active","more","no","no","no","0","14","no","no","no","no","no","63.27","4","12","14","11","8","10","10","32"
+NA,"52","male","partner","never","Active","guideline","no","yes","no","0","5","no","no","no","no","no",NA,"6",NA,NA,NA,NA,NA,NA,NA
+"197.3","84","female","alone","ever","Active","guideline","yes","yes","no","0","0","no","no","no","no","no","80","1","13","16","15","12","7","7","64"
+"331.59","63","male","partner","never","Placebo","guideline","yes","no","no","0","15","yes","no","no","no","no","312","1","6","4","4","5","10","2","88"
+"111","58","male","alone","ever","Placebo","guideline","no","no","no","0","4","no","no","no","no","no","219.54","2","10","8","9","8","7","1","100"
+"30","89","female","alone","never","Placebo","more","no","yes","no","0",NA,"no","no","no","no","no",NA,"6",NA,NA,NA,NA,NA,NA,NA
+"78.33","84","female","alone","never","Active","guideline","no","yes","no","2","0","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"14.21","79","male","partner","never","Active","guideline","yes","no","no","2","6","no","yes","no","no","no","135.42","4","7","11","12","9","4","0","100"
+"95.8","86","female","alone","never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","50.8","2","15","15","15","9","8","14","68"
+"75.39","73","male","partner","ever","Placebo","guideline","yes","yes","no","1","8","no","no","no","no","no",NA,"1","4","8","4","4","4","2","100"
+"170.25","69","female","partner","ever","Placebo","guideline","no","no","no","0","4","yes","no","no","no","yes","193.3","0","12","10","10","9","4","1","92"
+"61","70","male","partner","never","Placebo","guideline","no","no","no","0","3","yes","no","yes","no","no","220.8","0","6","6","7","7","5","6","80"
+"236.8","49","male","partner","never","Placebo","guideline","no","no","no","0","3","no","no","no","no","no","227.05","1","9","12","10","4","7","7","76"
+"163.2","53","male","partner","never","Active","guideline","no","no","no","0","5","no","no","no","no","no","179.49","1","13","20","19","8","7","14","68"
+"29.51","77","female","alone","never","Active","guideline","yes","yes","no","0","3","yes","no","no","no","no","61.96","0","10","16","11","13","11","3","76"
+"206.4","51","male","partner","never","Placebo","guideline","no","no","yes","0","7","yes","no","no","yes","no",NA,"2","17","15","16","14","14","30","20"
+"116","74","male","partner","never","Placebo","guideline","yes","yes","no","0","7","yes","no","no","yes","no","123.81","0","4","4","6","5","4","1","84"
+"323.17","58","male","partner","ever","Placebo","guideline","no","no","no","0","0","no","no","no","no","no","383","1","10","7","6","8","6","3","80"
+"107.81","79","male","partner","never","Placebo","guideline","no","no","no","0","3","no","no","no","no","no","163.08","1","16","15","19","10","13","5","68"
+"211.4","48","male","partner","never","Active","guideline","no","no","no","0","2","no","no","no","no","no","210.16","1","13","16","16","12","11","4","60"
+"157.4","78","male","partner","ever","Placebo","guideline","no","no","no","0","4","no","no","no","no","no","117.15","0","6","12","8","8","10","10","64"
+"126.64","52","male","partner","ever","Placebo","guideline","no","yes","no","0","4","no","no","no","no","no","251.15","2","6","12","9","4","4","2","100"
+"69.36","78","female","alone","never","Active","guideline","no","no","no","0","5","yes","no","no","no","no","128.04","1","20","17","20","18","15","23","32"
+"107.52","78","male","partner","never","Placebo","more","yes","yes","no","2","2","no","no","no","no","no","88.78","2","14","6","10","7","4","5","68"
+"60","69","male","partner","never","Active","guideline","no","yes","yes","0","8","yes","no","no","yes","no","107.16","1","13","4","16","6","16","10","60"
+"169.6","60","female","alone","ever","Placebo","guideline","no","no","yes","0","3","no","no","no","no","no","196.32","2","5","5","13","5","4","6","76"
+"106","68","male","partner","never","Active","guideline","yes","no","no","0","12","yes","no","yes","no","no","127","0","6","6","8","7","4","0","88"
+"132.5","68","female","partner","never","Placebo","guideline","no","no","no","0","2","no","no","no","no","no","131.16","0","4","5","5","5","4","0","92"
+"141.55","73","female","alone","ever","Active","guideline","no","yes","no","0","2","no","no","no","no","no","106.55","2","16","14","14","12","8","8","48"
+"247.23","37","female","partner","never","Active","guideline","no","no","no","0","1","no","no","no","no","no","172.14","1",NA,NA,"9","9","14","5","64"
+"71.72","44","male","alone","never","Active","guideline","no","no","no","0","12","yes","no","yes","no","no","50.8","2","19","17","17","15","15","24","16"
+"217.05","79","male","partner","never","Active","guideline","no","yes","no","0","3","no","no","no","no","no","147.74","2","10","11","12","10","7","3","60"
+"140.75","56","male","partner","ever","Placebo","guideline","no","yes","no","0","5","no","no","no","no","no","120.56","0","12","9","6","6","7","4","76"
+"95.8","84","female","alone","ever","Active","guideline","no","yes","no","0","3","no","no","no","no","yes",NA,"0","12","12","12","12","12","50","100"
+"140.85","73","male","partner","never","Active","guideline","no","no","no","0","2","yes","no","no","no","no","290.77","1","7","9","4","4","4","6","80"
+"2.2","71","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","50.8","2","11","10","16","12","6","10","84"
+"56.4","67","male","partner","ever","Active","guideline","yes","no","no","1","2","no","no","no","no","no","103.12","2","9","10","12","8","9","4","84"
+"59.24","80","male","partner","never","Active","guideline","no","yes","no","0","3","no","no","no","yes",NA,NA,"3","18","16","20","20","12","29","8"
+"77","77","female","partner",NA,"Placebo","guideline","no","yes","no","0","9","yes","yes","no","yes","no","100","1","12","10","10","6","8","11","80"
+"188.8","49","female","partner","never","Placebo","guideline","no","yes","no","0","3","no","no","no","no","no","78.65","1","12","16","10","8","4","4","76"
+"163.2","63","female","partner","never","Placebo","guideline","no","no","no","0","3","no","no","no","no","no","231.54","2","14","9","12","9","15","20","56"
+"0","88","female","partner","ever","Placebo","guideline","no","yes","no","0","2","yes","no","no","yes","no","25","0","7","5","7","6","4","0","96"
+"50","86","female","alone","ever","Placebo","guideline","no","no","no","2","4","no","no","no","no","no","52.2","2","13","15","11","15","12","5","72"
+"249.9","67","female","partner","never","Placebo","guideline","no","yes","no","0","3","no","no","no","no","no","111.1","2","12","11","12","8","8","10","64"
+"170.72","75","male","alone","never","Active","guideline","no","yes","no","0","4","no","no","no","no","no","170.12","1","6","4","4","4","8","2","92"
+"70","79","female","alone","never","Active","guideline","no","no","no","0","5","no","no","no","no","no","55","3","17","8","12","10","10","13","48"
+"144.13","80","female","alone","never","Placebo","guideline","no","no","no","0",NA,"no","no","no","yes","no","215.43","0","4","4","4","6","4","0","96"
+"315.91","68","male","partner","never","Placebo","guideline","no","no","no","0","1","no","no","no","no","no","241.05","1","5","4","9","4","6","4","88"
+"50.8","72","male","partner","ever","Active","guideline","no","no","yes","1","22","yes","no","no","no","no","44.6","4","6","7","6","10","18","9","88"
+"80.75","69","female","partner","ever","Placebo","guideline","no","yes","no","0","0","no","no","no","no","no","161.07","0","6","6","5","6","7","0","96"
+"25","97","female","alone",NA,"Active","guideline","yes","yes","no","2","24","no","no","no","no","no",NA,"5",NA,NA,NA,NA,NA,NA,"0"
+"277.11","54","male","partner","never","Placebo","guideline","no","no","no","0","3","yes","no","no","no","no",NA,"0","14","7","14","11","10","11","36"
+"112.4","47","female","partner","never","Placebo","guideline","no","no","no","0","2","no","no","no","no","no","52.2","0",NA,NA,NA,NA,"4","3","100"
+"105","64","female","partner","never","Active",NA,"yes","no","no","0","23","no","no","yes","no","no","112.57","4","7","7","4","4","6","1","92"
+"181.32","54","female","partner","never","Placebo","guideline","no","no","no","2","5","yes","no","no","no","no","158.84","2","13","12","10","8","4","1","68"
+"27.31","52","male","alone","never","Placebo","guideline","no","yes","no","1","2","no","no","no","no","no","151.92","2","7","15","11","5","8","8","52"
+"37.8","76","female","alone","never","Placebo","guideline","no","yes","yes","0","4","no","yes","no","no","no","25","1","12","13","13","13","12","7","56"
+"108.76","79","male","partner",NA,"Active","guideline","no","no","no","0","2","no","no","no","yes","no","300.85","2","4","8","9","6","5","2","92"
+"152.03","71","female","partner","ever","Active","guideline","no","yes","no","0","7","yes","no","no","no","no","222.55","1","7","5","6","4","12","8","100"
+"55","66","male","partner","never","Active","guideline","no","yes","no","0","20","yes","no","yes","yes","no","139.51","1","11","10","14","7","5","7","64"
+"80.25","80","male","partner","never","Placebo","guideline","yes","yes","no","2","9","no","no","no","no","no",NA,"6","6","13","20","18","15","13","32"
+"50","72","male","partner","never","Placebo","more","no","no","no","0","2","yes","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"188.47","70","male","partner","never","Active","guideline","no","yes","yes","0","0","no","yes","no","yes","no","158.89","1",NA,NA,NA,NA,NA,"0","96"
+"236.9","64","female","partner","ever","Placebo","guideline","no","no","no","0","2","no","no","no","no","no","297.6","0","7","10","4","4","4","1","100"
+"300.72","57","male","partner","ever","Active","guideline","no","no","no","0","1","no","no","no","no","no","280.13","0","4","4","5","4","4","1","100"
+"116.28","77","male","partner","ever","Placebo","guideline","yes","yes","no","1","9","yes","no","no","no","no","170.74","4","9","10","12","4","5","8","76"
+"156.31","65","female","alone","never","Active","guideline","no","yes","no","0","6","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"50","73","male","alone","never","Placebo","guideline","no","no","no","2","0","no","no","no","no","no","27.2","1","19","19","17","18","8","20","28"
+"27.2","85","female","alone","ever","Active","guideline","no","no","no","1","1","no","no","no","no","no",NA,"1","19","13","18","11","4","26","28"
+NA,"79","female","alone","never","Placebo","guideline","yes","no","no",NA,"9","yes","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"129.63","75","male","partner","never","Placebo","guideline","no","no","no","0","18","no","no","yes","yes","no",NA,"6","15","16","11","8","12","26","24"
+"82.63","75","female","partner","ever","Active","guideline","no","yes","no","0","4","no","no","no","no","no","119.68","2","16","16","14","7","12","10","76"
+"114.59","70","female","alone","ever","Active","guideline","no","no","yes","0","7","yes","no","no","no","yes","83.16","1","13","13","15","8","16","18","56"
+"117","70","male","partner","never","Placebo","guideline","yes","no","no","0","5","no","no","no","no","no","102.03","2","13","12","8","8","4","3","0"
+"99.92","82","male","alone","never","Placebo","guideline","no","no","no","0","4","no","yes","no","no","no","98.63","0","14","15","11","6","8","8","72"
+"323.68","56","male",NA,NA,"Active",NA,NA,NA,"no","0","3","no","no","no","no",NA,"448.38","2","5","8","4","4","4","1","96"
+"76.4","84","female","alone","ever","Placebo","guideline","no","yes","yes","0","0","no","no","no","no","no","56.4","1","16","17","12","14","12","7","68"
+"95.75","69","female","alone","ever","Active","guideline","no","yes","no","0","13","yes","no","no","no","no","82.09","4","8","7","6","4","4","3","88"
+"160.56","67","male","partner","never","Active","more","no","no","no","0","2","no","no","no","no","yes","349.48","2","17","17","13","9","17","9","72"
+"162.6","59","male","partner","ever","Placebo","guideline","no","no","no","0","1","no","no","no","no","no","249.67","1","4","9","4","5","4","1","88"
+"151","69","male","partner","never","Placebo","guideline","no","yes","no","0","1","yes","no","yes","no","no","254.61","1","13","10","12","8","10","11","56"
+"98.2","40","male","partner","never","Placebo","more",NA,"yes","no","0","2","yes","no","no","no","no","315.11","0","7","12","13","5","4","9","80"
+"148.15","72","male","partner","never","Active","guideline","no","yes","no","0","1","no","no","no","no","no","136","1","12","16","20","12","4","8","68"
+"111.8","73","male","partner","ever","Placebo","guideline","no","yes","yes","0","1","no","no","no","no","no","121","1","10","4","12","8","4","3","88"
+"179.23","50","male","partner","ever","Placebo","guideline","no","no","no","0","0","no","no","no","no","no","336.27","0","5","4","4","5","4","0","92"
+"107","44","female","alone","never","Placebo","guideline","no","yes","yes","1","5","no","no","no","no","no","70","1","12","13","11","10","10","6","68"
+"229.5","72","male","partner","never","Placebo","guideline","yes","yes","no","0","5","no","no","no","no","no","58.6","2","10","4","12","5","8","18","48"
+"365.28","64","male","partner","never","Placebo","more","no","no","no","0","9","yes","no","no","no","no","142.93","2","8","8","8","4","10","2","100"
+"412.9","55","male","partner","never","Active","guideline","no","no","no","0","5","yes","no","no","no","no","222.84","3","10","7","10","8","4","3","100"
+"108.31","67","female","partner","never","Active","guideline","no","yes","no","0","3","no","no","no","no","no","116.25","1","15","12","13","9","9","8","72"
+"153.63","86","male","partner","never","Active","guideline","yes","no","no","0","4","no","no","no","no","no","108.2","1","4","4","6","6","5","0","92"
+"111.8","78","female","alone","ever","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"101.16","74","male","alone","ever","Active","guideline","no","no","no","0","3","no","no","no","no","no","96","3","6","10","11","8","10","2","96"
+"157","73","male","partner","never","Active","guideline","no","yes","no","1","3","no","no","no","no","no",NA,"0","8","6","5","5","4","1","88"
+"290.84","61","male","partner","ever","Active","guideline","no","no","no","0","2","no","no","no","no","no","262","1","9","8","9","4","4","0","88"
+"88.2","74","female","alone","ever","Placebo","guideline","no","yes","no","0","1","no","no","no","no","no","130","1","17","10","16","12","12","16",NA
+"170.89","45","male","alone","ever","Active","guideline","yes","yes","no","0","13","no","no","no","no","no","170.84","1","6","10","10","8","4","0","52"
+"107.72","82","male","partner","ever","Placebo","guideline","no","yes","no","0","10","yes","no","yes","no","no","138.38","1","9","10","11","9","9","4","64"
+"225.6","61","male","partner","never","Placebo","guideline","no","no","no","0","1","no","no","no","no","no","219.55","0","9","7","8","9","11","6","60"
+"235.16","57","male","partner","never","Active","guideline","yes","no","no","0","0","no","no","no","no","no","255.33","0","9","6","8","7","6","2","72"
+"50","82","female","partner","never","Active","guideline","no","no","no","0","17","yes","no","yes","no","no","30.5","2","15","15","13","4","4","8","84"
+"99.55","74","female","alone","never","Active","guideline","no","yes","no","0","7","no","no","no","no","no","59.03","4","13","10","14","8","4","8","76"
+"105.61","80","female","alone","never","Active","guideline","no","yes","yes","1","0","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"29.46","78","male","partner","never","Placebo","more","no","yes","no","0","2","yes","no","no","no","no","167.32","1","10","17","4","4","4","4","92"
+"179.5","71","male","alone","ever","Placebo","guideline","no","yes","no","0","5","yes","no","no","yes","no","157.34","2","12","10","10","11","7","8","76"
+"245.11","56","male","alone","never","Active","guideline","no","no","no","0","2","no","no","no","no","no","92.4","1","7","6","5","7","4","8","84"
+"315.8","45","male","partner","never","Active","guideline","no","no","no","0","3","yes","no","no","no","no","378.79","0","6","6","13","7","5","5","72"
+"120","70","female","partner","ever","Active","guideline","yes","no","no","0","11","no","no","yes","no","no","78.6","1","17","17","18","9","5","26","56"
+"58.6","84","female","partner","never","Placebo","guideline","yes","yes","no","0","4","yes","no","no","no","no","204.55","2","17","15","13","5","10","7","56"
+"56.4","66","female","alone","never","Active","guideline","yes","no","no","0","12","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"159.11","54","male","partner","never","Active","guideline","no","yes","no","0","1","yes","no","no","yes","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"156.53","52","male","partner","ever","Active","guideline","no","yes","no","0","17","yes","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"186.8","62","female","partner","ever","Active","guideline","no","yes","yes","0","8","yes","no","no","no","no","165.6","2","16","16","18","9","20","18","24"
+"142.36","67","male","partner","never","Active","more","no","no","no","0","2","no","no","no","no","no","213.2","2","4","4","8","8","4","5","100"
+"222.4","64","male",NA,"never","Active",NA,"no","no","no","0","0","no","no","no","no","no","192.4","2","9","15","9","7","4","2","96"
+"58.6","93","male","alone","never","Placebo","guideline","no","yes","no","1","11","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"62.79","89","male","partner","never","Placebo","guideline","no","yes","no","2","3","yes","no","no","no","no","122.81","2","14","16","18","14","12","10","36"
+"105.72","74","male","partner","never","Placebo","guideline","yes","yes","no","0","2","no","yes","no","no","no","140.26","1","10","9","6","8","5","8","76"
+"258.2","66","male","partner","never","Placebo","more","no","yes","no","0","2","no","no","no","no","no","138.25","1","8","8","11","9","7","6","76"
+"256","51","female","alone","never","Active","guideline","no","no","no","0","4","yes","no","yes","no","no","77.25","2","15","17","7","7","20","29","60"
+"52.2","69","male","alone","ever","Placebo","guideline","yes","yes","yes","0","1","no","no","no","no","no","108.2","2","4","9","11","12","6","3","100"
+"50","93","female","alone","ever","Placebo","guideline","no","yes","yes","2","1","no","no","no","no","no","25","4","15","19","16","7","5","5","76"
+"103.49","66","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","21.93","4","13","19","19","13","13","40","56"
+"229.73","64","male","alone","never","Active","guideline","no","yes","no","0",NA,"no","no","no","yes","no","29.51","4","5","8","12","7","4","1","88"
+"196.8","71","male","partner","never","Placebo","guideline","no","yes","no","1","1","yes","no","no","no","no","146.8","1","12","13","10","6","6","2","76"
+"163.4","66","male","alone","ever","Active","guideline","no","no","no","0","2","no","no","no","no","no","140.8","1","7","5","4","7","4","1","88"
+"76.4","73","female","partner","never","Active","guideline","no","yes","no","0","4","no","no","no","no","no",NA,"2","18","8","15","4","19","3","88"
+"33.6","75","male","alone","never","Active","guideline","yes","no","no","0","2","no","no","no","no","no","106.8","1","7","9","10","7","4","1","84"
+"75","69","female","partner","never","Active","guideline","no","yes","no","0","1","no","no","no","no","no","25","2","16","19","20","12","9","12","72"
+"65","78","male","partner","never","Active","guideline","no","no","no","2","2","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"185.15","74","female","partner","never","Active","guideline","no","no","no","0","4","no","no","no","no","no","183.79","1","4","6","4","4","4","3","84"
+"155.52","68","male","partner","ever","Active","guideline","yes","yes","no","0","3","no","no","no","no","no","134.8","0","7","7","7","6","5","3","76"
+"34.56","78","female","alone","never","Placebo","guideline","no","yes","no","0","1","yes","no","no","no","no","103.7","2","10","12","11","10","8","2","96"
+"76.21","65","male","partner","never","Placebo","guideline","no","no","no","0","2","no","no","no","no","no","67.76","0","13","14","15","9","10","27","24"
+"65","70","male","alone","never","Active","more","no","yes","no","0","1","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"133.89","79","male","partner","never","Active","guideline","no","yes","yes","2","19","yes","no","yes","no","no","82.76","3","12","20","20","4","4","11","48"
+"50","75","female","partner","ever","Active","guideline","yes","yes","no","1","1","no","no","no","no","no","109.72","2","7","9","5","6","4","2","80"
+"111","72","male","partner","never","Active","guideline","no","yes","no","0","1","no","no","no","no","no","113.53","0","20","16","19","16","12","29","16"
+"213.6","56","male","partner","never","Placebo","guideline","no","yes","no","0","1","no","no","no","no","no","182.9","2","17","10","13","12","19","18","24"
+"50.8","56","male","alone","never","Placebo","guideline","no","yes","no","1","12","yes","no","no","no","no","68.3","2","18","19","15","14","12","21","28"
+"213.25","55","male","partner","never","Active","guideline","no","yes","no","0","1","no","no","no","no","no","224.53","1",NA,"8","8","7","11","8","76"
+"145.56","80","male","partner","never","Active","guideline","yes","no","no","0","6","no","no","no","no","no","150.03","2","7","9","16","7","4","1","84"
+"50","80","male","alone","ever","Active","guideline","yes","no","no","0","8","yes","no","no","no","no","79.03","2","17","19","18","14","16","9","52"
+"76.4","66","male","partner","never","Active","guideline","yes","no","no","0","2","no","no","no","no","no","161","0","13","14","15","13","10","9","60"
+"136","63","female","partner","ever","Active","guideline","no","yes","yes","0","2","no","no","no","no","no","239.04","1","11","8","4","4","4","6","68"
+"230.9","54","male","partner","ever","Active","guideline","no","yes","no","0","2","no","no","no","no","no","143.53","1","8",NA,"11","7","7","3","72"
+"248.25","45","male","partner","ever","Active","guideline","yes","no","no","0","0","no","no","no","no","no","153.25","1","12","6","8","13","7","8","88"
+"101","88","female","alone","ever","Active","guideline","no","yes","no","0","4","no","no","no","no","no",NA,"3",NA,NA,NA,NA,NA,NA,NA
+"113.4","71","male","partner","never","Active","guideline","no","yes","no","0","10","yes","no","no","no","no","125.4","0","4","9",NA,"9","8","0","96"
+"113.52","73","male","partner","never","Placebo","guideline","no","no","yes","2","19","yes","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"141.8","67","male","partner","never","Active","guideline","no","yes","no","0","7","yes","no","no","yes","no","218.39","1","18","14","16","15","17","37","48"
+"170.8","64","male","partner","never","Placebo","guideline","no","yes","yes","0","5","yes","no","no","no","no","210.24","1","12","8","16","12","4","2","80"
+"50.8","58","female","partner","never","Active","guideline","no","yes","no","1","4","no","no","no","no","no","35","3","16","13","19","10","15","37","40"
+"78.33","71","male","alone","never","Active","more","no","no","no","1","4","no","no","no","no","no","4.51","4","20","16","20","17","19","38","20"
+"146.8","71","female","partner","ever","Active","guideline","no","no","no","0","20","yes","no","no","no","no",NA,"3","14","6","4","8","12","7","88"
+"108.2","87","male","alone","never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","67.63","2","5","7","11","4","4","4","88"
+"180","61","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","281.28","2","10",NA,"12","13","6","6","76"
+"130.8","76","male","partner","ever","Placebo","guideline","yes","no","no","0","0","no","no","no","no","no","402.45","2","4","11","4","4","4","1","92"
+"135.63","70","female","alone","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","94.6","1","5","8","8","7","4","6","80"
+"201.8","69","male","partner","never","Placebo","guideline","no","yes","yes","0","2","no","no","no","no","no","204.55","2","11","9","8","5","11","6","44"
+"52.2","67","male","alone","never","Placebo","more","no","no","no","1","5","no","no","no","no","no","74.25","1","11","5","6","6","11","9","72"
+"282","60","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","yes","no","177.4","2","10","13","7","4","4","7","80"
+"89.61","82","male","alone","never","Placebo","guideline","no","yes","yes","0","4","no","no","no","no","no","158.52","0","4","10","6","5","4","0","96"
+"77.31","78","female","alone","ever","Active","guideline","no","yes","no","0","2","no","no","no","no","no","189.9","2","16","17","20","18","13",NA,"44"
+"204.67","71","female","partner","never","Active","guideline","no","yes","no","0","4","no","no","no","no","no","91","2","4","4","4","4","4","0","100"
+"200.9","59","male","partner","never","Active","guideline","no","no","no","1","3","yes","no","no","no","no","174.43","2","13","15","12","11","13","9","40"
+"233.73","56","male","alone","never","Placebo","guideline","no","no","no","0","1","yes","no","no","no","no","144.7","1",NA,NA,NA,NA,NA,NA,NA
+"325.6","46","male","partner","ever","Placebo","guideline","no","no","no","0","3","yes","no","no","no","no","177.87","2","16","14","13","14","17","19","44"
+"113","76","female",NA,"never","Placebo","guideline","no","no","no","1","4","no","yes","no","no","no","79.45","2","20","18","19","16","14","36","12"
+"91.91","64","male","partner","never","Active","more","no","yes","yes","0","5","yes","no","no","no","no",NA,"1",NA,NA,NA,NA,NA,NA,NA
+"195.8","58","female","partner","never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","111","1","11","13","6","4","7","11","76"
+"196.95","49","female","partner","ever","Active","guideline","no","no","no","0","5","yes","no","no","no","no","193.8","0","13","11","6","4","10","8","76"
+"207.31","52","male","alone","ever","Placebo","guideline","no","no","no","0","1","no","no","no","no","no","208.5","2","12","13","10","8","8","2","68"
+"53.6","88","male","partner","never","Placebo","guideline","no","yes","no","2","3","no","yes","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"45","82","male","partner","never","Placebo","guideline","no","no","no","0","7","no","no","no","no","no",NA,"4","7","18","16","7","12","15","48"
+"25","82","female","alone","never","Placebo","guideline","no","no","no","1","6","no","no","no","no","no","25.8","3","16","19","19","13","10","9","72"
+"147.4","34","female","partner","ever","Active","guideline","no","no","no","0","10","yes","no","no","no","no","139.05","2","20","14","15","16","18","36","24"
+"85","78","female","partner","ever","Active","guideline","no","no","no","0","3","no","no","no","no","no","131.8","1","12","8","4","12","4","1","92"
+"27.2","74","female","alone","never","Active","more","no","yes","no","2","2","no","no","no","no","no","36.23","2","10","11","15","9","7","3","84"
+"15","64","female","partner","never","Active","guideline","no","no","no","0","0","no","no","no","no","no","30.75","0","13","13","15","11","12","9","76"
+"225.6","51","male","partner","ever","Active","guideline","no","no","no","0","4","yes","no","no","no","no","211","0","7","4","4","5","7","1","88"
+"75.8","85","male","alone","never","Placebo","guideline","no","yes","no","0","3","no","no","no","no","no","75.8","1","17","16","13","10","12","12","36"
+"196.2","59","male","partner","never","Active","guideline","no","no","no","0","7","yes","no","no","no","no","122","1","11","13","11","10","4","3","84"
+"173.73","70","male","partner","ever","Placebo","guideline","no","no","no","0","4","yes","no","no","no","no","131.8","0","4","4","4","4","4","0","100"
+"40.32","77","male","partner","never","Placebo","guideline","yes","yes","no","0","1","yes","no","no","no","no","224.49","2","13","13","14","12","12","2","92"
+"106","82","male","partner","ever","Placebo","guideline","yes","no","no","0","19","yes","no","yes","no","no",NA,"2",NA,NA,NA,NA,NA,NA,NA
+"63.59","73","female","partner","never","Active","guideline","no","no","no","0","0","no","no","no","no","no","153.35","1","11","4","6","4","4","4","72"
+NA,"42","male","partner","ever","Placebo","guideline","no","no","no","0","7","yes","no","no","no","no","202.67","2","5","7","6","9","9","5","84"
+"155.11","62","male","partner","never","Active","guideline","no","yes","no","0","26","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"314.76","58","male","partner","never","Placebo","guideline","no","yes","no","0","0","yes","no","no","no","yes",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"196.47","84","male","partner","ever","Placebo","guideline","no","yes","no","0","6","no","no","no","no","no","7.31","4","16","17","9","5","9","15","64"
+NA,"71","female","alone","never","Active","guideline","yes","yes","no",NA,NA,"no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"247","54","male","partner","never","Active","more","no","yes","no","1","3","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"81.87","70","female","partner","ever","Active","guideline","no","yes","yes","0","3","yes","no","no","no","no","59.89","1","12","11","9","8","4","5","88"
+"132.12","87","male","partner","ever","Active","more","no","no","no","0","6","no","no","no","no","no","36.72","3","14","20","7","10","4","5","84"
+"50","84","male","alone","never","Active","guideline","yes","yes","no","2",NA,"no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+NA,"76","female","alone","never","Active","guideline","no","no","yes",NA,NA,"no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"247","67","male","partner","never","Active","guideline","no","yes","no","0","3","no","no","no","no","no","278.9","1","14","19","20","16","12","16","16"
+"166.72","52","male","partner","ever","Active","guideline","no","no","no","0","13","yes","no","yes","yes","no","161.4","1","13","12","14","10","15","5","64"
+"81.9","80","female","alone","ever","Active","guideline","no","yes","no","0","7","no","no","no","no","no","164.61","2","17","13","12","10","10","17","48"
+"148","63","female","alone","never","Placebo","guideline","no","yes","no","0","7","no","no","no","no","no","133","0","4","4","4","4","4","0","100"
+"43.8","67","male","partner","never","Placebo","guideline","no","yes","no","1","9","yes","no","yes","no","no","54.11","2","12","19","18","13","11","14","32"
+"143.31","67","male",NA,NA,"Placebo",NA,NA,NA,"no","0","0","no","no","no","no",NA,"27.2","1","18","20","20","17","8","27","40"
+"14.72","52","male","partner","never","Active","more","no","yes","yes","0","3","yes","no","no","no","no","97.4","0","14","19","16","9","6","6","68"
+"155.15","69","female","alone","never","Placebo","guideline","yes","yes","no","0","5","no","no","no","no","no","203.78","1","12","10","15","5","16","13","64"
+"247","71","male","partner","never","Active","guideline","yes","no","no","0","11","yes","no","no","no","no","61.2","2","8","7","4","4","15","5","96"
+"74.1","79","female","alone","never","Placebo","guideline","no","no","no","0","18","yes","no","yes","no","no","131.3","2","9","12","10","9","7","4","72"
+"122.55","75","male","partner","never","Active","guideline","no","no","no","0","3","no","yes","no","yes","no","81.59","0","7","6","9","11","11","4","76"
+"65","74","female","partner","never","Placebo","guideline","no","yes","no","0","6","no","no","no","no","no","75.8","1","16","12","8","8","12","7","72"
+"75","76","female","partner","ever","Active","guideline","no","yes","yes","0","2","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"64.67","75","female","alone","never","Placebo","guideline","no","no","no","0","1","yes","no","no","no","no","125.61","0","11","8","12","7","9","5","76"
+"115.48","72","female","alone","ever","Active","guideline","yes","no","no","0","1","no","no","no","no","no","108.8","1","7","5","12","7","4","0","96"
+"106.27","65","female","alone","ever","Placebo","guideline","no","no","no","0","1","no","no","no","no","no","92.09","1","5","4","10","4","12","5","84"
+"232.4","48","male","alone","never","Placebo","more","no","yes","no","0","2","no","no","no","no","no","282.48","1","7","8","9","4","7","7","76"
+"107.5","63","male","partner","ever","Active","guideline","no","yes","no","0","1","yes","no","no","no","no","210.17","1","8","6","9","6","6","2","96"
+"109.61","74","male","partner","never","Placebo","guideline","yes","yes","no","1","2","yes","no","no","no","no","111","2","4","4","8","8","4","3","40"
+"116.8","73","male","partner","never","Placebo","guideline","yes","no","no","0","2","yes","no","no","no","no",NA,"0",NA,NA,NA,NA,NA,NA,NA
+"114.92","78","male","partner","ever","Active","guideline","no","no","no","0","2","no","no","no","no","no","99.77","5","13","20","12","7","10","9","52"
+"85.5","45","male","partner","never","Placebo","guideline","no","no","no","0","5","no","no","no","no","yes","203.12","1","8","7","10","7","4","3","80"
+"124.27","66","male","alone","never","Active","guideline","no","no","no","0","3","no","no","no","yes","no","50.8","3","13","13","19","11","10","1","84"
+"263.33","37","male","partner","ever","Active","guideline","no","no","no","0","1","no","no","no","no","no","148.05","0","8","4","13","6","4","9","60"
+"166.8","54","male","partner","never","Placebo","guideline","no","no","no","0","3","no","no","no","no","no","236.8","0","4","8","4","4","4","1","100"
+NA,"83","male","partner","ever","Active","guideline","yes","no","no",NA,"27","no","no","yes","yes","yes",NA,"6",NA,NA,NA,NA,NA,NA,NA
+"124.11","66","female","alone","never","Placebo","guideline","no","no","no","0","6","no","no","no","no","no","238.43","2","16","16","4","4","8","7","44"
+"150","55","male","partner","never","Active","guideline","yes","yes","yes","0","5","no","no","no","no","no",NA,"6",NA,NA,NA,NA,NA,NA,NA
+"39.43","92","female","alone","ever","Placebo","guideline","no","yes","no","2","9","no","no","no","no","no","2.2","4","18","19","12","10","7","25","20"
+"79.03","88","female","partner","never","Active","guideline","yes","yes","no","0","21","yes","no","no","yes","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"270.93","57","male","partner","ever","Placebo","guideline","no","no","no","0","3","no","no","no","no","no","276.72","0","12","10","13","8","6","8","72"
+"431.8","55","male","partner","never","Active","guideline","yes","yes","no","0","1","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"65","79","female","alone","never","Active","guideline","no","no","no","0","8","no","no","no","no","no",NA,"6",NA,NA,NA,NA,NA,NA,NA
+"173.85","78","female","partner","ever","Active","guideline","yes","no","no","0","0","yes","no","no","no","no","210.58","1","8","4","6","5","4","5","72"
+"196.8","48","male","partner","ever","Active","guideline","no","no","no","0","2","yes","no","no","no","no","144.16","1","11","11","11","11","12","14","100"
+"58.6","80","male","alone","never","Placebo","guideline","no","no","no","2","2","no","no","no","no","no","78.6","3","14","16","13","5","14","10","80"
+"40","49","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","yes","no","no","no","122.98","0","14","11","12","11","11","30","60"
+"90.55","75","male","partner","ever","Placebo","guideline","no","yes","yes","0","5","yes","no","no","yes","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"55.2","74","male","alone","never","Placebo","guideline",NA,"yes","no","0","5","no","yes","no","yes","no",NA,"2","18","20","20","8","10","12","68"
+"102.31","85","female","alone","never","Placebo","guideline","yes","no","no","0","1","no","no","no","no","no","171.28","0","11","12","13","6","6","8","76"
+"60.69","82","male","alone","ever","Active","guideline","no","yes","no","0","5","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"27.2","79","male","partner","never","Placebo","guideline","yes","yes","yes","2","3","yes","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"68.6","75","male","partner","never","Active","guideline","no","yes","yes","1","5","no","no","no","no","yes","2.2","2","16","20","20","20","4","12","48"
+"221.47","70","male","partner","never","Placebo","guideline","no","yes","no","0","2","yes","no","no","yes","no","187.3","2","5","8","10","7","13","7","76"
+"272.8","57","male","partner","never","Active","guideline","no","no","no","0","4","no","no","no","no","no","259.84","2","9","8","9","8","14","2","100"
+"35.25","85","female","alone","ever","Active","guideline","no","yes","no",NA,"23","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"68.09","83","female","alone",NA,"Placebo",NA,"no","yes","no","0","5","no","no","no","no","no","92","1",NA,"10","13","12","10","8","84"
+"137.52","77","female","alone","ever","Active","guideline","no","no","no","0","5","yes","no","no","no","no","241.65","1","10","13","10","7","5","4","64"
+NA,"76","female","alone","never","Active","guideline","no","yes","no","1","7","no","no","no","no","no","30","3","16","14","20","10","6","11","28"
+"227.91","54","male","partner","ever","Active","guideline","no","no","no","0","4","yes","no","no","no","no","206.06","2","15","12","12","9","8","5","72"
+"56.4","78","female","alone","ever","Active","guideline","yes","yes","no","0","11","yes","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"16","85","male","partner","never","Active","guideline","no","yes","no",NA,"2","no","no","no","no","no","4.51","3","4","11","17","6","5","4","84"
+"135.1","82","male","partner","ever","Placebo","more","no","no","no","1","3","yes","no","no","no","no","144.77","1","12","11","6","5","4","4","72"
+NA,"80","male","partner","never","Placebo","more","yes","yes","no","0","12","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"42.63","91","female","alone","never","Placebo","guideline","no","yes","yes","0","0","no","yes","no","no","no","42.63","1","20","16","19","12","4","7","36"
+"52.2","78","male","alone","never","Placebo","guideline","no","yes","no","0","4","no","no","no","no","no","171.56","3","10","11","13","14","6","6","64"
+"0","78","male","partner","never","Placebo","guideline","no","yes","no","1","2","no","no","no","no","no","14.86","4","11","19","17","7","11","1","84"
+"155.19","77","male","partner","ever","Placebo","guideline","no","yes","no","1","2","yes","no","no","no","no","107.5","2","18","19","18","9","13","12","40"
+"38.2","71","male","partner","never","Placebo","guideline","no","yes","yes","0","1","no","no","no","no","no","95","1","20","16","16","16","12","24","64"
+"135.69","66","male","partner","never","Active","guideline","no","no","yes","0","2","no","no","no","no","no","139.86","2","9","13","8","10","9","12","68"
+"205.6","55","male","alone","never","Placebo","guideline","no","yes","yes","0","2","no","no","no","no","no","60","1","17","20","20","14","9","8","40"
+"81.67","71","female","alone","never","Placebo","guideline","no","yes","no","0","5","no","no","no","no","no","44.16","3","16","20","17","4","17","20","20"
+"85.05","84","male","partner","never","Placebo","more","no","no","no","1","2","yes","no","no","no","no","128.11","1","5","5","7","8","8","5","88"
+"71.6","80","male","alone",NA,"Placebo","guideline","yes","yes","yes","0","3","yes","no","yes","no","no","151","1","16","12","14","6","10","5","80"
+"101.74","71","female","alone","never","Active","guideline","no","yes","no","0","0","no","no","no","no","no","27.9","1","12","14","14","13","13","6","88"
+"290.56","69","male","partner","never","Active","more","no","no","no","0","1","no","no","no","yes","no","254.35","1","7","9","10","7","6","3","80"
+"251.2","62","male","partner","never","Active","guideline","no","no","no","0","2","yes","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"274.11","57","male","partner",NA,"Placebo",NA,"yes","yes","yes","0","7","yes","yes","yes","no","no","358.76","0","9","6","12","7","6","3","64"
+"226","61","male","alone","ever","Placebo","guideline","no","yes","no","0","5","yes","no","no","no","no","275.76","0","4","8","9","8","4","0","92"
+"59.56","75","male","alone","never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","135.72","2","6","6","5","4","8","6","92"
+"53.11","93","female","alone","never","Placebo","guideline","no","yes","no","1","2","no","no","no","no","no","39.03","2","18","18","16","9","9","9","56"
+"150.6","86","male","partner","never","Placebo","guideline","no","no","no","0","3","no","yes","no","no","no","111","1","10","12","12","11","11","5","64"
+"119.76","84","male","alone","ever","Placebo","guideline","no","yes","no","0","2","yes","no","no","no","no","74.76","2","12","14","10","4","5","11","72"
+"101.4","80","male","partner","never","Placebo","guideline","no","yes","yes","2","4","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"186.56","70","male","partner","never","Placebo","guideline","no","yes","no","0","2","yes","no","no","yes","no","249.46","2","14","15","12","10",NA,"20","72"
+"337.8","68","female","partner",NA,"Active","guideline","no","no","no","2","1","yes","no","no","no","no","181.72","2","5","4","5","5","4","0","92"
+"170.05","40","female","partner","never","Placebo","guideline","no","no","no","0","15","no","no","yes","no","no","27.2","4","14","10","12","7","6","17","76"
+"95.8","77","female","partner","ever","Placebo","guideline","no","no","no","1","7","yes","no","no","no","no","131.8","1","15","9","5","7","4","12","100"
+"120.65","70","female","partner","never","Placebo","guideline","no","no","no","0","6","yes","no","no","no","no",NA,"4","12","20","16","8","18","14","72"
+"108.2","84","male","partner","ever","Active","guideline","yes","yes","yes","0","9","no","no","no","no","no","112.08","4","8","16","18","10","11","5","40"
+"188.16","71","male","partner","never","Active","guideline","yes","yes","no","0","9","no","no","no","no","no","183.93","4","5","9","11","5","7","3","80"
+"362.13","44","male","partner","never","Placebo","guideline","no","no","no","0","2","yes","no","no","no","no","241.4","2","14","14","13","9","10","16","68"
+"228.61","80","male","partner","never","Active","guideline","no","no","no","0","3","no","no","no","no","no","313.27","2","14","9","10","9","10","8","76"
+"65","65","female","alone","never","Active","guideline","no","yes","no","0","4","no","no","no","no","no","153.05","3","17","16","12","7","9","4","76"
+"259.53","60","male","partner","never","Placebo","more","no","yes","no","0","4","no","no","no","no","no","169.75","3","4","6","5","5","8","4","92"
+"272.72","69","female","alone","never","Placebo","guideline","no","yes","no","0","1","no","no","no","no","no","27.2","2","15","13","7","4","6","9","92"
+"169.6","47","male","partner","never","Placebo","guideline","no","no","no","0","1","yes","no","no","no","no","139.57","2","9","11","10","7","12","11","92"
+"88.31","63","male","partner","never","Placebo","more","no","yes","no","0","3","yes","no","no","no","no","81.41","2",NA,NA,NA,NA,NA,NA,NA
+"236","57","male","alone","never","Placebo","more","no","no","no","0","1","no","no","no","no","yes","217","1","4","12","14","8","9","2","88"
+"78.44","78","female","partner","never","Active","guideline","yes","yes","no","0","12","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"249.6","33","male",NA,NA,"Active",NA,NA,NA,"no","0","1","no","no","no","no",NA,"205.02","1","4","6","6","5","7","1","84"
+"94.6","81","female","alone","ever","Active","guideline","no","yes","no","1","2","no","no","no","yes","no","35.91","3","18","19","20","16","10","23","48"
+"194.12","70","male","partner","never","Placebo","guideline","no","no","no","0","0","no","no","no","no","no","191.8","1","16","14","15","10","7","11","60"
+"205.6","68","female","alone","ever","Placebo","guideline","no","no","no","0","3","yes","no","no","no","no","258.55","1","10","5","5","4","4","5","92"
+"139.3","67","female","alone","never","Placebo","guideline","yes","no","no","0","12","yes","no","yes","no","no","245.73","2","13","17","13","4","6","6","68"
+"217.87","73","male",NA,NA,"Active",NA,NA,NA,"no","0","4","no","no","no","no",NA,"169.58","1","9","8","13","6","4","2","96"
+"219.76","36","male","partner","ever","Active","guideline","no","no","no","0","0","no","no","no","no","no","161.4","2","18","20","17","7","11","8","56"
+"106.98","78","female","partner","never","Active","guideline","no","yes","no","0","4","no","no","no","no","no","199.56","2","6","16","12","9","13","5","76"
+"50","71","female","partner","never","Active","guideline","no","yes","no","0","1","no","no","no","no","no","52.2","3","17","20","19","11","8","14","48"
+"52.2","38","male","partner","ever","Placebo","guideline","no","no","no","0","5","yes","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"85.45","79","male","partner","never","Active","guideline","no","yes","no","0","6","no","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"59.56","78","female","partner","ever","Active","more","no","yes","no","0","7","yes","no","no","no","no","110.2","4","16","17","17","8","12","12","68"
+"168.6","77","female","partner","ever","Active","guideline","no","yes","no","0","16","no","no","no","no","no","0","4","16","18","19","7","16","18","52"
+"232","63","male","partner","ever","Placebo","guideline","no","yes","yes","0","3","no","no","no","no","no","162.08","2","14","19","19","8","17","15","68"
+"116.73","77","male","partner","never","Placebo","guideline","no","yes","yes","0","8","yes","no","yes","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"89.12","75","male","partner","never","Active","guideline","no","yes","no","0","6","no","no","no","no","no","159.71","1","13","10","16","10","6","13","64"
+"50","68","female","alone","never","Active","guideline","no","no","no","0","2","no","no","no","no","no","129.1","0","12","15","11","10","6","4","72"
+"199.72","56","male","partner","never","Active","guideline","no","no","no","0","2","yes","no","no","no","no","172.25","1","18","13","10","4","9","7","76"
+"176.89","83","female","alone","never","Active","guideline","no","yes","no","0","5","no","no","no","no","no","138.53","0","13","8","7","8","10","2","92"
+"143.71","71","male","partner","never","Placebo","more","no","no","no","0","5","no","no","no","no","no","68.25","1","20","17","20","13","8","19","16"
+"148.11","68","male","partner","never","Active","more","no","yes","no","2",NA,"no","no","no","no","no","58.6","2","20","20","20","20","16","45","4"
+"91.4","74","male","partner","ever","Placebo","guideline","no","yes","no","0","5","no","no","no","yes","no","170.79","1","13","11","8","5","6","3","76"
+"406.8","79","female","alone",NA,"Placebo",NA,"no","yes","no","0","21","no","yes","no","no","no","0","4","10","16","10","12","4","15","20"
+"58.6","69","male","partner","ever","Placebo","guideline","yes","yes","no","0","17","yes","no","no","no","no","149.77","1","14","13","15","4","4",NA,"56"
+"162.99","67","female","partner","never","Active","guideline","no","no","no","0","4","yes","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"108.2","76","female","alone","never","Active","guideline","yes","no","no","2","2","no","no","no","no","no","27.2","2","11","12","13","8",NA,"12","52"
+"119.51","48","female","partner","never","Active","guideline","no","no","no","0","15","yes","no","yes","no","no","167.11","2","14","5","14","6","12","6","68"
+"475.61","67","male","partner","never","Active","guideline","no","yes","no","0","1","no","no","no","yes","no","250","0","5","6","5","6","4","3","72"
+"31.4","82","female","alone","never","Placebo","guideline","no","yes","no","0","5","no","no","no","no",NA,NA,"4",NA,NA,NA,NA,NA,NA,NA
+"161.86","70","female","partner","never","Placebo","guideline","no","no","no","1","7","yes","no","no","no","no","96.86","2",NA,"5","4","4",NA,"5","84"
+"25","94","female","alone","ever","Placebo","guideline","yes","yes","no",NA,"12","no","no","no","no","no",NA,"4","13","19","19","4","4","32","80"
+"54.51","93","female","alone","never","Placebo","guideline","yes","yes","no","0","7","no","no","no","no","no",NA,"5","15","15","7","8","4","18","28"
+"144.6","53","male","partner","never","Placebo","guideline","no","yes","no","0","3","no","no","no","no","no","60.4","3","4","6","8","4","8","0","100"
+"55","42","male","alone","never","Active","guideline","no","no","no","0","2","yes","no","no","no","yes","58.6","1","18","19","15","16","7","8","48"
+"294.3","56","male","partner","never","Placebo","guideline","no","yes","no","0","5","yes","no","no","no","no",NA,"1","6","6","6","4","5","5","88"
+"110.8","61","female","partner","never","Active","guideline","no","yes","yes","0","22","yes","no","yes","no","no",NA,"6",NA,NA,NA,NA,NA,NA,NA
+"256.8","59","female","alone","never","Placebo","guideline","no","no","no","0","0","no","no","no","no","no","95.8","1","14","10","12","4","10","10","64"
+"232.91","69","female","partner","ever","Active","guideline","no","yes","no","2","5","yes","no","no","no","no","240.34","2","16","15","17","9","16","10","44"
+"264.65","47","male","partner","ever","Active","guideline","no","no","no","0","3","yes","no","no","no","no","305.28","1","16","15","14","10","9","4","68"
+"93.44","44","male","alone","never","Active","more","no","no","no","0","3","no","no","no","no","no","161.94","3","12","11","12","11","13","7","64"
+"132.5","69","male","partner","ever","Placebo","guideline","no","no","no","0","2","yes","no","no","no","no","179.53","0","12","6","10","10","11","6","60"
+"78.08","77","female","partner","never","Placebo","guideline","no","yes","no","0","15","yes","no","yes","no","no",NA,"1",NA,NA,NA,NA,NA,NA,NA
+"108.6","75","male","alone","ever","Placebo","guideline","no","no","no","0","1","yes","no","no","no","no",NA,"2","14","15","15","10","9","6","36"
+"33.93","86","female","alone","ever","Placebo","guideline","yes","no","no","2","24","yes","no","no","no","no","0","4","10","20","11","8","11","2","68"
+"574.26","70","male","partner","never","Placebo","guideline","no","yes","no","0","2","no","no","no","no","no","225.16","1","8","7","6","6","6","3","80"
+"309.5","56","male","partner","never","Active","guideline","no","no","no","0","1","yes","no","no","no","no","415.76","1","13","8","11","7","11","5","76"
+"247","48","female","partner","never","Placebo","guideline","no","no","no","0","12","yes","no","no","no","no","138.2","2","15","13","17","9","5","3","68"
+"136","55","male","partner","never","Active","guideline","no","no","no","0","13","yes","no","yes","no","no","172.2","0","13","7","13","7","7","6","52"
+"302.8","45","male","alone","never","Active","guideline","no","yes","no","0","0","no","no","no","no","no","101.4","2","12","17","13","9","7","4","92"
+NA,"79","male","partner","ever","Active","guideline","yes","yes","no","0","19","yes","no","yes","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"173.2","81","male","partner","never","Placebo","guideline","no","no","no","0","5","no","no","no","no","no","111.4","1","10","13","12","8","8","7","84"
+"129.11","79","male","alone","ever","Placebo","guideline","no","yes","no","0","1","no","no","no","yes","no","395.56","0","10","6","9","12","6","7","96"
+"218.23","57","male","alone","ever","Placebo","guideline","no","no","no","0","12","no","no","no","no","no","216.36","2","8","16","4","4","20","1","44"
+"229.16","83","male","alone","ever","Active","guideline","no","no","no","0","11","no","no","no","no","no","256.23","4","12","9","9","5","4","1","100"
+"136","82","male","alone","never","Placebo","guideline","no","yes","yes","1","18","no","no","no","no","no",NA,"4","17","20","20","4","4","18","16"
+"61","79","male","partner","never","Placebo","guideline","no","yes","no","2","2","no","yes","no","yes","no","27.2","2",NA,NA,NA,NA,NA,NA,NA
+"221.8","77","male","alone","never","Active","guideline","yes","yes","no","0","22","no","no","no","no","no","41.55","4",NA,NA,NA,NA,NA,"4","52"
+"149.16","49","male","partner","never","Placebo","guideline","no","no","no","1","2","no","no","no","no","no","256.55","2","10","7","6","6","5","1","80"
+"373.58","47","male","partner","ever","Active","guideline","no","no","no","0","6","yes","no","no","no","no","176.61","2","19","14","16","13","18","24","28"
+"204.6","81","female","alone","never","Active","guideline","no","no","no","0","6","no","no","no","no","no","115.03","1","17","9","13","5","5","9","60"
+"173.2","24","female","partner","ever","Active","guideline","no","no","no","0","1","no","no","no","no","no","171.2","2","10","13","8","8","6","6","64"
+"121","70","male","partner","never","Active","more","no","no","no","0","2","no","no","no","yes","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"0","68","male","partner","ever","Placebo","guideline","yes","yes","yes","0","8","no","no","no","no","no",NA,"2","7","13","12","7","4","4","16"
+"121.4","80","male","partner","never","Active","guideline","no","no","no","0","5","no","no","no","no","no","4.51","2","5","6","7","7","4","0","88"
+"46","67","male","partner","never","Active","guideline","no","yes","no","1","18","yes","yes","no","no","no",NA,"4","18","20","20","9","4","18","68"
+"206","55","male","alone","ever","Active","guideline","no","no","no","0","1","no","no","no","no","no",NA,"1","9","10","8","4","4","6","88"
+"160.11","77","male","partner","ever","Placebo","guideline","no","no","no","0","4","no","no","yes","no","no","124.44","1","9","13","13","8","9","6","68"
+"60.61","71","female","partner","never","Active","guideline","no","yes","no","0","5","no","no","no","no","no","58.94","1","20","13","15","11","4","22","24"
+"128.49","63","female","partner","never","Placebo","guideline","no","yes","no","0","3","no","no","no","no","no","95.05","0",NA,NA,NA,NA,NA,NA,NA
+"5","62","male","partner","ever","Placebo","guideline","no","yes","yes","2","19","yes","no","no","yes","no","103.93","2","18","15","18","12","16","36","36"
+"98.17","61","male","partner","never","Active","more","no","yes","no","0","2","no","no","no","no","yes","157.12","3","5","10","5","8","9","9","80"
+"282.4","77","female","alone","never","Placebo","guideline","yes","yes","no","0","11","yes","no","no","no","no","180.6","3","11","9","9","7","5","9","72"
+"110.8","77","male","partner","never","Placebo","guideline","no","no","no","0","1","no","no","no","no","no","58.6","1","11","7","7","7","5","7","72"
+"166.8","90","male","alone","never","Placebo","more","yes","yes","no","0","10","no","no","no","no","no","58.6","3","13","10","13","10","15","6","80"
+"162.45","71","female","alone","ever","Placebo","guideline","no","yes","no","0","1","yes","no","no","no","no","160.89","1","5","6","5","5","4","1","92"
+"156","68","female","alone","never","Active","more","no","yes","no","0","12","yes","no","no","no","no","85.69","2","4","4","4","8","11","1","100"
+"390.27","62","male","partner","ever","Active","guideline","no","no","yes","0","2","no","no","no","no","no","240.19","2","8","15","8","8","4","12","100"
+"155.96","57","male","partner","never","Placebo","guideline","no","no","no","0","1","no","no","no","no","no","151.06","1","10","7","12","8","6","8","64"
+"58.6","72","male","alone","never","Placebo","more","no","no","no","0","7","no","no","no","no","no",NA,"2","15","18","15","6","4","5","56"
+"179.87","79","male","partner","never","Placebo","guideline","no","no","no","0","3","no","no","no","yes","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
+"75.8","76","female","partner","never","Active","guideline","no","yes","no","0","3","no","no","no","no","no","59.7","2","19","14","18","8","4","8","64"
+"0","67","male","partner","never","Active","guideline","no","no","no","0","3","no","no","no","no","no","119.05","2","6","14","10","8","10","5","80"
+"131.8","66","male","partner","never","Placebo","guideline","no","no","no","0","1","no","no","no","no","no","101.4","1","10","10","8","7","5","4","76"
+"95.8","83","female","partner","never","Active","more","no","yes","no","1","2","no","no","no","no","no","56.4","2","10","12","20","9","5","15","24"
+"90","71","male","alone","never","Placebo","guideline","no","no","no","0","6","no","no","no","no","no","55","1","4","4","4","8","8","4","100"
+"67.63","68","male","alone","never","Placebo","guideline","no","yes","no","1","2","yes","no","no","no","no","137.89","2","8","11","9","5","8","3","84"
+"162.72","52","male","partner","never","Placebo","more","no","yes","no","0","3","yes","no","no","no","no","347.78","0","6","6","7","6","6","3","76"
+"227.33","80","male","partner","never","Active","guideline","no","yes","no","0","2","no","no","no","no","no","284.33","1","6","4","8","4","4",NA,"100"
+"168.48","84","male","partner","never","Placebo","guideline","yes","yes","yes","1","1","no","no","no","no","no","152.72","1","10","9","8","8","8","6","76"
+"229.2","50","male","partner","never","Placebo","guideline","no","no","no","0","3","no","no","no","no","no",NA,"2","11","10","14",NA,"15","16","76"
+"197.15","44","male","partner","ever","Placebo","guideline","no","no","no","0","7","yes","no","no","no","no","245.75","1","8","4","9","5","7","6","76"
+NA,"63","male","partner","never","Placebo","guideline","no","no","no","0","2","yes","no","no","no","no",NA,NA,NA,NA,NA,NA,NA,NA,NA
diff --git a/2 Longterm/dags.R b/2 Longterm/dags.R
new file mode 100644
index 0000000..0ee21c8
--- /dev/null
+++ b/2 Longterm/dags.R
@@ -0,0 +1,145 @@
+## Everything
+
+dag <- 'dag {
+ bb="-4.79,-6.035,4.818,5.504"
+ SES [pos="-4.463,-2.925"]
+ ad_treat [pos="2.007,-1.567"]
+ afli [pos="0.028,-1.851"]
+ age [pos="-1.242,-0.765"]
+ alc [pos="-3.716,-0.111"]
+ ami [pos="-3.137,3.986"]
+ civil [pos="-4.099,0.703"]
+ diabetes [pos="-3.838,3.579"]
+ education [pos="-3.632,-3.678"]
+ gen_PA [pos="-2.820,-1.247"]
+ hypertension [pos="-4.034,2.468"]
+ mrs_0 [pos="-1.746,2.715"]
+ mrs_1 [pos="1.326,-0.469"]
+ nihss_0 [pos="0.271,1.296"]
+ pase_0 [exposure,pos="-0.542,0.173"]
+ revasc [pos="0.980,2.332"]
+ rtreat [pos="2.334,2.036"]
+ sex [pos="-4.538,-0.778"]
+ smoker [pos="-1.877,-2.160"]
+ stroke [adjusted,pos="0.766,0.321"]
+ svd [latent,pos="-2.400,1.493"]
+ tci [pos="-2.418,4.467"]
+ vasc_event [outcome,pos="3.754,0.358"]
+ SES -> ad_treat
+ SES -> age
+ SES -> alc
+ SES -> gen_PA
+ SES -> stroke
+ SES -> vasc_event
+ ad_treat -> vasc_event
+ afli -> pase_0
+ afli -> stroke
+ afli -> vasc_event
+ age -> afli
+ age -> civil
+ age -> mrs_1
+ age -> nihss_0
+ age -> vasc_event
+ alc -> hypertension
+ alc -> pase_0
+ alc -> stroke
+ alc -> svd
+ alc -> vasc_event
+ ami -> afli
+ ami -> mrs_0
+ ami -> stroke
+ ami -> vasc_event
+ civil -> pase_0
+ civil -> stroke
+ civil -> vasc_event
+ diabetes -> mrs_0
+ diabetes -> nihss_0
+ diabetes -> stroke
+ diabetes -> svd
+ diabetes -> vasc_event
+ education -> SES
+ education -> ad_treat
+ education -> age
+ education -> alc
+ education -> gen_PA
+ education -> stroke
+ education -> vasc_event
+ gen_PA -> ami
+ gen_PA -> diabetes
+ gen_PA -> hypertension
+ gen_PA -> pase_0
+ gen_PA -> smoker
+ gen_PA -> tci
+ hypertension -> afli
+ hypertension -> mrs_0
+ hypertension -> nihss_0
+ hypertension -> stroke
+ hypertension -> svd
+ hypertension -> vasc_event
+ mrs_0 -> pase_0
+ mrs_0 -> revasc
+ mrs_1 -> ad_treat
+ mrs_1 -> vasc_event
+ nihss_0 -> revasc
+ pase_0 -> ad_treat
+ pase_0 -> nihss_0
+ pase_0 -> stroke
+ revasc -> mrs_1
+ rtreat -> mrs_1
+ rtreat -> vasc_event
+ sex -> ad_treat
+ sex -> alc
+ sex -> education
+ sex -> mrs_1
+ sex -> pase_0
+ sex -> stroke
+ sex -> vasc_event
+ smoker -> age
+ smoker -> mrs_1
+ smoker -> vasc_event
+ stroke -> mrs_1
+ stroke -> nihss_0
+ stroke -> rtreat
+ stroke -> vasc_event
+ svd -> mrs_0
+ svd -> pase_0
+ svd -> vasc_event
+ tci -> mrs_0
+ tci -> stroke
+ tci -> vasc_event
+}'
+
+
+## Simplified
+
+dag <- 'dag {
+bb="-4.79,-6.035,4.818,5.504"
+"Higher SES" [pos="-1.671,-1.740"]
+"U: higher svd score" [latent,pos="-3.091,2.172"]
+"active treat" [pos="1.914,3.209"]
+"higher PA" [exposure,pos="-0.999,0.555"]
+"lower mrs_0" [pos="-2.437,1.259"]
+ad_treat [pos="-0.448,-0.358"]
+cardio_vasc [pos="-4.202,0.839"]
+male [pos="-3.119,-0.926"]
+vasc_event [outcome,pos="3.754,0.358"]
+"Higher SES" -> "higher PA"
+"Higher SES" -> ad_treat
+"Higher SES" -> vasc_event
+"U: higher svd score" -> "lower mrs_0"
+"U: higher svd score" -> vasc_event
+"active treat" -> vasc_event
+"higher PA" -> ad_treat
+"higher PA" -> vasc_event
+"lower mrs_0" -> "higher PA"
+ad_treat -> vasc_event
+cardio_vasc -> "U: higher svd score"
+cardio_vasc -> "higher PA" [pos="-2.876,-0.185"]
+cardio_vasc -> "lower mrs_0"
+cardio_vasc -> vasc_event [pos="-4.762,5.060"]
+male -> "higher PA"
+male -> vasc_event [pos="-2.540,-5.134"]
+}'
+
+dag |> ggdag::ggdag_adjustment_set(node_size = 14, text_col = "black") +
+ theme(legend.position = "bottom")
diff --git a/2 Longterm/data.R b/2 Longterm/data.R
new file mode 100644
index 0000000..5d286a6
--- /dev/null
+++ b/2 Longterm/data.R
@@ -0,0 +1,260 @@
+##
+## Data pull and export for Forskermaskinen
+##
+## Exports are made in REDCap instead
+##
+## Data set is made here, not in REDCap, as data here is better organised.
+##
+
+library(haven)
+library(dplyr)
+library(purrr)
+
+## All data
+# source("2 Longterm/data_import_files.R")
+source("/Users/au301842/PAaSO/2 Longterm/data_import_api.R")
+
+## Helpers
+source("/Users/au301842/PAaSO/2 Longterm/funs.R")
+
+# Streamlining missings for easier handling
+
+# NA values
+## Empty fields ("") are not included as NA, to ease later corrections.
+nas <- c("9.", "9. NA", "Not available", "Not relevant (filter/fold)")
+
+# Replaces all NAs in factors, and rejoins data frame
+# Factors keeps old levels; doesn't matter when exported as .csv and reimported...
+ls_nas <- lapply(seq_along(ls_sel), function(i) {
+ ds <- ls_sel[[i]] |> select(starts_with("talos_")
+ # & where(is.factor)
+ ) |>
+ data.frame()
+
+ ds_n <- lapply(seq_len(ncol(ds)),function(j){
+ as.character(if_else(ds[,j] %in% nas, NA, ds[,j]))
+ }) |> bind_cols()
+
+ colnames(ds_n) <- colnames(ds)
+
+ ds_sub <- ls_sel[[i]] |> select(-colnames(ds_n))
+
+ ds_fin <- tibble(ds_sub,ds_n)
+
+ ds_fin |> select(colnames(ls_sel[[i]])) |> select(-grep("[0-9]x$",colnames(ls_sel[[i]])))
+})
+
+names(ls_nas) <- names(ls_sel)
+
+
+
+## MFI domain scores
+
+# MFI variables to reverse
+# -> Create MFI function
+mfi_rev <- tolower(c("TALOS_MFI02","TALOS_MFI05","TALOS_MFI09","TALOS_MFI10","TALOS_MFI13","TALOS_MFI14","TALOS_MFI16","TALOS_MFI17","TALOS_MFI18","TALOS_MFI19"))
+
+match(mfi_rev,colnames(ls_nas$mfi|> select(matches(paste0("talos_mfi",stRoke::add_padding(1:20))))))
+
+domain_scores <- ls_nas$mfi |> select(matches(paste0("talos_mfi",stRoke::add_padding(1:20)))) |> mfi_domains(var = mfi_rev)
+
+colnames(domain_scores) <- paste0("talos_mfi_",colnames(domain_scores))
+
+ls_nas$mfi <- tibble(ls_nas$mfi,domain_scores)
+
+## SDMT score correction
+
+# Correction table
+#
+# Holds manually determined 90 second times, additionally, "2015-02-18" is used
+# as cut date for change from 60 seconds to 90 seconds
+#
+#
+
+if (FALSE){
+sdmt_time<-openxlsx::read.xlsx("/Volumes/Data/source/tid.sdmt.xlsx") |>
+ tidyr::pivot_longer(cols = c(tid.1md, tid.6md)) |> mutate(deltager=as.character(deltager))
+sdmt_time$name <- as.double(as.character(factor(sdmt_time$name,labels = c("2","4"))))
+
+# Setting cut date
+sdmt_cut<-as.Date("2015-02-18")
+
+# Joining datasets to have date of visit
+sdmt_corr <- left_join(ls_nas$sdmt,sdmt_time |> mutate(name=as.character(name)), by = c("rnumb"="deltager","instance"="name"))
+
+# Modyfying old correction table to be complete
+sdmt_corr$value <- if_else(sdmt_corr$talos_sdmt00 select(ends_with(pase_index)) |>
+ pase_calc(adjust_work = FALSE)
+
+ensure_prefix <- function(vec,prefix){
+ ifelse(!grepl(paste0("^",prefix),vec),paste0(prefix,vec),vec)
+}
+
+colnames(pase_scores) <- colnames(pase_scores)# |> ensure_prefix(prefix="pase_")
+
+last_cols <- function(ds, n){
+ ds[,(ncol(ds)-n+1):ncol(ds)]}
+
+pase_scores_work <- ls_nas$pase |> select(ends_with(pase_index)) |>
+ pase_calc(adjust_work = TRUE) |> last_cols(4) %>%
+ rename_with(~ paste0(., "_w"))
+
+colnames(pase_scores_work) <- colnames(pase_scores_work) #|> ensure_prefix(prefix="pase_")
+
+ls_nas$pase <- tibble(ls_nas$pase,pase_scores,pase_scores_work)
+
+## Registration correction
+
+# Mutate all ends_with "00" as.Date in original data import file
+# source("2 Longterm/funs.R")
+
+ls_corr <- lapply(ls_nas,time_reg_correction, ref=subjects)
+
+run_eval=FALSE
+if (run_eval){
+library(compareDF)
+
+ls_comp <- lapply(seq_along(ls_nas),function(i){
+ compare_df(ls_corr[[i]],ls_nas[[i]],group_col = c("rnumb","instance"),stop_on_error = FALSE)
+})
+
+ls_comp[[1]] |>
+ create_output_table()
+}
+
+ls_wide <- ls_corr |> longlist2wide()
+
+df_wide <- ls_wide |> purrr::reduce(full_join,by="rnumb")
+
+## The final assembly
+
+df_ddv <- subjects |>
+ mutate(rnumb=as.character(rnumb)) |>
+ left_join(df_wide %>%
+ ## Keep only first "SITE" occurance
+ ## Using magrittr pipe for easy placeholder use
+ select(-grep("_site_",colnames(.))[-1])
+ )
+
+# write.csv(df_ddv,"/Volumes/Data/REDCap/DDV/talos_ddv.csv",row.names = FALSE)
+
+
+## Generate data description
+attr_files <- list.files("/Users/au301842/PAaSO/REDCap/attr",pattern = ".csv$",full.names = TRUE)
+attr_files_short <- list.files("/Users/au301842/PAaSO/REDCap/attr",pattern = ".csv$",full.names = FALSE)
+
+nms <- do.call(c,lapply(strsplit(attr_files_short,"_"),"[[",2)) |> gsub("['.']csv","",x=_) |> tolower()
+
+attr_lst <- lapply(attr_files,read.csv)
+names(attr_lst) <- nms
+
+attr_df <- lapply(seq_along(attr_lst),function(i){
+
+ data.frame(name = tolower(ifelse(
+ !grepl("^TALOS|cpr|record_id", attr_lst[[i]][, 1]),
+ paste0(nms[i], "_", attr_lst[[i]][, 1]),
+ attr_lst[[i]][, 1]
+ )),
+ attr = attr_lst[[i]][, 2],
+ instr = paste(toupper(nms[i]),"instrument"))
+
+}) |> bind_rows()
+
+attr_df$attr[grepl("sys_date$",attr_df$name)] <- "System date"
+attr_df$attr[grepl("sys_site$",attr_df$name)] <- "Trial site"
+attr_uni <- attr_df[!duplicated(attr_df$name),]
+
+# data.frame(variabel=colnames(df_ddv),
+# visit=stRoke::str_extract(colnames(df_ddv),"[0124]$"),
+# attr_df[match(gsub("_[0124]$","",colnames(df_ddv)),attr_df$name),-1]) |>
+# write.csv("REDCap/ddv_variabelbeskrivelse_raw.csv",row.names = FALSE)
+#
+# read.csv("REDCap/ddv_variabelbeskrivelse.csv") |>
+# filter_at(1,all_vars(.%in%colnames(df_ddv))) |>
+# write.csv("REDCap/ddv_variabelbeskrivelse_mod.csv",row.names = FALSE)
+
+
+is.na(ds$talos_pase01_0) |> summary()
+
+
+
+## Cumulated data
+
+# dta<-read.csv("/Volumes/Data/exercise/source/background.csv",colClasses = "character", na.strings = c("NA","","unknown"))
+#
+# export<-dta[,c("pase_0",
+# "age",
+# "sex",
+# "civil",
+# "smoker",
+# "rtreat",
+# "alc",
+# "afli",
+# "hypertension",
+# "diabetes",
+# "mrs_0",
+# "nihss_c",
+# "thrombolysis",
+# "pad",
+# "thrombechtomy",
+# "ami",
+# "tci",
+# "rdate",
+# "cpr",
+# "rnumb",
+# "height",
+# "weight",
+# "weight_est",
+# "inc_time",
+# "compliant",
+# "mrs_1",
+# "mrs_6",
+# "pase_6",
+# "visit_1",
+# "visit_6")]
+
+# export$diabetes[is.na(export$diabetes)]<-"no"
+# export$hypertension[is.na(export$hypertension)]<-"no"
+# export$thrombolysis[is.na(export$thrombolysis)]<-"no"
+# export$thrombechtomy[is.na(export$thrombechtomy)]<-"no"
+# export$pad[is.na(export$pad)]<-"no"
+# export$ami[is.na(export$ami)]<-"no"
+# export$inc_time[export$inc_time<0]<-0
+# export$compliant<-as.numeric(factor(export$compliant))
+# export$rdate<-as.Date(export$rdate)
+# export$mrs_0[export$mrs_0==3]<-NA
+
+# export <- export|>
+# mutate(any_rep=factor(ifelse(thrombolysis=="yes"|thrombechtomy=="yes","yes","no")), # If not noted, no therapy was received
+# weight=ifelse(is.na(weight),weight_est,weight))|>
+# select(-c(weight_est))
+#
+# dput(names(export))
+
+# write.csv(export|>select(c(rnumb,rtreat)),"/Volumes/Data/SDS upload/study_treatment.csv",row.names = FALSE)
+# write.csv(export,"/Volumes/Data/SDS upload/data_all.csv",row.names = FALSE)
+# write.csv(export|>select(-c(rtreat)),"/Volumes/Data/SDS upload/background.csv",row.names = FALSE)
+
+# max(export$visit_6[!is.na(export$visit_6)])
+
+
diff --git a/2 Longterm/data_import_api.R b/2 Longterm/data_import_api.R
new file mode 100644
index 0000000..d73528c
--- /dev/null
+++ b/2 Longterm/data_import_api.R
@@ -0,0 +1,110 @@
+
+token=keyring::key_get("TALOS_REDCAP_API")
+
+## Primary data set of recorded data
+
+inst <- REDCapR::redcap_instruments(redcap_uri = "https://redcap.au.dk/api/",token = token)$data
+
+tools <- tolower(c(
+ "PASE",
+ "MFI",
+ "mdi",
+ "mmse",
+ "mrs",
+ "SDMT",
+ "who",
+ "ham",
+ "bi",
+ "grad",
+ "nihss"
+))
+
+vec_starts_with <- function(d,v){
+ filt <- paste0("^(", paste(v, collapse="|"), ")")
+
+ d[grep(filt,d)]
+}
+
+vec_ends_with <- function(d,v){
+ filt <- paste0("(", paste(v, collapse="|"), ")$")
+ # sub(paste0(".*?_(",paste(v,collapse = "|"),")$"),"\\1",colnames(d))
+ d[grep(filt,d)]
+}
+
+# vec_starts_with(inst$instrument_name,tools)
+
+data <- REDCapR::redcap_read(redcap_uri = "https://redcap.au.dk/api/",token = token,
+ forms = vec_starts_with(inst$instrument_name,tools),
+ fields = "record_id")$data
+
+ds <- data |> select(!ends_with("complete"))
+
+talos2long <- function(ds,exclude=c("talos","record"),instance_vals=c("0","1","2","4"),exclude_col_ends=c("user","lock")){
+ nms <- unique(do.call(c,lapply(strsplit(colnames(ds),"_"),"[[",1)))
+ nms <- nms[!nms %in% exclude]
+
+ ls <- lapply(seq_along(nms),function(i){
+ cols <- c("record_id",vec_starts_with(colnames(ds),c(paste0("talos_",nms[i]),nms[i])))
+
+ d <- select(ds,all_of(cols))
+
+ ends <- unique(do.call(c,lapply(strsplit(colnames(d),"_"),function(i){
+ i[length(i)]
+ })))
+
+ ins <- colnames(d) %in% vec_ends_with(colnames(d),paste0("_",instance_vals))
+
+ ls_ins <- split.default(d[-1],factor(stRoke::str_extract(colnames(d[ins]),paste0("[",paste(instance_vals,collapse=""),"]$"))))
+
+ dat <- lapply(seq_along(ls_ins),function(i){
+ dr <- cbind(d[1],instance=names(ls_ins)[i],ls_ins[[i]])
+ colnames(dr) <- unique(gsub(pattern = paste0("_[",paste(instance_vals,collapse=""),"]$"),"",colnames(dr)))
+ dr |> select(record_id,contains("_sys_"),instance,everything())
+ }) |> bind_rows() |> rename(rnumb=record_id) |> mutate(rnumb=as.character(rnumb))
+
+ ## Col name ending on 00 is date col of measure in all tools
+ dat[,vec_ends_with(colnames(dat),"00")] <- as.Date(dat[,vec_ends_with(colnames(dat),"00")])
+
+ dat |> select(!ends_with(exclude_col_ends))
+ })
+
+ names(ls) <- nms
+ ls
+
+}
+
+ls_sel <- data |> select(!ends_with("complete"))|> talos2long()
+
+## Data set of baseline and DAP data
+
+subjects_raw <-
+ REDCapR::redcap_read(
+ redcap_uri = "https://redcap.au.dk/api/",
+ token = token,
+ forms = vec_starts_with(inst$instrument_name, c("end", "inkl", "reg", "basis")),
+ fields = "record_id"
+ )$data
+
+subjects <- subjects_raw |>
+ select(
+ record_id,
+ talos_end00,
+ talos_end01,
+ rdate,
+ rtreat,
+ cpr,
+ basis_kon,
+ starts_with("reg_")
+ ) |> select(!ends_with("complete")) |>
+ rename(rnumb = record_id,
+ enddate = talos_end00,
+ eos_early = talos_end01,
+ sex=basis_kon) |>
+ mutate(
+ enddate = as.Date(enddate),
+ rdate = as.Date(rdate),
+ inc_time = as.numeric(difftime(enddate, rdate, units = "days")),
+ age = stRoke::age_calc(as.Date(stRoke::cpr_dob(cpr,"%Y-%m-%d")),enddate=rdate)
+ )
+
+# colnames(subjects) <- gsub("^reg_","",colnames(subjects))
diff --git a/2 Longterm/data_import_files.R b/2 Longterm/data_import_files.R
new file mode 100644
index 0000000..4c8ff26
--- /dev/null
+++ b/2 Longterm/data_import_files.R
@@ -0,0 +1,49 @@
+# Specifying needed data collection files
+data_source <- c(
+ "PASE_rev_v13.dta",
+ "MFI_rev_v13.dta",
+ "mdi_rev_v13.dta",
+ "mmse_rev_v13.dta",
+ "mrs_rev_v13.dta",
+ "SDMT_rev_v13.dta",
+ "who_rev_v13.dta"
+)
+
+## Cumulated data
+dta<-read.csv("/Volumes/Data/exercise/source/background.csv",colClasses = "character", na.strings = c("NA","","unknown"))
+
+# Getting full filenames
+file_nms <- list.files("/Volumes/Data/STATA13",full.names = TRUE)[match(data_source,list.files("/Volumes/Data/STATA13"))]
+
+# Loading datafiles
+
+dta<-read.csv("/Volumes/Data/exercise/source/background.csv",colClasses = "character", na.strings = c("NA","","unknown"))
+
+ls <- lapply(file_nms,function(i){
+ d <- read_dta(i)
+ colnames(d) <- tolower(gsub("instance","INSTANCE",colnames(d))) #in the sdmt dataset, instance column is lower case
+ d
+})
+
+# Selecting desired variables
+ls_sel <- lapply(seq_along(ls), function(i) {
+ ls[[i]] |> select(cpr,
+ SYS_SITE,
+ INSTANCE,
+ starts_with("TALOS_")) |> as_factor() |>
+ full_join(select(dta,cpr, rnumb)) |> select(rnumb,everything())
+})
+
+# Naming lists according to file names
+names(ls_sel) <- tolower(unlist(lapply(data_source,function(x){strsplit(x,"_")[[1]][1]})))
+
+## Screening list and EOS data
+subjects <- read_dta("/Volumes/Data/STATA13/inkl_rev_v13.dta") |>
+ select(c("cpr", "rnumb", "rdate", "rtreat")) |>
+ filter(rnumb != 999) |>
+ left_join(read_dta("/Volumes/Data/STATA13/end_rev_v13.dta") |>
+ select(c("cpr", "TALOS_end00", "TALOS_end01"))
+ ) |>
+ rename(enddate = TALOS_end00,
+ eos_early = TALOS_end01) |>
+ as_factor()
diff --git a/2 Longterm/flowchart.R b/2 Longterm/flowchart.R
new file mode 100644
index 0000000..2f41c81
--- /dev/null
+++ b/2 Longterm/flowchart.R
@@ -0,0 +1,33 @@
+data <- list(a=1000, b=800, c=600, d=400)
+
+
+DiagrammeR::grViz("
+digraph graph2 {
+
+graph [layout = dot]
+
+# node definitions with substituted label text
+node [shape = rectangle, width = 4, fillcolor = Biege]
+a [label = '@@1']
+b [label = '@@2']
+c [label = '@@3']
+node [shape = rectangle, width = 2, fillcolor = Biege]
+d [label = '@@4']
+e [label = '@@5']
+
+a -> b -> c [dir=s]
+a -> d [dir=e]
+b -> e [dir=e]
+# c -> f
+
+{rank=same; a -> b -> c [dir=s]}
+
+}
+
+[1]: paste0('All patients in TALOS (n = ', data$a, ')')
+[2]: paste0('Patients with PASE (n = ', data$b, ')')
+[3]: paste0('Patients with first event after follow-up (n = ', data$c, ')')
+[4]: paste0('Excluded due to missing PASE (n = ', data$d, ')')
+[5]: paste0('Excluded due to early event (n = ', data$d, ')')
+# [6]: paste0('Excluded due to missing PASE (n = ', data$d, ')')
+")
diff --git a/2 Longterm/funs.R b/2 Longterm/funs.R
new file mode 100644
index 0000000..4fa2b5a
--- /dev/null
+++ b/2 Longterm/funs.R
@@ -0,0 +1,248 @@
+
+## Utils
+
+multi_rev <- function(ds, var){
+ ndx <- match(var,colnames(ds))
+ for (i in seq_along(ndx)){
+ j <- ndx[i]
+ ds[[j]]<-as.character(factor(ds[[j]],labels = c(rev(levels(factor(ds[[j]]))))))
+ }
+ ds
+}
+
+reg2score <- function(ds){
+ # Removes all padding from registred scores
+ l <- c()
+ for (i in seq_len(ncol(ds))){
+ l[[i]] <- gsub("[^a-zA-Z0-9]","",ds[[i]])
+ }
+
+ d <- do.call(cbind,l) |> data.frame()
+
+ colnames(d) <- colnames(ds)
+ d |> tibble()
+}
+
+
+
+## MFI modding
+
+mfi_domains <- function(ds, reverse=TRUE, var){
+
+ # Subscore indexes
+ indexes <- list(
+ data.frame(grp="gen", ndx=c(1, 5, 12, 16)),
+ data.frame(grp="phy", ndx=c(2, 8, 14, 20)),
+ data.frame(grp="act", ndx=c(3, 6, 10, 17)),
+ data.frame(grp="mot", ndx=c(4, 9, 15, 18)),
+ data.frame(grp="men", ndx=c(7, 11, 13, 19))
+ ) |> bind_rows() |> arrange(ndx)
+
+ # Assumes reverse scores are not correctly reversed
+ if (reverse){ds <- ds |> multi_rev(var)}
+
+ # Removes padding and converts to numeric
+ d <- ds |> reg2score() |>
+ mutate_if(is.character, as.numeric)
+
+ split.default(d, factor(indexes$grp)) |>
+ lapply(function(x){
+ apply(x, MARGIN = 1, sum)
+ }) |> bind_cols()
+
+}
+
+## Registration correction
+
+# 1. If the inc_time is 38 days or less MDI 6 scores are moved to MDI 1 and visit 6 is defined as visit 1.
+# 2. If both visit 1 and 6 dates are NA, use enddate as visit 1 date. This is the case if patients were excluded early.
+# 3. If visit 6 is recorded later than enddate, use enddate instead. MDI 6 score is dropped.
+# 4. If visit delay is 7 days or less, and inclusion time is more than 38, MDI 1 is moved to MDI 6 and dropped. If MDI 1 and 6 are different both are kept. Enddate is moved to visit 6 date.
+# 5. Defining the visit 6 date as same as enddate if visit delay is <7.
+
+# ds <- ls_nas$mdi
+# ref <- subjects
+
+
+time_reg_correction <- function(ds, ref) {
+
+ # Splitting by rnumb, to treat each subj
+ ls <- split(ds, ds$rnumb)
+
+ # ref: https://r-coder.com/progress-bar-r/
+ # Setting up simple progress bar
+ pb <- txtProgressBar(min = 0, max = length(ls), style = 3)
+
+
+ # Getting the rnumbs for subsetting in order of the list
+ nms <- names(ls)
+ # Applying correction to each element in list
+ ls_c <- lapply(seq_along(ls), function(i) {
+ cat(paste(i,"af",length(ls)))
+ # Updates the current state
+ setTxtProgressBar(pb, i)
+
+ # Current rnumb
+ nm <- nms[i]
+ # print(i)
+ df <- ls[[i]]
+ # Only run if both instance 2 and 4 are present
+ if (all(c(2, 4) %in% select(df, matches("instance", ignore.case = TRUE))[[1]])) {
+
+ # Define common variables
+ inc_time <- as.numeric(ref$inc_time[ref$rnumb == nm])
+ end_date <- as.Date(ref$enddate[ref$rnumb == nm])
+ rdate <- as.Date(ref$rdate[ref$rnumb == nm])
+ inst <- grep("instance", tolower(colnames(df)))
+
+ # Define relevant data columns to substitute/modify
+ cols <- (inst + 1):ncol(df)
+
+ # Define date column index
+ date_col_index <-
+ match(colnames(select(df, ends_with("00"))), colnames(df))
+
+ # Step 1
+
+ ## Correction if inc_time is performed
+ if (inc_time <= 38 & all(is.na(df[df[inst] == 2, cols]))) {
+ # Substitutions to transfer instance 4 meassures and leave as NA
+ df[df[inst] == 2, cols] <- df[df[inst] == 4, cols]
+ df[df[inst] == 4, -c(inst,date_col_index)] <- NA
+ }
+
+ # Step 2
+
+ if (all(is.na(df[date_col_index]))) {
+ # If both visit dates are missing, instance 2 date is substituted with enddate
+ df[date_col_index][df[inst] == 2] <-
+ as.character(end_date)
+ }
+
+ # Step HELPA
+ ## Extra help step to impute enddate as visit 4 if instance 4 is present but no date.
+ if (is.na(df[date_col_index][df[inst] == 4])){
+ df[date_col_index][df[inst] == 4] <- as.character(end_date)
+ }
+
+ ## Last steps are only performed if date values are available for both instance 2 and 4
+ if (!any(is.na(df[date_col_index]))){
+
+ # Step 3
+ end_delay <- as.numeric(difftime(df[date_col_index][df[inst] == 4],
+ end_date,
+ units = "days"))
+
+ # If enddate is before last visit, the last visit data is dropped.
+ if (end_delay > 2) {
+ df[df[inst] == 4,-c(inst,date_col_index)] <- NA
+ }
+
+ # Step 4
+ visit_delay <-
+ as.numeric(difftime(df[date_col_index][df[inst] == 4], df[date_col_index][df[inst] ==
+ 2], units = "days"))
+
+ if (purrr::is_empty(visit_delay)){
+ visit_delay <- NA
+ }
+
+
+ ## Test if data has manually been inserted at visit 2, though should should be visit 4 time wise
+ second2fourth <-
+ if_else((visit_delay <= 7 |
+ all(is.na(df[df[inst] == 2, cols]))) &
+ inc_time > 38,
+ TRUE,
+ FALSE,
+ missing = FALSE)
+
+ ## Move data from 2. visit to 4.
+ if (second2fourth) {
+ # df[date_col_index][df[inst] == 2]
+
+ ## If all missing at last visit, 1. visit is copied
+ if (all(is.na(df[df[inst] == 4, cols]))) {
+ df[df[inst] == 4, cols] <- df[df[inst] == 2, cols]
+ }
+
+ ## If entries at visit 2 and 4 are identical, vist 2 is deleted
+ if (identical(df[df[inst] == 4, cols], df[df[inst] == 2, cols])) {
+ df[df[inst] == 2, -c(inst,date_col_index)] <- NA
+ }
+
+ ## If data entries are NA at visit 2, the date is also deleted
+ if (all(is.na(df[df[inst] == 2, cols]))) {
+ df[,date_col_index][df[inst] == 2] <- NA
+ }
+
+ ## The registered enddate is copied to the visit 4 date
+ df[,date_col_index][df[inst] == 4] <-
+ as.character(end_date)
+ }
+
+ # Step 5
+ ## Ensure enddate is visit 4 if visit delay is <7
+ if (visit_delay < 7) {
+ df[,date_col_index][df[inst] == 4] <- as.character(end_date)
+ }
+ }
+ }
+ df
+ })
+
+ ls_c |> bind_rows()
+
+}
+
+longlist2wide <-
+ function(list,
+ id.name = "rnumb",
+ instance = "instance",
+ inst.glue = "{.value}_{instance}") {
+
+ # ref: https://r-coder.com/progress-bar-r/
+ # Setting up simple progress bar
+ pb <- txtProgressBar(min = 0, max = length(list), style = 3)
+
+ l <- lapply(seq_along(list), function(i) {
+
+ # Updates the current state
+ setTxtProgressBar(pb, i)
+
+ lst <- list[[i]] |> data.frame()
+
+ rep_inst <-
+ length(levels(factor(lst[, colnames(lst) == instance]))) > 1
+
+
+ k <- lapply(split(lst, f = lst[[id.name]]), function(j) {
+ cname <- colnames(j)
+ vals <-
+ cname[!cname %in% c(id.name,
+ instance)]
+ s <- tidyr::pivot_wider(
+ j,
+ names_from = instance,
+ values_from = all_of(vals),
+ names_glue = inst.glue
+ )
+ s[!colnames(s) %in% instance]
+ })
+
+ k |> dplyr::bind_rows()
+
+
+ })
+
+ }
+
+na_recode <- function(ds,vars_na,new_na="no"){
+ for (i in seq_along(vars_na)){
+ ds[i][is.na(ds[i])] <- new_na
+ }
+ ds
+}
+
+
+
diff --git a/2 Longterm/generalised odds ratio.R b/2 Longterm/generalised odds ratio.R
new file mode 100644
index 0000000..5a0b0e8
--- /dev/null
+++ b/2 Longterm/generalised odds ratio.R
@@ -0,0 +1,9 @@
+## Generaloised odds ratio
+##
+## Tournament based approach
+##
+
+
+library(genodds)
+
+
diff --git a/2 Longterm/grotta_bars.R b/2 Longterm/grotta_bars.R
new file mode 100644
index 0000000..df97ecc
--- /dev/null
+++ b/2 Longterm/grotta_bars.R
@@ -0,0 +1,26 @@
+library(rankinPlot)
+
+?rankinPlot::grottaBar
+
+dta<-read.csv("/Volumes/Data/exercise/source/background.csv",colClasses = "character", na.strings = c("NA","","unknown"))[,c("rtreat","mrs_0","mrs_1","mrs_6","hypertension","diabetes","civil")]
+
+df <- dta |> select(c("rtreat","mrs_0","mrs_1","mrs_6")) |> pivot_longer(cols = -rtreat)
+
+x<-table(mRS=df$value,
+ Group=df$rtreat,
+ Time = df$name)
+
+grottaBar(x,groupName="Group",
+ scoreName = "mRS",
+ strataName="Time",
+ colourScheme ="custom"
+) +
+ scale_fill_viridis_d(direction=-1)
+
+dta |> select(-c("mrs_0","mrs_1")) |> generic_stroke(group = "rtreat", score = "mrs_6", variables = c("hypertension","diabetes","civil"))
+
+library(stRoke)
+cc<-dta[complete.cases(dta),]
+talos <- cc[sample(1:nrow(cc),200),] |> select(-mrs_0)
+
+save(talos,file="talos.rda")
diff --git a/2 Longterm/hr coef plot.R b/2 Longterm/hr coef plot.R
new file mode 100644
index 0000000..5197f48
--- /dev/null
+++ b/2 Longterm/hr coef plot.R
@@ -0,0 +1,173 @@
+source(here::here("1 PA Decline/dst import.R"))
+
+file <- project.aid::docx2list("/Users/au301842/Library/CloudStorage/OneDrive-Personal/Research/PhD/2 TALOS opfølgning/Manuskript/Arkiv/Longterm risk_v1_0.docx", data.type = "table cell")
+
+ds <- file |>
+ purrr::pluck(3) |>
+ (\(.x){
+ setNames(.x, letters[seq_len(ncol(.x))])
+ })() |>
+ dplyr::filter(dplyr::row_number() <= dplyr::n() - 1) |>
+ setNames(c("var", purrr::map(1:3, \(.x)paste0(c("hr", "ci"), .x)) |> purrr::list_c())) |>
+ dplyr::mutate(dplyr::across(dplyr::everything(), ~ gsub("—", "", .x))) |>
+ (\(.x){
+ split.default(.x, factor(project.aid::str_extract(names(.x), "\\d$"), labels = c("Univariable", "Multivariable", "Imputed"))) |>
+ purrr::imap(\(.y, .i){
+ dplyr::bind_cols(var = .x[1], .y) |>
+ tidyr::separate_wider_delim(
+ col = dplyr::starts_with("ci"),
+ delim = ", ",
+ # names_sep = "_",
+ too_few = "align_start",
+ names = c("low", "high")
+ ) |>
+ (\(.z){
+ names(.z)[2] <- "hr"
+ .z
+ # setNames(c("var","hr","low","high"))
+ })() |>
+ dplyr::mutate(model = .i)
+ })
+ })() |>
+ dplyr::bind_rows()
+
+create_log_tics <- function(data) {
+ sort(round(unique(c(1 / data, data)), 2))
+}
+
+forest_plot <- function(data,
+ group.colors = viridisLite::viridis(3,option = "D"),
+ x.tics = create_log_tics(c(1, 1.5, 3, 6)),
+ point.shape = rep(23, 3),
+ legend.title = "",
+ dodge.width = .8,
+ wrap.col) {
+
+ data |>
+ ggplot2::ggplot(ggplot2::aes(x = log(hr), y = labels, color = model, fill = model)) +
+ ggplot2::geom_vline(ggplot2::aes(xintercept = 0), linewidth = .5, linetype = "dashed") +
+ ggplot2::geom_point(ggplot2::aes(shape = model),
+ # position = ggplot2::position_dodge(width = dodge.width),
+ size = 7
+ ) +
+ ggplot2::geom_errorbarh(ggplot2::aes(xmax = log(high), xmin = log(low)),
+ # position = ggplot2::position_dodge(width = dodge.width),
+ size = .5,
+ height = .2,
+ color = "gray50"
+ ) +
+ # ggplot2::position_dodge(width = 2, preserve = "total")+
+ ggplot2::scale_x_continuous(
+ breaks = log(x.tics),
+ labels = x.tics,
+ limits = log(range(x.tics))
+ ) +
+ ggplot2::scale_color_manual(values = group.colors) +
+ ggplot2::scale_fill_manual(values = group.colors) +
+ ggplot2::scale_shape_manual(values = point.shape) +
+ ggplot2::theme_bw() +
+ ggplot2::theme(
+ panel.grid.minor = ggplot2::element_blank(),
+ # legend.title = ggplot2::element_text(""),
+ legend.position = "bottom"
+ ) +
+ ggplot2::ylab("") +
+ ggplot2::xlab("Hazards ratio (log)") +
+ ggplot2::labs(
+ shape = legend.title,
+ color = legend.title,
+ fill = legend.title
+ ) +
+ ggplot2::facet_wrap(facets = ggplot2::vars(model), ncol = wrap.col)
+}
+
+# LETTERS[1:8] |> purrr::map(\(.x){
+# viridisLite::viridis(3,option = .x)|>
+# project.aid::color_plot(ncol = 3)
+# }) |> patchwork::wrap_plots(ncol=1)
+
+headers <- c("Clinical data","Lifestyle factors","Socioeconomic factors","Assessments at follow-up")
+
+ds_new <- ds |>
+ dplyr::mutate(dplyr::across(c("hr", "low", "high"), ~ as.numeric(.x)),
+ var = factor(var, levels = rev(unique(var))),
+ model = factor(model, levels = unique(model))
+ ) |>
+ dplyr::mutate(level=apply(is.na(dplyr::pick(hr,low,high))|dplyr::pick(hr,low,high) == "",1,sum),
+ labels=dplyr::case_when(level==3&var%in%headers~marquee::marquee_glue("**{var}**"),
+ level==3&var!="Body mass index"~marquee::marquee_glue("*{var}*"),
+ .default=marquee::marquee_glue("{var}")),
+ labels = factor(labels, levels = rev(unique(labels))))
+
+(p1 <- ds_new |> (\(.x){
+ forest_plot(.x, wrap.col = length(levels(.x$model)))
+ })()+
+ ggplot2::theme(axis.text.y =marquee::element_marquee(vjust = .77,
+ # hjust = -1,
+ size=14)))
+
+
+ggplot2::ggsave(
+ filename = here::here("2 Longterm/hr_plot_facets.png"),
+ plot = p1+
+ ggplot2::theme(
+ strip.background = ggplot2::element_blank(),
+ strip.text.x = ggplot2::element_blank(),
+ legend.text = ggplot2::element_text(size=14),
+ axis.text.x=ggplot2::element_text(size=10),
+ axis.ticks.length.y = ggplot2::unit(3,"mm"),
+ axis.ticks.y = ggplot2::element_line(color = "white")
+ ),
+ units = "mm",
+ width = 250,
+ height = 300,
+ # pointsize = 10,
+ dpi = 300,
+)
+
+
+headers <- c("Clinical data","Lifestyle factors","Socioeconomic factors","Assessments at follow-up")
+
+(t <- ds |>
+ dplyr::mutate(dplyr::across(dplyr::everything(), ~ gsub("—", "", .x))) |>
+ dplyr::mutate(dplyr::across(c("hr", "low", "high"), ~ as.numeric(.x)),
+ var = factor(var, levels = rev(unique(var))),
+ model = factor(model, levels = unique(model))
+ ) |>
+ dplyr::mutate(level=apply(is.na(dplyr::pick(hr,low,high))|dplyr::pick(hr,low,high) == "",1,sum),
+ labels=dplyr::case_when(level==3&var%in%headers~glue::glue("**{var}**"),
+ level==3~glue::glue("*{var}*"),
+ .default=glue::glue("{var}"))) |>
+ dplyr::filter(model=="Univariable") |>
+ ggplot2::ggplot(
+ # ggplot2::aes(x = x, y = var)
+ ) +
+ ggtext::geom_richtext(ggplot2::aes(x = 0, y = var,label = labels),fill = NA,
+ label.colour = NA,
+ hjust="right") +
+ ggplot2::scale_x_continuous(
+ limits = c(-.1,0)
+ )+
+ ggplot2::theme_void())
+
+(w <- patchwork::wrap_plots(list(t,
+ # patchwork::plot_spacer(),
+ p1+
+ ggplot2::theme(
+ strip.background = ggplot2::element_blank(),
+ strip.text.x = ggplot2::element_blank(),
+ axis.text.y = ggplot2::element_blank(),
+ plot.margin = ggplot2::unit(c(1,1,1,0), 'cm'),
+ # axis.ticks.y.length = ggplot2::unit(0, "pt"),
+ # axis.ticks.y = ggplot2::element_blank(),
+ # panel.border=ggplot2::element_blank(),
+ panel.spacing = ggplot2::unit(0, "cm")
+ )),ncol=2,widths = c(1.2,3),axes = "collect"))
+
+ggplot2::ggsave(
+ filename = here::here("2 Longterm/hr_plot_facets_labels.png"),plot = w,
+ units = "mm",
+ width = 200,
+ height = 220,
+ dpi = 300,
+)
diff --git a/2 Longterm/hr_plot_facets.png b/2 Longterm/hr_plot_facets.png
new file mode 100644
index 0000000..93998bd
Binary files /dev/null and b/2 Longterm/hr_plot_facets.png differ
diff --git a/2 Longterm/hr_plot_facets_labels.png b/2 Longterm/hr_plot_facets_labels.png
new file mode 100644
index 0000000..3ad6f55
Binary files /dev/null and b/2 Longterm/hr_plot_facets_labels.png differ
diff --git a/2 Longterm/import_mfi.R b/2 Longterm/import_mfi.R
new file mode 100644
index 0000000..e69de29
diff --git a/2 Longterm/kamila-clustering.R b/2 Longterm/kamila-clustering.R
new file mode 100644
index 0000000..3cde557
--- /dev/null
+++ b/2 Longterm/kamila-clustering.R
@@ -0,0 +1,84 @@
+## Not run:
+# import and format a mixed-type data set
+library(kamila)
+data(Byar, package='clustMD')
+
+ds <- readr::read_csv("2 Longterm/assigndata.csv",na = c("","NA")) |> na.omit()
+
+ds <- ds |> dplyr::mutate(mrs_1 = mrs_1>2)
+
+cat_i <- lapply(ds,is.character) |> purrr::list_c()
+con_i <- lapply(ds,is.double) |> purrr::list_c()
+
+xor(cat_i,con_i)
+
+clin_clust=2
+# Byar$logSpap <- log(Byar$Serum.prostatic.acid.phosphatase)
+
+# conInd <- c(5,6,8:10,16)
+# conVars <- Byar[,conInd]
+# conVars <- data.frame(scale(conVars))
+
+conVars <- ds[,con_i]
+conVars <- data.frame(scale(conVars))
+
+# catVarsFac <- Byar[,-c(1:2,conInd,11,14,15)]
+# catVarsFac[] <- lapply(catVarsFac, factor)
+# catVarsDum <- dummyCodeFactorDf(catVarsFac)
+
+catVarsFac <- ds[,cat_i]
+catVarsFac <- lapply(catVarsFac, factor) |> dplyr::bind_cols() |> as.data.frame()
+catVarsDum <- dummyCodeFactorDf(catVarsFac)
+
+# Modha-Spangler clustering with kmeans default Hartigan-Wong algorithm
+gmsResHw <- gmsClust(conVars, catVarsDum, nclust = clin_clust)
+
+# Modha-Spangler clustering with kmeans Forgy-Lloyd algorithm
+# NOTE searchDensity should be >= 10 for optimal performance:
+# this is just a syntax demo
+gmsResLloyd <- gmsClust(conVars, catVarsDum, nclust = clin_clust,
+ algorithm = "Lloyd", searchDensity = 15)
+
+# KAMILA clustering
+kamRes <- kamila(conVars, catVarsFac, numClust=2:7, numInit=10, calcNumClust="ps")
+
+# Plot results
+# ternarySurvival <- factor(Byar$SurvStat)
+# levels(ternarySurvival) <- c('Alive','DeadProst','DeadOther')[c(1,2,rep(3,8))]
+plottingData <- cbind(
+ conVars,
+ catVarsFac,
+ KamilaCluster = factor(kamRes$finalMemb))
+# plottingData$Bone.metastases <- ifelse(
+# plottingData$Bone.metastases == '1', yes='Yes',no='No')
+#
+# # Plot Modha-Spangler/Hartigan-Wong results
+# msPlot <- ggplot(
+# plottingData,
+# aes(
+# x=logSpap,
+# y=Index.of.tumour.stage.and.histolic.grade,
+# color=ternarySurvival,
+# shape=MSCluster))
+# plotOpts <- function(pl) (pl + geom_point() +
+# scale_shape_manual(values=c(2,3,7)) + geom_jitter())
+# plotOpts(msPlot)
+
+# Plot KAMILA results
+kamPlot <- ggplot(
+ plottingData,
+ aes(
+ x=pase_0,
+ y=pase_6,
+ color=KamilaCluster,
+ shape=KamilaCluster))
+plotOpts(kamPlot)
+
+
+plotting_ls <- tibble(KamilaCluster = factor(kamRes$finalMemb),
+ MSCluster = factor(gmsResHw$results$cluster)) |>
+ purrr::map(\(x) cbind(x, ds))
+
+plotting_ls |> purrr::map(\(y) {
+ y |> gtsummary::tbl_summary(by=x) |> gtsummary::add_p() |> gtsummary::add_overall()}) |>
+ gtsummary::tbl_merge()
diff --git a/2 Longterm/kmeans-clustering.R b/2 Longterm/kmeans-clustering.R
new file mode 100644
index 0000000..cadcc26
--- /dev/null
+++ b/2 Longterm/kmeans-clustering.R
@@ -0,0 +1,114 @@
+ds <- readr::read_csv("2 Longterm/assigndata.csv", na = c("", "NA")) |> na.omit()
+
+ds <- ds |> dplyr::mutate(mrs_1 = mrs_1 > 2)
+
+
+library(tidymodels)
+library(tidyverse)
+
+ds |>
+ na.omit() |>
+ kmeans(centers = 3)
+
+
+ds_num <- ds |> mutate(
+ across(where(is.double), ~ scale(.x)),
+ across(is.character, ~ as.numeric(factor(.x)))
+)
+
+ds_num |> kmeans(centers = 3)
+
+set.seed(321)
+kclusts <-
+ tibble(k = 1:9) %>%
+ mutate(
+ kclust = map(k, ~ kmeans(ds_num, .x)),
+ tidied = map(kclust, tidy),
+ glanced = map(kclust, glance),
+ augmented = map(kclust, augment, ds_num)
+ )
+
+kclusts
+
+clusters <-
+ kclusts %>%
+ unnest(cols = c(tidied))
+
+assignments <-
+ kclusts %>%
+ unnest(cols = c(augmented))
+
+clusterings <-
+ kclusts %>%
+ unnest(cols = c(glanced))
+
+ggplot(assignments, aes(x = pase_0, y = age)) +
+ geom_point(aes(color = .cluster), alpha = 0.8) +
+ facet_wrap(~k)
+
+ggplot(clusterings, aes(k, tot.withinss)) +
+ geom_line() +
+ geom_point()
+
+PCA
+
+pairs(assignments[-c(2:4)],
+ gap = 0,
+ bg = c("red", "yellow", "blue")[assignments$k],
+ pch = 21
+)
+
+
+pc.out <- prcomp(ds_num, center = TRUE, scale = TRUE)
+
+pc.sum <- summary(pc.out)
+
+pscr <- tibble(
+ x = 1:dim(pc.sum$importance)[2],
+ Proportion = pc.sum$importance[2, ],
+ Cumulative = pc.sum$importance[3, ]
+) %>%
+ pivot_longer(cols = -x) %>%
+ ggplot(aes(x = x, y = value, color = name)) +
+ geom_line() +
+ geom_point() +
+ ylim(0, 1) +
+ labs(
+ title = "Scree plot",
+ color = "Variance"
+ ) +
+ ylab("Variance") +
+ xlab("Principal components")
+
+
+###
+###
+
+install.packages("VarSelLCM")
+library(VarSelLCM)
+
+# Please indicate the number of cores you wan to use for parallelization
+nb.CPU <- 4
+# clustering without variable selection (about than 10/20 sec on 4 CPU)
+res_without <- ds |> select(!mrs_1) |>
+ mutate(across(is.character, ~ factor(.x))) |> as.data.frame() |>
+ VarSelCluster(
+ gvals = 1:5,
+ crit.varsel = "BIC",
+ vbleSelec = FALSE,
+ nbcores = nb.CPU
+ )
+
+summary(res_without)
+
+plot(res_without)
+
+plot(x=res_without, y="mdi_1")
+
+plot(x=res_without, y="sex")
+
+print(res_without)
+
+coef(res_without)
+
+VarSelShiny(res_without)
diff --git a/2 Longterm/sankey events.R b/2 Longterm/sankey events.R
new file mode 100644
index 0000000..951d398
--- /dev/null
+++ b/2 Longterm/sankey events.R
@@ -0,0 +1,191 @@
+
+# source("1 PA Decline/data_format.R")
+
+# NEW QUARTILES
+
+
+# Visuals - sankey
+# https://stackoverflow.com/questions/50395027/beautifying-sankey-alluvial-visualization-using-r
+
+
+## Painting
+
+df_raw <- readr::read_csv(here::here("2 Longterm/DDV 241031/event_sankey_data.csv"))
+
+df <- df_raw|>
+ dplyr::rename(pase_0_cut=pase_0_quartile,
+ pase_6_cut=pase_4_quartile) |>
+ dplyr::mutate(change=dplyr::case_when(
+ pase_0_cut==1 & pase_6_cut==1 ~ "ll",
+ pase_0_cut %in% 2:4 & pase_6_cut %in% 2:4 ~ "hh",
+ pase_0_cutpase_6_cut ~ "drop"
+ ),
+ dplyr::across(c(pase_0_cut,pase_6_cut,change),as.factor))
+
+
+df |> sankey_ready()
+
+sankey_ready <- function(data,change.var="change"){
+ df <- data
+ # |>
+ # dplyr::count(dplyr::across(dplyr::all_of(c("pase_0_cut", "pase_6_cut",change.var)))) |>
+ # dplyr::mutate(dplyr::across(dplyr::starts_with("pase_"),\(.x) factor(.x))) |>
+ # setNames(c("pase_0_cut", "pase_6_cut","change","n"))
+
+ lbs0 <-
+ c(
+ paste0("1st \n(n=", sum(df$n[df$pase_0_cut == "1"]), ")"),
+ paste0("2nd \n(n=", sum(df$n[df$pase_0_cut == "2"]), ")"),
+ paste0("3rd \n(n=", sum(df$n[df$pase_0_cut == "3"]), ")"),
+ paste0("4th \n(n=", sum(df$n[df$pase_0_cut == "4"]), ")")
+ )
+
+
+ lbs6 <-
+ c(
+ paste0("1st \n(n=", sum(df$n[df$pase_6_cut == "1"]), ")"),
+ paste0("2nd \n(n=", sum(df$n[df$pase_6_cut == "2"]), ")"),
+ paste0("3rd \n(n=", sum(df$n[df$pase_6_cut == "3"]), ")"),
+ paste0("4th \n(n=", sum(df$n[df$pase_6_cut == "4"]), ")")
+ )
+
+
+ levels(df$pase_0_cut) <- lbs0[1:length(levels(df$pase_0_cut))]
+ levels(df$pase_6_cut) <- lbs6[1:length(levels(df$pase_6_cut))]
+
+ df$pase_0_cut <- factor(df$pase_0_cut, levels = rev(levels(df$pase_0_cut)))
+ df$pase_6_cut <- factor(df$pase_6_cut, levels = rev(levels(df$pase_6_cut)))
+
+ df$change <- factor(df$change, levels = c("hh","hop", "drop", "ll"))
+
+ if (change.var=="change"){
+ df |> dplyr::mutate(first_grp=ifelse(substr(pase_0_cut,1,1)==1,"low","higher"))
+ } else if (change.var=="change_any"){
+ df |> dplyr::mutate(first_grp=dplyr::case_when(
+ substr(pase_0_cut,1,1)==1 ~ "low",
+ substr(pase_0_cut,1,1) %in% 2:3 ~ "mid",
+ substr(pase_0_cut,1,1)==4 ~ "high"))
+ }
+}
+
+# hops <- "#66c1a3" # grey
+# # drops <- "#990033" # Midtrød
+# drops <- "#CE0045" # Lighter Midtrød
+# nos <- "grey80" # Light grey
+#
+# # border <- "#00596B"
+# # box <- "#008099"
+#
+# border <- "#EA571D"
+# box <- "#1E4B66"
+#
+# higher <- "yellow"
+# low <- "purple"
+
+library(ggalluvial)
+
+library(ggplot2)
+
+# project.aid::color_plot(viridisLite::turbo(4))
+
+plot_sankey <- function(data,
+ # palette=viridisLite::turbo(4),
+ hops = "#1AE4B6FF",
+ drops = "#FABA39FF",
+ hh = "#30123BFF",
+ ll = "#7A0403FF",
+ border = "#EA571D",
+ box = "#1E4B66",
+ higher = "#1E4B66",
+ mid = "#1E4B66",
+ low = "#1E4B66",
+ alpha = 0.8,
+ a1=pase_0_cut,
+ a2=pase_6_cut,
+ a1.grp=first_grp,
+ text.size = 4
+){
+
+ if (length(unique(data[[ncol(data)]]))>2) {
+ fills <- c(higher,low,mid)
+ } else {
+ fills <- c(higher,low)
+ }
+
+ cls <- c(hh, hops, drops, ll)
+ # stratum.grp <- c(df[["first_grp"]],df[["last_grp"]])
+
+ # cls <- palette
+ # browser()
+ ggplot(data, aes(y = n, axis1 = {{a1}}, axis2 = {{a2}})) +
+ geom_alluvium(
+ aes(fill = change, color = change),
+ width = 1 / 16,
+ alpha = alpha,
+ knot.pos = 0.4,
+ curve_type ="sigmoid"
+ ) +
+ geom_stratum(aes(fill={{a1.grp}}),
+ # geom_stratum(aes(fill=stratum_grp),
+ size = 2,
+ width = 1 / 3.4,
+ # fill = box,
+ color = border
+ ) +
+ geom_text(stat = "stratum",
+ aes(label = after_stat(stratum)),
+ colour = "white",
+ size = text.size,
+ lineheight = 1) +
+ scale_x_continuous(
+ breaks = 1:2,
+ labels = c("Pre-stroke\nPASE quartile", "Six months\nPASE quartile")
+ ) +
+ scale_fill_manual(values = c(cls,fills),na.value = box) +
+ scale_color_manual(values = cls) +
+ ggtitle("PA level changes from \npre-stroke to post-stroke")
+}
+
+# c("change","change_any") |> purrr::map(\(.x){
+# df_raw |>
+# sankey_ready(change.var = .x)
+# }) |>
+# purrr::map(\(.x){
+# .x |> plot_sankey(text.size=4.5)
+# }) |>
+# patchwork::wrap_plots()
+
+pal <- viridisLite::turbo(12)
+
+project.aid::color_plot(pal)
+
+df |>
+ sankey_ready() |>
+ plot_sankey(text.size=4.5)
+
+p_delta <- df |>
+ sankey_ready() |>
+ plot_sankey(text.size=4.5)
+
+ggplot2::ggsave(filename = here::here("2 Longterm/sankey_event_stroke.png"),
+ p_delta +
+ theme_void() +
+ theme(
+ legend.position = "none",
+ # panel.grid.major = element_blank(),
+ # panel.grid.minor = element_blank(),
+ # axis.text.y = element_blank(),
+ # axis.title.y = element_blank(),
+ axis.text.x = element_text(),
+ # text = element_text(size = 5),
+ plot.title = element_blank(),
+ # panel.background = element_rect(fill = "white"),
+ plot.background = element_rect(fill="white"),
+ panel.border = element_blank()
+ ),
+ units = "mm",
+ width = 84,
+ height = 70,
+ # pointsize = 30,
+ dpi = 600)
diff --git a/2 Longterm/sankey_event_stroke.png b/2 Longterm/sankey_event_stroke.png
new file mode 100644
index 0000000..440eb27
Binary files /dev/null and b/2 Longterm/sankey_event_stroke.png differ
diff --git a/2 Longterm/sdmt correction.R b/2 Longterm/sdmt correction.R
new file mode 100644
index 0000000..99a15f1
--- /dev/null
+++ b/2 Longterm/sdmt correction.R
@@ -0,0 +1,24 @@
+# During study time, the SDMT was performed in a non-standardised way until around 2015-02-18, only giving subjects 60 seconds.
+# Some filled assessments were marked and were all manually evaluated for correction.
+# A decision was reached to multiply old results by a factor of 1.5 assuming a proportional increase in completed fields.
+
+
+
+sdmt_time<-openxlsx::read.xlsx("/Volumes/Data/source/tid.sdmt.xlsx") |>
+ tidyr::pivot_longer(cols = c(tid.1md, tid.6md)) |> mutate(deltager=as.character(deltager))
+sdmt_time$name <- as.double(as.character(factor(sdmt_time$name,labels = c("2","4"))))
+
+# Setting cut date
+sdmt_cut<-as.Date("2015-02-18")
+
+# Joining datasets to have date of visit
+sdmt_corr <- left_join(ls_nas$sdmt,sdmt_time |> mutate(name=as.character(name)), by = c("rnumb"="deltager","instance"="name"))
+
+# Modyfying old correction table to be complete
+sdmt_corr$value <- if_else(sdmt_corr$talos_sdmt00
+ ggsurvfit(linewidth = 1,) +
+ add_confidence_interval() +
+ add_risktable() +
+ add_quantile(y_value = 0.6, color = "gray50", linewidth = 0.75) +
+ # limit plot to show 8 years and less
+ coord_cartesian(xlim = c(0, 8)) +
+ # update figure labels/titles
+ labs(
+ y = "Percentage Survival",
+ title = "Recurrence by Time From Surgery to Randomization",
+ ) +
+ # reduce padding on edges of figure and format axes
+ scale_y_continuous(label = scales::percent,
+ breaks = seq(0, 1, by = 0.2),
+ expand = c(0.015, 0)) +
+ scale_x_continuous(breaks = 0:10,
+ expand = c(0.02, 0)))
+
+
+
+head(df_colon)
+
+library("survival")
+library("survminer")
+
+variables <- c("sex", "age", "adhere", "extent", "surg")
+
+cox_model <- coxph(as.formula(paste("Surv(time, status) ~",paste(variables,collapse="+"))), data = df_colon)
+
+summary(cox_model)
+
+ggsurvplot(survfit(cox_model), data=df_colon, palette = "#2E9FDF",
+ ggtheme = theme_minimal())
+
+# Checks
+
+(ph_check <- survival::cox.zph(cox_model))
+
+survminer::ggcoxzph(ph_check, var=c("sex", "age", "adhere", "surg"),
+ font.main = 10,
+ font.x = 10,
+ font.y = 10)
+
+
+## Below is the nest best solution
+## Try at smoothing the survival curve
+
+## Working code to get satisfying object
+df <- survfit2(Surv(time, status) ~ surg, data = df_colon) |>
+ tidy_survfit(type = "survival")
+
+df_split <- split(df,df$strata)
+
+df_smoothed <- purrr::reduce(lapply(c("estimate","conf.low", "conf.high"), function(j) {
+ do.call(rbind,
+ lapply(seq_along(df_split), function(i) {
+ nms <- names(df_split)[i]
+ y <-
+ predict(mgcv::gam(as.formula(paste0(
+ j[[1]], " ~ s(time, bs = 'cs')"
+ )), data = df_split[[i]]))
+ df <- data.frame(df_split[[i]]$time, y, nms)
+ names(df) <- c("time", paste0(j[[1]], ".smooth"), "strata")
+ df
+ }))
+}),dplyr::full_join) |> full_join(df)
+
+ggplot(data=df_smoothed) +
+ geom_line(aes(x=time, y=estimate.smooth, color = strata))+
+ geom_ribbon(aes(x=time, ymin = conf.low.smooth, ymax = conf.high.smooth, fill = strata), alpha = 0.50) +
+ # geom_smooth(aes(x=time, y=estimate, color = strata), method = "gam", formula = y ~ s(x, bs = "cs")) +
+ # reduce padding on edges of figure and format axes
+ scale_y_continuous(label = scales::percent,
+ breaks = seq(0, 1, by = 0.2),
+ expand = c(0.015, 0), limits = c(0,1)) +
+ scale_x_continuous(breaks = 0:10,
+ expand = c(0.02, 0))+
+ labs(
+ y = "Percentage Survival",
+ title = "Recurrence by Time From Surgery to Randomization",
+ ) +
+ # limit plot to show 8 years and less
+ coord_cartesian(xlim = c(0, 8))
+
+
+
+## Dendrogram
+
+df_colon[do.call(c, lapply(seq_len(ncol(df_colon)), function(i) {
+ is.double(df_colon[[i]])
+}))][-1] |> scale() |> dist() |> hclust(method="average") |> ggdendro::ggdendrogram()
+
+
+## Better example??
+##
+
+library(tidyverse)
+library(survival)
+library(purrr)
+library(ggsurvfit)
+library(cobs)
+
+## Data
+plot.type <- "survival"
+
+x <- survfit2(Surv(time, status) ~ surg, data = df_colon)
+df <-
+ tidy_survfit(x, type = plot.type) %>% dplyr::mutate(survfit = c(list(x),
+ rep_len(list(), dplyr::n() - 1L)))
+method <- "gam"
+
+df_split <- split(df,df$strata)
+
+df_smoothed <- purrr::reduce(lapply(c("estimate","conf.low", "conf.high"), function(j) {
+ do.call(rbind,
+ lapply(seq_along(df_split), function(i) {
+ nms <- names(df_split)[i]
+ x = df_split[[i]]$time
+ if (method=="loess"){
+ y <-
+ predict(loess(as.formula(paste0(
+ j[[1]], " ~ time"
+ )), data = df_split[[i]]))
+ } else if (method=="gam"){
+ y <-
+ predict(mgcv::gam(as.formula(paste0(
+ j[[1]], " ~ s(time, bs = 'cs')"
+ )), data = df_split[[i]]))
+ } else if (method=="cobs") {
+
+ if (plot.type=="survival"){
+ ## This will make the plot start in (0,1)
+ con <- rbind(c( 0,min(x),1))
+ ## This ensures a monotonic decreasing slope
+ ## for the estimate, not the CIs
+ if (j[[1]]=="estimate"){
+ direction="decrease"
+ } else {direction="none"}
+
+ } else if (plot.type=="risk"){
+ con <- rbind(c( 0,min(x),0))
+ if (j[[1]]=="estimate"){
+ direction="increase"
+ } else {direction="none"}
+ }
+
+ m <- cobs(x,df_split[[i]][[j]],
+ constraint=direction,
+ nknots = 4,
+ pointwise= con,
+ degree = 2,)
+ y <- predict(m, x)[, 'fit']
+ }
+
+ df <- data.frame(x, y, nms)
+ names(df) <- c("time", paste0(j[[1]], ".smooth"), "strata")
+ df
+ }))
+}),dplyr::full_join) |> full_join(df)
+
+## Plotting
+ggplot(data=df_smoothed) +
+ geom_line(aes(x=time, y=estimate.smooth, color = strata))+
+ geom_ribbon(aes(x=time, ymin = conf.low.smooth, ymax = conf.high.smooth, fill = strata), alpha = 0.50)
+
+## Weighted GAM approach
+## https://stackoverflow.com/a/66705556/21019325
+
+## It does not work. Gonna stop here due to lack of time.
+## Apparantly
+
+dat_orig <- df_split[[1]][,c("time","estimate")]
+x1=0
+y1=1
+# set.seed(123)
+# N = 100
+# x <- sort(runif(N) * 4 - 1)
+# f <- exp(4*x)/(1+exp(4*x))
+# y <- f + rnorm(N) * 0.1
+# x = c(-1, x)
+# y = c(-0.1, y)
+# dat = data.frame(x = x, y= y)
+x <- do.call(c,c(x1,dat_orig[1]))
+y <- do.call(c,c(y1,dat_orig[,2]))
+dat <- data.frame(x=x,y=y)
+k <- 13
+
+library(mgcv)
+
+fit0 <- gam(y ~ s(x, k = k, bs = "cr"),data=dat)
+# predict from unconstrained GAM fit
+
+newdata <- data.frame(x = x)
+newdata$y_pred_fit0 <- predict(fit0, newdata = newdata)
+
+# Show regular spline fit (and save fitted object)
+# f.ug <- gam(y~s(x,k=k,bs="cr"))
+
+# explicitly construct smooth term's design matrix
+sm <- smoothCon(s(x,k=k,bs="cr"),dat,knots=NULL)[[1]]
+# find linear constraints sufficient for monotonicity of a cubic regression spline
+# it assumes "cr" is the basis and its knots are provided as input
+f.mono <- mono.con(sm$xp,up = FALSE)
+
+G <- list(
+ X=sm$X,
+ C=matrix(0,0,0), # [0 x 0] matrix (no equality constraints)
+ sp=fit0$sp, # smoothing parameter estimates (taken from unconstrained model)
+ p=sm$xp, # array of feasible initial parameter estimates
+ y=dat[,2],
+ w= c(1e8, rep(1,nrow(dat_orig))), # weights for data
+ Ain=f.mono$A, # matrix for the inequality constraints
+ bin=f.mono$b, # vector for the inequality constraints
+ S=sm$S, # list of penalty matrices; The first parameter it penalizes is given by off[i]+1
+ off=0 # Offset values locating the elements of M$S in the correct location within each penalty coefficient matrix. (Zero offset implies starting in first location)
+)
+
+p <- pcls(G) # fit spline (using smoothing parameter estimates from unconstrained fit)
+
+# predict
+newdata$y_pred_fit2 <- Predict.matrix(sm, data.frame(x = newdata$x)) %*% p
+# plot
+ggplot(data=newdata) +
+ geom_line(aes(x=x, y=y_pred_fit2))
+ # geom_ribbon(aes(x=time, ymin = conf.low.smooth, ymax = conf.high.smooth, fill = strata), alpha = 0.50)
+#
+plot(y ~ x, data = dat)
+lines(y_pred_fit0 ~ x, data = newdata, col = 2, lwd = 2)
+lines(y_pred_fit2 ~ x, data = newdata, col = 4, lwd = 2)
+abline(v = -1)
+abline(h = -0.1)
\ No newline at end of file
diff --git a/2 Longterm/survival_two_groups.R b/2 Longterm/survival_two_groups.R
new file mode 100644
index 0000000..3a3f52f
--- /dev/null
+++ b/2 Longterm/survival_two_groups.R
@@ -0,0 +1,132 @@
+# =============================================================================
+# Retrospective Sample Size Evaluation — Event-Free Survival (2 Groups)
+# Freedman Method | works directly from hazard ratio and observed events
+# Appropriate for: unequal group sizes, single censored-at-event designs
+# =============================================================================
+
+# --- 0. Install & Load Packages ----------------------------------------------
+
+# Uncomment to install if needed:
+# install.packages("gsDesign")
+
+library(gsDesign)
+
+
+# --- 1. Observed Data --------------------------------------------------------
+
+# n : number of participants per group
+# events : number of observed events per group
+# person_time : total person-years of follow-up per group
+# = sum of each individual's follow-up duration
+# naturally accounts for censoring and variable follow-up
+# max_follow_up : maximum follow-up time (years)
+
+n_A <- 323; events_A <- 80; person_time_A <- 2089
+n_B <- 56; events_B <- 32; person_time_B <- 294
+max_follow_up <- 9 # years
+
+# Derived quantities
+hazard_A <- events_A / person_time_A # events per person-year
+hazard_B <- events_B / person_time_B
+hr <- hazard_B / hazard_A # observed hazard ratio (B vs A)
+
+overall_event_rate <- (events_A + events_B) / (n_A + n_B)
+pi_A <- n_A / (n_A + n_B)
+pi_B <- n_B / (n_A + n_B)
+
+cat("=== Observed Data Summary ===\n")
+cat(sprintf("Group A : N=%-4d Events=%-3d Person-years=%6.0f Hazard=%.4f\n",
+ n_A, events_A, person_time_A, hazard_A))
+cat(sprintf("Group B : N=%-4d Events=%-3d Person-years=%6.0f Hazard=%.4f\n",
+ n_B, events_B, person_time_B, hazard_B))
+cat(sprintf("Hazard ratio (B vs A) : %.3f\n", hr))
+cat(sprintf("Allocation (A / B) : %.1f%% / %.1f%%\n", pi_A*100, pi_B*100))
+cat(sprintf("Overall event rate : %.3f\n", overall_event_rate))
+
+
+# --- 2. Required Events — Freedman Method ------------------------------------
+# Freedman (1982): works directly from the hazard ratio.
+# More stable than Schoenfeld when group sizes are unequal, because it does
+# not depend on a variance term V that collapses under unequal allocation.
+#
+# Formula: E = (z_alpha/2 + z_beta)^2 * (1 + hr)^2 / (hr - 1)^2
+#
+# Note: hr must not equal 1 (no difference). If hr < 1, invert it so
+# the formula always uses the ratio > 1.
+
+required_events_freedman <- function(alpha = 0.05, power = 0.80, hr) {
+ if (hr == 1) stop("Hazard ratio must not equal 1 (no detectable difference).")
+ hr <- ifelse(hr < 1, 1/hr, hr) # ensure hr > 1
+ z_alpha <- qnorm(1 - alpha / 2)
+ z_beta <- qnorm(power)
+ E <- (z_alpha + z_beta)^2 * (1 + hr)^2 / (hr - 1)^2
+ return(ceiling(E))
+}
+
+E_required <- required_events_freedman(alpha = 0.05, power = 0.80, hr = hr)
+N_required <- ceiling(E_required / overall_event_rate)
+
+cat("\n=== Freedman Method (alpha=0.05, power=0.80) ===\n")
+cat("Required total events :", E_required, "\n")
+cat("Observed total events :", events_A + events_B, "\n")
+cat("Required total N :", N_required, "\n")
+cat("Observed total N :", n_A + n_B, "\n")
+cat("Difference (req-obs) :", N_required - (n_A + n_B), "\n")
+
+
+# --- 3. Validation via gsDesign::nSurv ---------------------------------------
+
+cat("\n=== gsDesign Validation ===\n")
+tryCatch({
+ gs <- nSurv(
+ lambdaC = hazard_A,
+ hr = hr,
+ sided = 2,
+ alpha = 0.05,
+ beta = 0.20,
+ T = max_follow_up,
+ minfup = 0
+ )
+ print(gs)
+}, error = function(e) {
+ cat("gsDesign error:", conditionMessage(e), "\n")
+})
+
+
+# --- 4. Sensitivity Analysis Across Power Levels -----------------------------
+
+power_levels <- c(0.70, 0.75, 0.80, 0.85, 0.90)
+
+sensitivity <- data.frame(
+ power = power_levels,
+ events_req = sapply(power_levels, function(pw)
+ required_events_freedman(0.05, pw, hr))
+)
+sensitivity$n_req <- ceiling(sensitivity$events_req / overall_event_rate)
+sensitivity$adequate <- ifelse(sensitivity$n_req <= (n_A + n_B), "Yes", "No")
+
+cat("\n=== Sensitivity Analysis by Power Level ===\n")
+print(sensitivity)
+
+
+# --- 5. Interpretation -------------------------------------------------------
+
+cat("\n=== Interpretation ===\n")
+cat(sprintf("Hazard ratio: %.3f — Group B events occur %.1fx faster than Group A\n",
+ hr, hr))
+
+if (E_required <= (events_A + events_B)) {
+ cat("Event count : ADEQUATE — observed events meet Freedman requirement.\n")
+} else {
+ cat(sprintf("Event count : INSUFFICIENT — %d observed, %d required.\n",
+ events_A + events_B, E_required))
+}
+
+if (N_required <= (n_A + n_B)) {
+ cat("Sample size : ADEQUATELY POWERED at 80%.\n")
+} else {
+ cat(sprintf(paste0("Sample size : UNDERPOWERED at 80%% — ",
+ "N=%d observed, N=%d required (shortfall: %d).\n"),
+ n_A + n_B, N_required, N_required - (n_A + n_B)))
+ cat("Type II error risk is elevated — interpret null results with caution.\n")
+}
\ No newline at end of file
diff --git a/2 Longterm/table plotting tests.R b/2 Longterm/table plotting tests.R
new file mode 100644
index 0000000..e69de29
diff --git a/2 Longterm/varsellcm-clustering.R b/2 Longterm/varsellcm-clustering.R
new file mode 100644
index 0000000..1e44ac5
--- /dev/null
+++ b/2 Longterm/varsellcm-clustering.R
@@ -0,0 +1,33 @@
+ds <- readr::read_csv("2 Longterm/assigndata.csv", na = c("", "NA"))
+
+library(VarSelLCM)
+
+# Please indicate the number of cores you wan to use for parallelization
+nb.CPU <- 4
+# clustering without variable selection (about than 10/20 sec on 4 CPU)
+clusters <- ds |> select(!mrs_1) |> na.omit() |>
+ mutate(across(is.character, ~ factor(.x))) |> as.data.frame() |>
+ VarSelCluster(
+ gvals = 1:5,
+ crit.varsel = "BIC",
+ vbleSelec = FALSE,
+ nbcores = nb.CPU
+ )
+
+summary(clusters)
+
+plot(clusters)
+
+plot(x=clusters, y="mdi_1")
+
+plot(x=clusters, y="sex")
+
+print(clusters)
+
+coef(clusters)
+
+VarSelShiny(clusters)
+
+clusters@partitions@zMAP
+
+gtsummary::tbl_summary(tibble(ds |> na.omit(), class=clusters@partitions@zMAP),by=class) |> gtsummary::add_p()
diff --git a/2 Longterm/wsc-sankey.R b/2 Longterm/wsc-sankey.R
new file mode 100644
index 0000000..9c18599
--- /dev/null
+++ b/2 Longterm/wsc-sankey.R
@@ -0,0 +1,58 @@
+
+grps <- rbind(c("low0","low6","1"),
+ c("high0","low6","2"),
+ c("low0","high6","3"),
+ c("high0","high6","4"))
+
+tmes <- c(48,62,55,323)
+
+tbl <- data.frame(grps,tmes)
+
+colnames(tbl) <- c("t1","t2","grp","n")
+
+library(ggalluvial)
+
+cls <- viridisLite::turbo(4,direction=-1)
+
+cls
+stRoke::color_plot(viridisLite::turbo(4,direction=-1))
+
+p <- ggplot(tbl,aes(y = n, axis1 = t1, axis2 = t2)) +
+ geom_alluvium(
+ aes(fill = grp, color = grp),
+ width = 1 / 16,
+ alpha = .6,
+ knot.pos = 0.4
+ ) +
+ # geom_stratum(aes(size=10),width = 1 / 4,
+ # fill = box,
+ # color = border) +
+ # geom_text(stat = "stratum", aes(label = after_stat(stratum)), colour = "white", size = 20) +
+ scale_x_continuous(breaks = 1:2,
+ labels = c("Pre-stroke\nquartile", "Six months\nquartile")) +
+ scale_y_continuous(breaks=c(0,103,488))+
+ scale_fill_manual(values = cls) +
+ scale_color_manual(values = cls) +
+ # labs(title=NULL, legend=NULL)+
+ theme_minimal()
+
+png(
+ filename = "sankey_change_WSC.png",
+ units = "mm",
+ width = 500,
+ height = 500,
+ pointsize = 15,
+ res = 300
+); p+
+ theme_minimal() +
+ theme(
+ legend.position = "none",
+ panel.grid.major = element_blank(),
+ panel.grid.minor = element_blank(),
+ axis.text.y = element_blank(),
+ axis.title.y = element_blank(),
+ axis.text.x = element_blank(),
+ plot.title = element_blank(),
+ panel.background = element_rect(fill='transparent'),
+ plot.background = element_rect(fill='transparent', color=NA)
+ ); dev.off()
diff --git a/3 Cognitive change/.DS_Store b/3 Cognitive change/.DS_Store
new file mode 100644
index 0000000..516caf3
Binary files /dev/null and b/3 Cognitive change/.DS_Store differ
diff --git a/3 Cognitive change/dsc_tekst.png b/3 Cognitive change/dsc_tekst.png
new file mode 100755
index 0000000..7f088f2
Binary files /dev/null and b/3 Cognitive change/dsc_tekst.png differ
diff --git a/3 Cognitive change/project-presentation.html b/3 Cognitive change/project-presentation.html
new file mode 100644
index 0000000..a50a926
--- /dev/null
+++ b/3 Cognitive change/project-presentation.html
@@ -0,0 +1,2171 @@
+
+
+
+
+
+
+
+
+
+
+
+ Physical activity before stroke, small vessel disease and cognitive decline after stroke
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Physical activity before stroke, small vessel disease and cognitive decline after stroke
+
+
+
+
+
+
+Hypothesis
+
+
+
+
+
+
+
+Higher level of PA before acute ischemic stroke (AIS) is associated with decreased risk of cognitive decline after stroke independently of stroke severity and cSVD burden.
+
+
+
+Data
+
+Physical Activity Scale in the Elderly (PASE ) questionnaire
+Modified Rankin Scale (mRS )
+Level of education
+Informant Questionnaire on Cognitive Decline in the Elderly, short version (IQCODE )
+Repeatable Battery for the Assessment of Neuropsychological Status (RBANS ), Scandinavian version
+Wellbeing and depressive symptoms
+Cerebral Small vessel disease burden (cSVD score )
+
+
+
+Education
+
+
+
+
+
+
+
+
+
+ Characteristic
+ Overall , N = 95
+ female , N = 33
+ male , N = 62
+
+
+
+ Level of education
+
+
+
+ Folkeskole (9-10 år)
+20 (21%)
+11 (33%)
+9 (15%)
+ Gymnasiale/erhvervsfaglige uddannelser (11-12 år)
+30 (32%)
+8 (24%)
+22 (36%)
+ Erhvervsakademiuddannelser (13-14 år)
+16 (17%)
+5 (15%)
+11 (18%)
+ Professionsbachelor/universitetsbachelor (15-17 år)
+18 (19%)
+8 (24%)
+10 (16%)
+ Kandidatuddannelser (18-19 år)
+10 (11%)
+1 (3.0%)
+9 (15%)
+ PhD ( > 20 år)
+0 (0%)
+0 (0%)
+0 (0%)
+ Not classified
+1
+0
+1
+
+
+
+
+
+
+
+
+
+SVD scoring
+
+Number of microbleeds (SWI)
+Superficiel siderose (SWI)
+Lacunes (3D FLAIR)
+White matter hyperintensities (3D FLAIR)
+Enlarged Perivascular Space (3D FLAIR)
+Atrophy (3D T1)
+
+
+
+
+IQCODE og RBANS
+
+
+
+
+
+
+
+
+
+ Characteristic
+ Overall , N = 95
+ female , N = 33
+ male , N = 62
+
+
+
+ mRS at inclusion
+
+
+
+ 0
+69 (73%)
+22 (67%)
+47 (76%)
+ 1
+17 (18%)
+6 (18%)
+11 (18%)
+ 2
+9 (9.5%)
+5 (15%)
+4 (6.5%)
+ IQCODE score
+49.0 (48.0, 54.0)
+49.5 (48.0, 53.0)
+49.0 (48.0, 54.0)
+ RBANS 3 months
+81 (73, 90)
+83 (73, 90)
+80 (74, 85)
+ RBANS 12 months
+84 (73, 94)
+86 (72, 92)
+78 (73, 93)
+
+
+
+
+
+
+
+
+
+RBANS plot
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/3 Cognitive change/project-presentation.qmd b/3 Cognitive change/project-presentation.qmd
new file mode 100644
index 0000000..10f0c2e
--- /dev/null
+++ b/3 Cognitive change/project-presentation.qmd
@@ -0,0 +1,160 @@
+---
+title: "Physical activity before stroke, small vessel disease and cognitive decline after stroke"
+format:
+ revealjs:
+ footer: "Andreas"
+ slide-number: c/t
+ show-slide-number: all
+ toc: true
+ toc-title: "Overview"
+ logo: dsc_tekst.png
+ theme: serif
+ css: style.css
+editor: visual
+---
+
+## Hypothesis
+
+```{r}
+library(tidyverse)
+# remotes::install_github("agdamsbo/REDCapRITS")
+
+library(gtsummary)
+library(patchwork)
+library(REDCapRITS)
+
+# REDCapR::redcap_instruments(redcap_uri = "https://redcap.au.dk/api/", token = keyring::key_get("enigma_api_key"))$data
+
+d_list <- REDCapRITS::read_redcap_tables(
+ uri = "https://redcap.au.dk/api/",
+ token = keyring::key_get("enigma_api_key"),
+ fields = c("record_id", "incl_by" , "incl_date"),
+ forms = c(
+ "klassifikation_af_primre_stroke",
+ "baseline_stroke",
+ "registrering",
+ "baseline_nihss",
+ "mrs",
+ "uddannelsesniveau",
+ "hjde_vgt_og_blodtryk",
+ "rygeanamnese",
+ "rbans",
+ "iqcode",
+ "eos"
+ )
+)
+```
+
+```{r message=FALSE}
+d <- REDCapRITS::redcap_wider(d_list)
+```
+
+> Higher level of PA before acute ischemic stroke (AIS) is associated with decreased risk of cognitive decline after stroke independently of stroke severity and cSVD burden.
+
+## Data {.smaller}
+
+- Physical Activity Scale in the Elderly (**PASE**) questionnaire
+- Modified Rankin Scale (**mRS**)
+- Level of education
+- Informant Questionnaire on Cognitive Decline in the Elderly, short version (**IQCODE**)
+- Repeatable Battery for the Assessment of Neuropsychological Status (**RBANS**), Scandinavian version
+- Wellbeing and depressive symptoms
+- Cerebral Small vessel disease burden (**cSVD score**)
+
+## Education {.smaller}
+
+```{r education}
+# dput(levels(factor(d$education_inclusion_long)))
+
+d |>
+ select(kon, education_inclusion_long, ) |>
+ mutate(
+ education_inclusion_long = factor(
+ education_inclusion_long,
+ levels = c(
+ "Folkeskole (9-10 år)",
+ "Gymnasiale/erhvervsfaglige uddannelser (11-12 år)",
+ "Erhvervsakademiuddannelser (13-14 år)",
+ "Professionsbachelor/universitetsbachelor (15-17 år)",
+ "Kandidatuddannelser (18-19 år)",
+ "PhD ( > 20 år)"
+ )
+ )) |>
+ tbl_summary(
+ by = "kon",
+ missing = "ifany",
+ missing_text = "Not classified",
+ label = list(education_inclusion_long ~ "Level of education")
+ ) |>
+ add_overall(
+ )
+```
+
+## SVD scoring
+
+- Number of microbleeds (SWI)
+- Superficiel siderose (SWI)
+- Lacunes (3D FLAIR)
+- White matter hyperintensities (3D FLAIR)
+- Enlarged Perivascular Space (3D FLAIR)
+- Atrophy (3D T1)
+
+## SVD score {.scrollable}
+
+```{r}
+REDCapTidieR::read_redcap(
+ redcap_uri = "https://redcap.au.dk/api/",
+ token = keyring::key_get("enigma_api_key"),
+ forms = c("svd_score")) |> REDCapTidieR::bind_tibbles()
+
+svd_score |> filter(svd_initials=="AGD",redcap_event=="inclusion") |> select(svd_score) |> na.omit() |> mutate(svd_score = as.numeric(svd_score)) |> tbl_summary()
+```
+
+## IQCODE og RBANS {.smaller}
+
+```{r}
+d |>
+ select(kon,
+ mrs_score_inclusion_long,
+ iq_score,
+ rbans_e_is_3_months_long,
+ rbans_e_is_12_months_long
+ # ,
+ # svd_score
+ ) |>
+ mutate(mrs_score_inclusion_long=factor(mrs_score_inclusion_long,labels = c("0","1","2"))) |>
+ tbl_summary(
+ by = "kon",
+ missing = "no",
+ label = list(
+ mrs_score_inclusion_long~"mRS at inclusion",
+ iq_score~"IQCODE score",
+ rbans_e_is_3_months_long~"RBANS 3 months",
+ rbans_e_is_12_months_long~"RBANS 12 months"#,
+ # svd_score~"SVD score at inclusion"
+ )
+ ) |>
+ add_overall()
+```
+
+## RBANS plot
+
+```{r}
+source("/Users/au301842/ENIGMAtrial_R/src/plot_index.R")
+
+rbans <- d_list$rbans |>
+ dplyr::select(c("record_id",
+ "redcap_event_name",
+ ends_with(c("_is","_lo","_up","_per")))) |>
+ na.omit()|>
+ dplyr::mutate(redcap_event=factor(redcap_event_name,
+ levels = c("3_months","12_months"),
+ labels = c("3 months","12 months"))) |>
+ dplyr::tibble()
+
+rbans |>
+ dplyr::filter(record_id %in% record_id[duplicated(record_id)]) |> # Only patients with both 3 and 12 month
+ dplyr::filter(record_id %in% sample(record_id,5)) |> # 5 random patients
+ # filter(record_id %in% 28:32) |> # Only specified number
+ plot_index(id="redcap_event_name",facet.by = "record_id")
+```
diff --git a/3 Cognitive change/project-presentation_files/.DS_Store b/3 Cognitive change/project-presentation_files/.DS_Store
new file mode 100644
index 0000000..74e05e0
Binary files /dev/null and b/3 Cognitive change/project-presentation_files/.DS_Store differ
diff --git a/3 Cognitive change/project-presentation_files/figure-revealjs/unnamed-chunk-4-1.png b/3 Cognitive change/project-presentation_files/figure-revealjs/unnamed-chunk-4-1.png
new file mode 100644
index 0000000..d9694e2
Binary files /dev/null and b/3 Cognitive change/project-presentation_files/figure-revealjs/unnamed-chunk-4-1.png differ
diff --git a/3 Cognitive change/project-presentation_files/figure-revealjs/unnamed-chunk-5-1.png b/3 Cognitive change/project-presentation_files/figure-revealjs/unnamed-chunk-5-1.png
new file mode 100644
index 0000000..ce25678
Binary files /dev/null and b/3 Cognitive change/project-presentation_files/figure-revealjs/unnamed-chunk-5-1.png differ
diff --git a/3 Cognitive change/project-presentation_files/libs/clipboard/clipboard.min.js b/3 Cognitive change/project-presentation_files/libs/clipboard/clipboard.min.js
new file mode 100644
index 0000000..41c6a0f
--- /dev/null
+++ b/3 Cognitive change/project-presentation_files/libs/clipboard/clipboard.min.js
@@ -0,0 +1,7 @@
+/*!
+ * clipboard.js v2.0.10
+ * https://clipboardjs.com/
+ *
+ * Licensed MIT © Zeno Rocha
+ */
+!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=10&&(o=s(n.width)/f||1),a>0&&(i=s(n.height)/a||1)}return{width:n.width/o,height:n.height/i,top:n.top/i,right:n.right/o,bottom:n.bottom/i,left:n.left/o,x:n.left/o,y:n.top/i}}function c(e){var n=t(e);return{scrollLeft:n.pageXOffset,scrollTop:n.pageYOffset}}function p(e){return e?(e.nodeName||"").toLowerCase():null}function u(e){return((n(e)?e.ownerDocument:e.document)||window.document).documentElement}function l(e){return f(u(e)).left+c(e).scrollLeft}function d(e){return t(e).getComputedStyle(e)}function h(e){var t=d(e),n=t.overflow,r=t.overflowX,o=t.overflowY;return/auto|scroll|overlay|hidden/.test(n+o+r)}function m(e,n,o){void 0===o&&(o=!1);var i,a,d=r(n),m=r(n)&&function(e){var t=e.getBoundingClientRect(),n=s(t.width)/e.offsetWidth||1,r=s(t.height)/e.offsetHeight||1;return 1!==n||1!==r}(n),v=u(n),g=f(e,m),y={scrollLeft:0,scrollTop:0},b={x:0,y:0};return(d||!d&&!o)&&(("body"!==p(n)||h(v))&&(y=(i=n)!==t(i)&&r(i)?{scrollLeft:(a=i).scrollLeft,scrollTop:a.scrollTop}:c(i)),r(n)?((b=f(n,!0)).x+=n.clientLeft,b.y+=n.clientTop):v&&(b.x=l(v))),{x:g.left+y.scrollLeft-b.x,y:g.top+y.scrollTop-b.y,width:g.width,height:g.height}}function v(e){var t=f(e),n=e.offsetWidth,r=e.offsetHeight;return Math.abs(t.width-n)<=1&&(n=t.width),Math.abs(t.height-r)<=1&&(r=t.height),{x:e.offsetLeft,y:e.offsetTop,width:n,height:r}}function g(e){return"html"===p(e)?e:e.assignedSlot||e.parentNode||(o(e)?e.host:null)||u(e)}function y(e){return["html","body","#document"].indexOf(p(e))>=0?e.ownerDocument.body:r(e)&&h(e)?e:y(g(e))}function b(e,n){var r;void 0===n&&(n=[]);var o=y(e),i=o===(null==(r=e.ownerDocument)?void 0:r.body),a=t(o),s=i?[a].concat(a.visualViewport||[],h(o)?o:[]):o,f=n.concat(s);return i?f:f.concat(b(g(s)))}function x(e){return["table","td","th"].indexOf(p(e))>=0}function w(e){return r(e)&&"fixed"!==d(e).position?e.offsetParent:null}function O(e){for(var n=t(e),i=w(e);i&&x(i)&&"static"===d(i).position;)i=w(i);return i&&("html"===p(i)||"body"===p(i)&&"static"===d(i).position)?n:i||function(e){var t=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&r(e)&&"fixed"===d(e).position)return null;var n=g(e);for(o(n)&&(n=n.host);r(n)&&["html","body"].indexOf(p(n))<0;){var i=d(n);if("none"!==i.transform||"none"!==i.perspective||"paint"===i.contain||-1!==["transform","perspective"].indexOf(i.willChange)||t&&"filter"===i.willChange||t&&i.filter&&"none"!==i.filter)return n;n=n.parentNode}return null}(e)||n}var j="top",E="bottom",D="right",A="left",L="auto",P=[j,E,D,A],M="start",k="end",W="viewport",B="popper",H=P.reduce((function(e,t){return e.concat([t+"-"+M,t+"-"+k])}),[]),T=[].concat(P,[L]).reduce((function(e,t){return e.concat([t,t+"-"+M,t+"-"+k])}),[]),R=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function S(e){var t=new Map,n=new Set,r=[];function o(e){n.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){if(!n.has(e)){var r=t.get(e);r&&o(r)}})),r.push(e)}return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){n.has(e.name)||o(e)})),r}function C(e){return e.split("-")[0]}function q(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&o(n)){var r=t;do{if(r&&e.isSameNode(r))return!0;r=r.parentNode||r.host}while(r)}return!1}function V(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function N(e,r){return r===W?V(function(e){var n=t(e),r=u(e),o=n.visualViewport,i=r.clientWidth,a=r.clientHeight,s=0,f=0;return o&&(i=o.width,a=o.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(s=o.offsetLeft,f=o.offsetTop)),{width:i,height:a,x:s+l(e),y:f}}(e)):n(r)?function(e){var t=f(e);return t.top=t.top+e.clientTop,t.left=t.left+e.clientLeft,t.bottom=t.top+e.clientHeight,t.right=t.left+e.clientWidth,t.width=e.clientWidth,t.height=e.clientHeight,t.x=t.left,t.y=t.top,t}(r):V(function(e){var t,n=u(e),r=c(e),o=null==(t=e.ownerDocument)?void 0:t.body,a=i(n.scrollWidth,n.clientWidth,o?o.scrollWidth:0,o?o.clientWidth:0),s=i(n.scrollHeight,n.clientHeight,o?o.scrollHeight:0,o?o.clientHeight:0),f=-r.scrollLeft+l(e),p=-r.scrollTop;return"rtl"===d(o||n).direction&&(f+=i(n.clientWidth,o?o.clientWidth:0)-a),{width:a,height:s,x:f,y:p}}(u(e)))}function I(e,t,o){var s="clippingParents"===t?function(e){var t=b(g(e)),o=["absolute","fixed"].indexOf(d(e).position)>=0&&r(e)?O(e):e;return n(o)?t.filter((function(e){return n(e)&&q(e,o)&&"body"!==p(e)})):[]}(e):[].concat(t),f=[].concat(s,[o]),c=f[0],u=f.reduce((function(t,n){var r=N(e,n);return t.top=i(r.top,t.top),t.right=a(r.right,t.right),t.bottom=a(r.bottom,t.bottom),t.left=i(r.left,t.left),t}),N(e,c));return u.width=u.right-u.left,u.height=u.bottom-u.top,u.x=u.left,u.y=u.top,u}function _(e){return e.split("-")[1]}function F(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}function U(e){var t,n=e.reference,r=e.element,o=e.placement,i=o?C(o):null,a=o?_(o):null,s=n.x+n.width/2-r.width/2,f=n.y+n.height/2-r.height/2;switch(i){case j:t={x:s,y:n.y-r.height};break;case E:t={x:s,y:n.y+n.height};break;case D:t={x:n.x+n.width,y:f};break;case A:t={x:n.x-r.width,y:f};break;default:t={x:n.x,y:n.y}}var c=i?F(i):null;if(null!=c){var p="y"===c?"height":"width";switch(a){case M:t[c]=t[c]-(n[p]/2-r[p]/2);break;case k:t[c]=t[c]+(n[p]/2-r[p]/2)}}return t}function z(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function X(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function Y(e,t){void 0===t&&(t={});var r=t,o=r.placement,i=void 0===o?e.placement:o,a=r.boundary,s=void 0===a?"clippingParents":a,c=r.rootBoundary,p=void 0===c?W:c,l=r.elementContext,d=void 0===l?B:l,h=r.altBoundary,m=void 0!==h&&h,v=r.padding,g=void 0===v?0:v,y=z("number"!=typeof g?g:X(g,P)),b=d===B?"reference":B,x=e.rects.popper,w=e.elements[m?b:d],O=I(n(w)?w:w.contextElement||u(e.elements.popper),s,p),A=f(e.elements.reference),L=U({reference:A,element:x,strategy:"absolute",placement:i}),M=V(Object.assign({},x,L)),k=d===B?M:A,H={top:O.top-k.top+y.top,bottom:k.bottom-O.bottom+y.bottom,left:O.left-k.left+y.left,right:k.right-O.right+y.right},T=e.modifiersData.offset;if(d===B&&T){var R=T[i];Object.keys(H).forEach((function(e){var t=[D,E].indexOf(e)>=0?1:-1,n=[j,E].indexOf(e)>=0?"y":"x";H[e]+=R[n]*t}))}return H}var G={placement:"bottom",modifiers:[],strategy:"absolute"};function J(){for(var e=arguments.length,t=new Array(e),n=0;n=0?-1:1,i="function"==typeof n?n(Object.assign({},t,{placement:e})):n,a=i[0],s=i[1];return a=a||0,s=(s||0)*o,[A,D].indexOf(r)>=0?{x:s,y:a}:{x:a,y:s}}(n,t.rects,i),e}),{}),s=a[t.placement],f=s.x,c=s.y;null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=f,t.modifiersData.popperOffsets.y+=c),t.modifiersData[r]=a}},ie={left:"right",right:"left",bottom:"top",top:"bottom"};function ae(e){return e.replace(/left|right|bottom|top/g,(function(e){return ie[e]}))}var se={start:"end",end:"start"};function fe(e){return e.replace(/start|end/g,(function(e){return se[e]}))}function ce(e,t){void 0===t&&(t={});var n=t,r=n.placement,o=n.boundary,i=n.rootBoundary,a=n.padding,s=n.flipVariations,f=n.allowedAutoPlacements,c=void 0===f?T:f,p=_(r),u=p?s?H:H.filter((function(e){return _(e)===p})):P,l=u.filter((function(e){return c.indexOf(e)>=0}));0===l.length&&(l=u);var d=l.reduce((function(t,n){return t[n]=Y(e,{placement:n,boundary:o,rootBoundary:i,padding:a})[C(n)],t}),{});return Object.keys(d).sort((function(e,t){return d[e]-d[t]}))}var pe={name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name;if(!t.modifiersData[r]._skip){for(var o=n.mainAxis,i=void 0===o||o,a=n.altAxis,s=void 0===a||a,f=n.fallbackPlacements,c=n.padding,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.flipVariations,h=void 0===d||d,m=n.allowedAutoPlacements,v=t.options.placement,g=C(v),y=f||(g===v||!h?[ae(v)]:function(e){if(C(e)===L)return[];var t=ae(e);return[fe(e),t,fe(t)]}(v)),b=[v].concat(y).reduce((function(e,n){return e.concat(C(n)===L?ce(t,{placement:n,boundary:p,rootBoundary:u,padding:c,flipVariations:h,allowedAutoPlacements:m}):n)}),[]),x=t.rects.reference,w=t.rects.popper,O=new Map,P=!0,k=b[0],W=0;W=0,S=R?"width":"height",q=Y(t,{placement:B,boundary:p,rootBoundary:u,altBoundary:l,padding:c}),V=R?T?D:A:T?E:j;x[S]>w[S]&&(V=ae(V));var N=ae(V),I=[];if(i&&I.push(q[H]<=0),s&&I.push(q[V]<=0,q[N]<=0),I.every((function(e){return e}))){k=B,P=!1;break}O.set(B,I)}if(P)for(var F=function(e){var t=b.find((function(t){var n=O.get(t);if(n)return n.slice(0,e).every((function(e){return e}))}));if(t)return k=t,"break"},U=h?3:1;U>0;U--){if("break"===F(U))break}t.placement!==k&&(t.modifiersData[r]._skip=!0,t.placement=k,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function ue(e,t,n){return i(e,a(t,n))}var le={name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name,o=n.mainAxis,s=void 0===o||o,f=n.altAxis,c=void 0!==f&&f,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.padding,h=n.tether,m=void 0===h||h,g=n.tetherOffset,y=void 0===g?0:g,b=Y(t,{boundary:p,rootBoundary:u,padding:d,altBoundary:l}),x=C(t.placement),w=_(t.placement),L=!w,P=F(x),k="x"===P?"y":"x",W=t.modifiersData.popperOffsets,B=t.rects.reference,H=t.rects.popper,T="function"==typeof y?y(Object.assign({},t.rects,{placement:t.placement})):y,R="number"==typeof T?{mainAxis:T,altAxis:T}:Object.assign({mainAxis:0,altAxis:0},T),S=t.modifiersData.offset?t.modifiersData.offset[t.placement]:null,q={x:0,y:0};if(W){if(s){var V,N="y"===P?j:A,I="y"===P?E:D,U="y"===P?"height":"width",z=W[P],X=z+b[N],G=z-b[I],J=m?-H[U]/2:0,K=w===M?B[U]:H[U],Q=w===M?-H[U]:-B[U],Z=t.elements.arrow,$=m&&Z?v(Z):{width:0,height:0},ee=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},te=ee[N],ne=ee[I],re=ue(0,B[U],$[U]),oe=L?B[U]/2-J-re-te-R.mainAxis:K-re-te-R.mainAxis,ie=L?-B[U]/2+J+re+ne+R.mainAxis:Q+re+ne+R.mainAxis,ae=t.elements.arrow&&O(t.elements.arrow),se=ae?"y"===P?ae.clientTop||0:ae.clientLeft||0:0,fe=null!=(V=null==S?void 0:S[P])?V:0,ce=z+ie-fe,pe=ue(m?a(X,z+oe-fe-se):X,z,m?i(G,ce):G);W[P]=pe,q[P]=pe-z}if(c){var le,de="x"===P?j:A,he="x"===P?E:D,me=W[k],ve="y"===k?"height":"width",ge=me+b[de],ye=me-b[he],be=-1!==[j,A].indexOf(x),xe=null!=(le=null==S?void 0:S[k])?le:0,we=be?ge:me-B[ve]-H[ve]-xe+R.altAxis,Oe=be?me+B[ve]+H[ve]-xe-R.altAxis:ye,je=m&&be?function(e,t,n){var r=ue(e,t,n);return r>n?n:r}(we,me,Oe):ue(m?we:ge,me,m?Oe:ye);W[k]=je,q[k]=je-me}t.modifiersData[r]=q}},requiresIfExists:["offset"]};var de={name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state,r=e.name,o=e.options,i=n.elements.arrow,a=n.modifiersData.popperOffsets,s=C(n.placement),f=F(s),c=[A,D].indexOf(s)>=0?"height":"width";if(i&&a){var p=function(e,t){return z("number"!=typeof(e="function"==typeof e?e(Object.assign({},t.rects,{placement:t.placement})):e)?e:X(e,P))}(o.padding,n),u=v(i),l="y"===f?j:A,d="y"===f?E:D,h=n.rects.reference[c]+n.rects.reference[f]-a[f]-n.rects.popper[c],m=a[f]-n.rects.reference[f],g=O(i),y=g?"y"===f?g.clientHeight||0:g.clientWidth||0:0,b=h/2-m/2,x=p[l],w=y-u[c]-p[d],L=y/2-u[c]/2+b,M=ue(x,L,w),k=f;n.modifiersData[r]=((t={})[k]=M,t.centerOffset=M-L,t)}},effect:function(e){var t=e.state,n=e.options.element,r=void 0===n?"[data-popper-arrow]":n;null!=r&&("string"!=typeof r||(r=t.elements.popper.querySelector(r)))&&q(t.elements.popper,r)&&(t.elements.arrow=r)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function he(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function me(e){return[j,D,E,A].some((function(t){return e[t]>=0}))}var ve={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state,n=e.name,r=t.rects.reference,o=t.rects.popper,i=t.modifiersData.preventOverflow,a=Y(t,{elementContext:"reference"}),s=Y(t,{altBoundary:!0}),f=he(a,r),c=he(s,o,i),p=me(f),u=me(c);t.modifiersData[n]={referenceClippingOffsets:f,popperEscapeOffsets:c,isReferenceHidden:p,hasPopperEscaped:u},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":p,"data-popper-escaped":u})}},ge=K({defaultModifiers:[Z,$,ne,re]}),ye=[Z,$,ne,re,oe,pe,le,de,ve],be=K({defaultModifiers:ye});e.applyStyles=re,e.arrow=de,e.computeStyles=ne,e.createPopper=be,e.createPopperLite=ge,e.defaultModifiers=ye,e.detectOverflow=Y,e.eventListeners=Z,e.flip=pe,e.hide=ve,e.offset=oe,e.popperGenerator=K,e.popperOffsets=$,e.preventOverflow=le,Object.defineProperty(e,"__esModule",{value:!0})}));
+
diff --git a/3 Cognitive change/project-presentation_files/libs/quarto-html/quarto-html.min.css b/3 Cognitive change/project-presentation_files/libs/quarto-html/quarto-html.min.css
new file mode 100644
index 0000000..c2857c3
--- /dev/null
+++ b/3 Cognitive change/project-presentation_files/libs/quarto-html/quarto-html.min.css
@@ -0,0 +1 @@
+/*# sourceMappingURL=0a6b880beb84f9b6f36107a76f82c5b1.css.map */
diff --git a/3 Cognitive change/project-presentation_files/libs/quarto-html/quarto-syntax-highlighting-dark.css b/3 Cognitive change/project-presentation_files/libs/quarto-html/quarto-syntax-highlighting-dark.css
new file mode 100644
index 0000000..941c9df
--- /dev/null
+++ b/3 Cognitive change/project-presentation_files/libs/quarto-html/quarto-syntax-highlighting-dark.css
@@ -0,0 +1,187 @@
+/* quarto syntax highlight colors */
+:root {
+ --quarto-hl-al-color: #f07178;
+ --quarto-hl-an-color: #d4d0ab;
+ --quarto-hl-at-color: #00e0e0;
+ --quarto-hl-bn-color: #d4d0ab;
+ --quarto-hl-bu-color: #abe338;
+ --quarto-hl-ch-color: #abe338;
+ --quarto-hl-co-color: #f8f8f2;
+ --quarto-hl-cv-color: #ffd700;
+ --quarto-hl-cn-color: #ffd700;
+ --quarto-hl-cf-color: #ffa07a;
+ --quarto-hl-dt-color: #ffa07a;
+ --quarto-hl-dv-color: #d4d0ab;
+ --quarto-hl-do-color: #f8f8f2;
+ --quarto-hl-er-color: #f07178;
+ --quarto-hl-ex-color: #00e0e0;
+ --quarto-hl-fl-color: #d4d0ab;
+ --quarto-hl-fu-color: #ffa07a;
+ --quarto-hl-im-color: #abe338;
+ --quarto-hl-in-color: #d4d0ab;
+ --quarto-hl-kw-color: #ffa07a;
+ --quarto-hl-op-color: #ffa07a;
+ --quarto-hl-ot-color: #00e0e0;
+ --quarto-hl-pp-color: #dcc6e0;
+ --quarto-hl-re-color: #00e0e0;
+ --quarto-hl-sc-color: #abe338;
+ --quarto-hl-ss-color: #abe338;
+ --quarto-hl-st-color: #abe338;
+ --quarto-hl-va-color: #00e0e0;
+ --quarto-hl-vs-color: #abe338;
+ --quarto-hl-wa-color: #dcc6e0;
+}
+
+/* other quarto variables */
+:root {
+ --quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+}
+
+code span.al {
+ font-weight: bold;
+ color: #f07178;
+}
+
+code span.an {
+ color: #d4d0ab;
+}
+
+code span.at {
+ color: #00e0e0;
+}
+
+code span.bn {
+ color: #d4d0ab;
+}
+
+code span.bu {
+ color: #abe338;
+}
+
+code span.ch {
+ color: #abe338;
+}
+
+code span.co {
+ font-style: italic;
+ color: #f8f8f2;
+}
+
+code span.cv {
+ color: #ffd700;
+}
+
+code span.cn {
+ color: #ffd700;
+}
+
+code span.cf {
+ font-weight: bold;
+ color: #ffa07a;
+}
+
+code span.dt {
+ color: #ffa07a;
+}
+
+code span.dv {
+ color: #d4d0ab;
+}
+
+code span.do {
+ color: #f8f8f2;
+}
+
+code span.er {
+ color: #f07178;
+ text-decoration: underline;
+}
+
+code span.ex {
+ font-weight: bold;
+ color: #00e0e0;
+}
+
+code span.fl {
+ color: #d4d0ab;
+}
+
+code span.fu {
+ color: #ffa07a;
+}
+
+code span.im {
+ color: #abe338;
+}
+
+code span.in {
+ color: #d4d0ab;
+}
+
+code span.kw {
+ font-weight: bold;
+ color: #ffa07a;
+}
+
+pre > code.sourceCode > span {
+ color: #f8f8f2;
+}
+
+code span {
+ color: #f8f8f2;
+}
+
+code.sourceCode > span {
+ color: #f8f8f2;
+}
+
+div.sourceCode,
+div.sourceCode pre.sourceCode {
+ color: #f8f8f2;
+}
+
+code span.op {
+ color: #ffa07a;
+}
+
+code span.ot {
+ color: #00e0e0;
+}
+
+code span.pp {
+ color: #dcc6e0;
+}
+
+code span.re {
+ color: #00e0e0;
+}
+
+code span.sc {
+ color: #abe338;
+}
+
+code span.ss {
+ color: #abe338;
+}
+
+code span.st {
+ color: #abe338;
+}
+
+code span.va {
+ color: #00e0e0;
+}
+
+code span.vs {
+ color: #abe338;
+}
+
+code span.wa {
+ color: #dcc6e0;
+}
+
+.prevent-inlining {
+ content: "";
+}
+
+/*# sourceMappingURL=935a306eefa94366c21e1a970dddb765.css.map */
diff --git a/3 Cognitive change/project-presentation_files/libs/quarto-html/quarto-syntax-highlighting.css b/3 Cognitive change/project-presentation_files/libs/quarto-html/quarto-syntax-highlighting.css
new file mode 100644
index 0000000..36cb328
--- /dev/null
+++ b/3 Cognitive change/project-presentation_files/libs/quarto-html/quarto-syntax-highlighting.css
@@ -0,0 +1,171 @@
+/* quarto syntax highlight colors */
+:root {
+ --quarto-hl-ot-color: #003B4F;
+ --quarto-hl-at-color: #657422;
+ --quarto-hl-ss-color: #20794D;
+ --quarto-hl-an-color: #5E5E5E;
+ --quarto-hl-fu-color: #4758AB;
+ --quarto-hl-st-color: #20794D;
+ --quarto-hl-cf-color: #003B4F;
+ --quarto-hl-op-color: #5E5E5E;
+ --quarto-hl-er-color: #AD0000;
+ --quarto-hl-bn-color: #AD0000;
+ --quarto-hl-al-color: #AD0000;
+ --quarto-hl-va-color: #111111;
+ --quarto-hl-bu-color: inherit;
+ --quarto-hl-ex-color: inherit;
+ --quarto-hl-pp-color: #AD0000;
+ --quarto-hl-in-color: #5E5E5E;
+ --quarto-hl-vs-color: #20794D;
+ --quarto-hl-wa-color: #5E5E5E;
+ --quarto-hl-do-color: #5E5E5E;
+ --quarto-hl-im-color: #00769E;
+ --quarto-hl-ch-color: #20794D;
+ --quarto-hl-dt-color: #AD0000;
+ --quarto-hl-fl-color: #AD0000;
+ --quarto-hl-co-color: #5E5E5E;
+ --quarto-hl-cv-color: #5E5E5E;
+ --quarto-hl-cn-color: #8f5902;
+ --quarto-hl-sc-color: #5E5E5E;
+ --quarto-hl-dv-color: #AD0000;
+ --quarto-hl-kw-color: #003B4F;
+}
+
+/* other quarto variables */
+:root {
+ --quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+}
+
+pre > code.sourceCode > span {
+ color: #003B4F;
+}
+
+code span {
+ color: #003B4F;
+}
+
+code.sourceCode > span {
+ color: #003B4F;
+}
+
+div.sourceCode,
+div.sourceCode pre.sourceCode {
+ color: #003B4F;
+}
+
+code span.ot {
+ color: #003B4F;
+}
+
+code span.at {
+ color: #657422;
+}
+
+code span.ss {
+ color: #20794D;
+}
+
+code span.an {
+ color: #5E5E5E;
+}
+
+code span.fu {
+ color: #4758AB;
+}
+
+code span.st {
+ color: #20794D;
+}
+
+code span.cf {
+ color: #003B4F;
+}
+
+code span.op {
+ color: #5E5E5E;
+}
+
+code span.er {
+ color: #AD0000;
+}
+
+code span.bn {
+ color: #AD0000;
+}
+
+code span.al {
+ color: #AD0000;
+}
+
+code span.va {
+ color: #111111;
+}
+
+code span.pp {
+ color: #AD0000;
+}
+
+code span.in {
+ color: #5E5E5E;
+}
+
+code span.vs {
+ color: #20794D;
+}
+
+code span.wa {
+ color: #5E5E5E;
+ font-style: italic;
+}
+
+code span.do {
+ color: #5E5E5E;
+ font-style: italic;
+}
+
+code span.im {
+ color: #00769E;
+}
+
+code span.ch {
+ color: #20794D;
+}
+
+code span.dt {
+ color: #AD0000;
+}
+
+code span.fl {
+ color: #AD0000;
+}
+
+code span.co {
+ color: #5E5E5E;
+}
+
+code span.cv {
+ color: #5E5E5E;
+ font-style: italic;
+}
+
+code span.cn {
+ color: #8f5902;
+}
+
+code span.sc {
+ color: #5E5E5E;
+}
+
+code span.dv {
+ color: #AD0000;
+}
+
+code span.kw {
+ color: #003B4F;
+}
+
+.prevent-inlining {
+ content: "";
+}
+
+/*# sourceMappingURL=debc5d5d77c3f9108843748ff7464032.css.map */
diff --git a/3 Cognitive change/project-presentation_files/libs/quarto-html/tabby.min.js b/3 Cognitive change/project-presentation_files/libs/quarto-html/tabby.min.js
new file mode 100644
index 0000000..4f44c7d
--- /dev/null
+++ b/3 Cognitive change/project-presentation_files/libs/quarto-html/tabby.min.js
@@ -0,0 +1,418 @@
+(function (root, factory) {
+ if (typeof define === "function" && define.amd) {
+ define([], function () {
+ return factory(root);
+ });
+ } else if (typeof exports === "object") {
+ module.exports = factory(root);
+ } else {
+ root.Tabby = factory(root);
+ }
+})(
+ typeof global !== "undefined"
+ ? global
+ : typeof window !== "undefined"
+ ? window
+ : this,
+ function (window) {
+ "use strict";
+
+ //
+ // Variables
+ //
+
+ var defaults = {
+ idPrefix: "tabby-toggle_",
+ default: "[data-tabby-default]",
+ };
+
+ //
+ // Methods
+ //
+
+ /**
+ * Merge two or more objects together.
+ * @param {Object} objects The objects to merge together
+ * @returns {Object} Merged values of defaults and options
+ */
+ var extend = function () {
+ var merged = {};
+ Array.prototype.forEach.call(arguments, function (obj) {
+ for (var key in obj) {
+ if (!obj.hasOwnProperty(key)) return;
+ merged[key] = obj[key];
+ }
+ });
+ return merged;
+ };
+
+ /**
+ * Emit a custom event
+ * @param {String} type The event type
+ * @param {Node} tab The tab to attach the event to
+ * @param {Node} details Details about the event
+ */
+ var emitEvent = function (tab, details) {
+ // Create a new event
+ var event;
+ if (typeof window.CustomEvent === "function") {
+ event = new CustomEvent("tabby", {
+ bubbles: true,
+ cancelable: true,
+ detail: details,
+ });
+ } else {
+ event = document.createEvent("CustomEvent");
+ event.initCustomEvent("tabby", true, true, details);
+ }
+
+ // Dispatch the event
+ tab.dispatchEvent(event);
+ };
+
+ var focusHandler = function (event) {
+ toggle(event.target);
+ };
+
+ var getKeyboardFocusableElements = function (element) {
+ return [
+ ...element.querySelectorAll(
+ 'a[href], button, input, textarea, select, details,[tabindex]:not([tabindex="-1"])'
+ ),
+ ].filter(
+ (el) => !el.hasAttribute("disabled") && !el.getAttribute("aria-hidden")
+ );
+ };
+
+ /**
+ * Remove roles and attributes from a tab and its content
+ * @param {Node} tab The tab
+ * @param {Node} content The tab content
+ * @param {Object} settings User settings and options
+ */
+ var destroyTab = function (tab, content, settings) {
+ // Remove the generated ID
+ if (tab.id.slice(0, settings.idPrefix.length) === settings.idPrefix) {
+ tab.id = "";
+ }
+
+ // remove event listener
+ tab.removeEventListener("focus", focusHandler, true);
+
+ // Remove roles
+ tab.removeAttribute("role");
+ tab.removeAttribute("aria-controls");
+ tab.removeAttribute("aria-selected");
+ tab.removeAttribute("tabindex");
+ tab.closest("li").removeAttribute("role");
+ content.removeAttribute("role");
+ content.removeAttribute("aria-labelledby");
+ content.removeAttribute("hidden");
+ };
+
+ /**
+ * Add the required roles and attributes to a tab and its content
+ * @param {Node} tab The tab
+ * @param {Node} content The tab content
+ * @param {Object} settings User settings and options
+ */
+ var setupTab = function (tab, content, settings) {
+ // Give tab an ID if it doesn't already have one
+ if (!tab.id) {
+ tab.id = settings.idPrefix + content.id;
+ }
+
+ // Add roles
+ tab.setAttribute("role", "tab");
+ tab.setAttribute("aria-controls", content.id);
+ tab.closest("li").setAttribute("role", "presentation");
+ content.setAttribute("role", "tabpanel");
+ content.setAttribute("aria-labelledby", tab.id);
+
+ // Add selected state
+ if (tab.matches(settings.default)) {
+ tab.setAttribute("aria-selected", "true");
+ } else {
+ tab.setAttribute("aria-selected", "false");
+ content.setAttribute("hidden", "hidden");
+ }
+
+ // add focus event listender
+ tab.addEventListener("focus", focusHandler);
+ };
+
+ /**
+ * Hide a tab and its content
+ * @param {Node} newTab The new tab that's replacing it
+ */
+ var hide = function (newTab) {
+ // Variables
+ var tabGroup = newTab.closest('[role="tablist"]');
+ if (!tabGroup) return {};
+ var tab = tabGroup.querySelector('[role="tab"][aria-selected="true"]');
+ if (!tab) return {};
+ var content = document.querySelector(tab.hash);
+
+ // Hide the tab
+ tab.setAttribute("aria-selected", "false");
+
+ // Hide the content
+ if (!content) return { previousTab: tab };
+ content.setAttribute("hidden", "hidden");
+
+ // Return the hidden tab and content
+ return {
+ previousTab: tab,
+ previousContent: content,
+ };
+ };
+
+ /**
+ * Show a tab and its content
+ * @param {Node} tab The tab
+ * @param {Node} content The tab content
+ */
+ var show = function (tab, content) {
+ tab.setAttribute("aria-selected", "true");
+ content.removeAttribute("hidden");
+ tab.focus();
+ };
+
+ /**
+ * Toggle a new tab
+ * @param {Node} tab The tab to show
+ */
+ var toggle = function (tab) {
+ // Make sure there's a tab to toggle and it's not already active
+ if (!tab || tab.getAttribute("aria-selected") == "true") return;
+
+ // Variables
+ var content = document.querySelector(tab.hash);
+ if (!content) return;
+
+ // Hide active tab and content
+ var details = hide(tab);
+
+ // Show new tab and content
+ show(tab, content);
+
+ // Add event details
+ details.tab = tab;
+ details.content = content;
+
+ // Emit a custom event
+ emitEvent(tab, details);
+ };
+
+ /**
+ * Get all of the tabs in a tablist
+ * @param {Node} tab A tab from the list
+ * @return {Object} The tabs and the index of the currently active one
+ */
+ var getTabsMap = function (tab) {
+ var tabGroup = tab.closest('[role="tablist"]');
+ var tabs = tabGroup ? tabGroup.querySelectorAll('[role="tab"]') : null;
+ if (!tabs) return;
+ return {
+ tabs: tabs,
+ index: Array.prototype.indexOf.call(tabs, tab),
+ };
+ };
+
+ /**
+ * Switch the active tab based on keyboard activity
+ * @param {Node} tab The currently active tab
+ * @param {Key} key The key that was pressed
+ */
+ var switchTabs = function (tab, key) {
+ // Get a map of tabs
+ var map = getTabsMap(tab);
+ if (!map) return;
+ var length = map.tabs.length - 1;
+ var index;
+
+ // Go to previous tab
+ if (["ArrowUp", "ArrowLeft", "Up", "Left"].indexOf(key) > -1) {
+ index = map.index < 1 ? length : map.index - 1;
+ }
+
+ // Go to next tab
+ else if (["ArrowDown", "ArrowRight", "Down", "Right"].indexOf(key) > -1) {
+ index = map.index === length ? 0 : map.index + 1;
+ }
+
+ // Go to home
+ else if (key === "Home") {
+ index = 0;
+ }
+
+ // Go to end
+ else if (key === "End") {
+ index = length;
+ }
+
+ // Toggle the tab
+ toggle(map.tabs[index]);
+ };
+
+ /**
+ * Create the Constructor object
+ */
+ var Constructor = function (selector, options) {
+ //
+ // Variables
+ //
+
+ var publicAPIs = {};
+ var settings, tabWrapper;
+
+ //
+ // Methods
+ //
+
+ publicAPIs.destroy = function () {
+ // Get all tabs
+ var tabs = tabWrapper.querySelectorAll("a");
+
+ // Add roles to tabs
+ Array.prototype.forEach.call(tabs, function (tab) {
+ // Get the tab content
+ var content = document.querySelector(tab.hash);
+ if (!content) return;
+
+ // Setup the tab
+ destroyTab(tab, content, settings);
+ });
+
+ // Remove role from wrapper
+ tabWrapper.removeAttribute("role");
+
+ // Remove event listeners
+ document.documentElement.removeEventListener(
+ "click",
+ clickHandler,
+ true
+ );
+ tabWrapper.removeEventListener("keydown", keyHandler, true);
+
+ // Reset variables
+ settings = null;
+ tabWrapper = null;
+ };
+
+ /**
+ * Setup the DOM with the proper attributes
+ */
+ publicAPIs.setup = function () {
+ // Variables
+ tabWrapper = document.querySelector(selector);
+ if (!tabWrapper) return;
+ var tabs = tabWrapper.querySelectorAll("a");
+
+ // Add role to wrapper
+ tabWrapper.setAttribute("role", "tablist");
+
+ // Add roles to tabs. provide dynanmic tab indexes if we are within reveal
+ var contentTabindexes =
+ window.document.body.classList.contains("reveal-viewport");
+ var nextTabindex = 1;
+ Array.prototype.forEach.call(tabs, function (tab) {
+ if (contentTabindexes) {
+ tab.setAttribute("tabindex", "" + nextTabindex++);
+ } else {
+ tab.setAttribute("tabindex", "0");
+ }
+
+ // Get the tab content
+ var content = document.querySelector(tab.hash);
+ if (!content) return;
+
+ // set tab indexes for content
+ if (contentTabindexes) {
+ getKeyboardFocusableElements(content).forEach(function (el) {
+ el.setAttribute("tabindex", "" + nextTabindex++);
+ });
+ }
+
+ // Setup the tab
+ setupTab(tab, content, settings);
+ });
+ };
+
+ /**
+ * Toggle a tab based on an ID
+ * @param {String|Node} id The tab to toggle
+ */
+ publicAPIs.toggle = function (id) {
+ // Get the tab
+ var tab = id;
+ if (typeof id === "string") {
+ tab = document.querySelector(
+ selector + ' [role="tab"][href*="' + id + '"]'
+ );
+ }
+
+ // Toggle the tab
+ toggle(tab);
+ };
+
+ /**
+ * Handle click events
+ */
+ var clickHandler = function (event) {
+ // Only run on toggles
+ var tab = event.target.closest(selector + ' [role="tab"]');
+ if (!tab) return;
+
+ // Prevent link behavior
+ event.preventDefault();
+
+ // Toggle the tab
+ toggle(tab);
+ };
+
+ /**
+ * Handle keydown events
+ */
+ var keyHandler = function (event) {
+ // Only run if a tab is in focus
+ var tab = document.activeElement;
+ if (!tab.matches(selector + ' [role="tab"]')) return;
+
+ // Only run for specific keys
+ if (["Home", "End"].indexOf(event.key) < 0) return;
+
+ // Switch tabs
+ switchTabs(tab, event.key);
+ };
+
+ /**
+ * Initialize the instance
+ */
+ var init = function () {
+ // Merge user options with defaults
+ settings = extend(defaults, options || {});
+
+ // Setup the DOM
+ publicAPIs.setup();
+
+ // Add event listeners
+ document.documentElement.addEventListener("click", clickHandler, true);
+ tabWrapper.addEventListener("keydown", keyHandler, true);
+ };
+
+ //
+ // Initialize and return the Public APIs
+ //
+
+ init();
+ return publicAPIs;
+ };
+
+ //
+ // Return the Constructor
+ //
+
+ return Constructor;
+ }
+);
diff --git a/3 Cognitive change/project-presentation_files/libs/quarto-html/tippy.css b/3 Cognitive change/project-presentation_files/libs/quarto-html/tippy.css
new file mode 100644
index 0000000..e6ae635
--- /dev/null
+++ b/3 Cognitive change/project-presentation_files/libs/quarto-html/tippy.css
@@ -0,0 +1 @@
+.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}
\ No newline at end of file
diff --git a/3 Cognitive change/project-presentation_files/libs/quarto-html/tippy.umd.min.js b/3 Cognitive change/project-presentation_files/libs/quarto-html/tippy.umd.min.js
new file mode 100644
index 0000000..ca292be
--- /dev/null
+++ b/3 Cognitive change/project-presentation_files/libs/quarto-html/tippy.umd.min.js
@@ -0,0 +1,2 @@
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@popperjs/core")):"function"==typeof define&&define.amd?define(["@popperjs/core"],t):(e=e||self).tippy=t(e.Popper)}(this,(function(e){"use strict";var t={passive:!0,capture:!0},n=function(){return document.body};function r(e,t,n){if(Array.isArray(e)){var r=e[t];return null==r?Array.isArray(n)?n[t]:n:r}return e}function o(e,t){var n={}.toString.call(e);return 0===n.indexOf("[object")&&n.indexOf(t+"]")>-1}function i(e,t){return"function"==typeof e?e.apply(void 0,t):e}function a(e,t){return 0===t?e:function(r){clearTimeout(n),n=setTimeout((function(){e(r)}),t)};var n}function s(e,t){var n=Object.assign({},e);return t.forEach((function(e){delete n[e]})),n}function u(e){return[].concat(e)}function c(e,t){-1===e.indexOf(t)&&e.push(t)}function p(e){return e.split("-")[0]}function f(e){return[].slice.call(e)}function l(e){return Object.keys(e).reduce((function(t,n){return void 0!==e[n]&&(t[n]=e[n]),t}),{})}function d(){return document.createElement("div")}function v(e){return["Element","Fragment"].some((function(t){return o(e,t)}))}function m(e){return o(e,"MouseEvent")}function g(e){return!(!e||!e._tippy||e._tippy.reference!==e)}function h(e){return v(e)?[e]:function(e){return o(e,"NodeList")}(e)?f(e):Array.isArray(e)?e:f(document.querySelectorAll(e))}function b(e,t){e.forEach((function(e){e&&(e.style.transitionDuration=t+"ms")}))}function y(e,t){e.forEach((function(e){e&&e.setAttribute("data-state",t)}))}function w(e){var t,n=u(e)[0];return null!=n&&null!=(t=n.ownerDocument)&&t.body?n.ownerDocument:document}function E(e,t,n){var r=t+"EventListener";["transitionend","webkitTransitionEnd"].forEach((function(t){e[r](t,n)}))}function O(e,t){for(var n=t;n;){var r;if(e.contains(n))return!0;n=null==n.getRootNode||null==(r=n.getRootNode())?void 0:r.host}return!1}var x={isTouch:!1},C=0;function T(){x.isTouch||(x.isTouch=!0,window.performance&&document.addEventListener("mousemove",A))}function A(){var e=performance.now();e-C<20&&(x.isTouch=!1,document.removeEventListener("mousemove",A)),C=e}function L(){var e=document.activeElement;if(g(e)){var t=e._tippy;e.blur&&!t.state.isVisible&&e.blur()}}var D=!!("undefined"!=typeof window&&"undefined"!=typeof document)&&!!window.msCrypto,R=Object.assign({appendTo:n,aria:{content:"auto",expanded:"auto"},delay:0,duration:[300,250],getReferenceClientRect:null,hideOnClick:!0,ignoreAttributes:!1,interactive:!1,interactiveBorder:2,interactiveDebounce:0,moveTransition:"",offset:[0,10],onAfterUpdate:function(){},onBeforeUpdate:function(){},onCreate:function(){},onDestroy:function(){},onHidden:function(){},onHide:function(){},onMount:function(){},onShow:function(){},onShown:function(){},onTrigger:function(){},onUntrigger:function(){},onClickOutside:function(){},placement:"top",plugins:[],popperOptions:{},render:null,showOnCreate:!1,touch:!0,trigger:"mouseenter focus",triggerTarget:null},{animateFill:!1,followCursor:!1,inlinePositioning:!1,sticky:!1},{allowHTML:!1,animation:"fade",arrow:!0,content:"",inertia:!1,maxWidth:350,role:"tooltip",theme:"",zIndex:9999}),k=Object.keys(R);function P(e){var t=(e.plugins||[]).reduce((function(t,n){var r,o=n.name,i=n.defaultValue;o&&(t[o]=void 0!==e[o]?e[o]:null!=(r=R[o])?r:i);return t}),{});return Object.assign({},e,t)}function j(e,t){var n=Object.assign({},t,{content:i(t.content,[e])},t.ignoreAttributes?{}:function(e,t){return(t?Object.keys(P(Object.assign({},R,{plugins:t}))):k).reduce((function(t,n){var r=(e.getAttribute("data-tippy-"+n)||"").trim();if(!r)return t;if("content"===n)t[n]=r;else try{t[n]=JSON.parse(r)}catch(e){t[n]=r}return t}),{})}(e,t.plugins));return n.aria=Object.assign({},R.aria,n.aria),n.aria={expanded:"auto"===n.aria.expanded?t.interactive:n.aria.expanded,content:"auto"===n.aria.content?t.interactive?null:"describedby":n.aria.content},n}function M(e,t){e.innerHTML=t}function V(e){var t=d();return!0===e?t.className="tippy-arrow":(t.className="tippy-svg-arrow",v(e)?t.appendChild(e):M(t,e)),t}function I(e,t){v(t.content)?(M(e,""),e.appendChild(t.content)):"function"!=typeof t.content&&(t.allowHTML?M(e,t.content):e.textContent=t.content)}function S(e){var t=e.firstElementChild,n=f(t.children);return{box:t,content:n.find((function(e){return e.classList.contains("tippy-content")})),arrow:n.find((function(e){return e.classList.contains("tippy-arrow")||e.classList.contains("tippy-svg-arrow")})),backdrop:n.find((function(e){return e.classList.contains("tippy-backdrop")}))}}function N(e){var t=d(),n=d();n.className="tippy-box",n.setAttribute("data-state","hidden"),n.setAttribute("tabindex","-1");var r=d();function o(n,r){var o=S(t),i=o.box,a=o.content,s=o.arrow;r.theme?i.setAttribute("data-theme",r.theme):i.removeAttribute("data-theme"),"string"==typeof r.animation?i.setAttribute("data-animation",r.animation):i.removeAttribute("data-animation"),r.inertia?i.setAttribute("data-inertia",""):i.removeAttribute("data-inertia"),i.style.maxWidth="number"==typeof r.maxWidth?r.maxWidth+"px":r.maxWidth,r.role?i.setAttribute("role",r.role):i.removeAttribute("role"),n.content===r.content&&n.allowHTML===r.allowHTML||I(a,e.props),r.arrow?s?n.arrow!==r.arrow&&(i.removeChild(s),i.appendChild(V(r.arrow))):i.appendChild(V(r.arrow)):s&&i.removeChild(s)}return r.className="tippy-content",r.setAttribute("data-state","hidden"),I(r,e.props),t.appendChild(n),n.appendChild(r),o(e.props,e.props),{popper:t,onUpdate:o}}N.$$tippy=!0;var B=1,H=[],U=[];function _(o,s){var v,g,h,C,T,A,L,k,M=j(o,Object.assign({},R,P(l(s)))),V=!1,I=!1,N=!1,_=!1,F=[],W=a(we,M.interactiveDebounce),X=B++,Y=(k=M.plugins).filter((function(e,t){return k.indexOf(e)===t})),$={id:X,reference:o,popper:d(),popperInstance:null,props:M,state:{isEnabled:!0,isVisible:!1,isDestroyed:!1,isMounted:!1,isShown:!1},plugins:Y,clearDelayTimeouts:function(){clearTimeout(v),clearTimeout(g),cancelAnimationFrame(h)},setProps:function(e){if($.state.isDestroyed)return;ae("onBeforeUpdate",[$,e]),be();var t=$.props,n=j(o,Object.assign({},t,l(e),{ignoreAttributes:!0}));$.props=n,he(),t.interactiveDebounce!==n.interactiveDebounce&&(ce(),W=a(we,n.interactiveDebounce));t.triggerTarget&&!n.triggerTarget?u(t.triggerTarget).forEach((function(e){e.removeAttribute("aria-expanded")})):n.triggerTarget&&o.removeAttribute("aria-expanded");ue(),ie(),J&&J(t,n);$.popperInstance&&(Ce(),Ae().forEach((function(e){requestAnimationFrame(e._tippy.popperInstance.forceUpdate)})));ae("onAfterUpdate",[$,e])},setContent:function(e){$.setProps({content:e})},show:function(){var e=$.state.isVisible,t=$.state.isDestroyed,o=!$.state.isEnabled,a=x.isTouch&&!$.props.touch,s=r($.props.duration,0,R.duration);if(e||t||o||a)return;if(te().hasAttribute("disabled"))return;if(ae("onShow",[$],!1),!1===$.props.onShow($))return;$.state.isVisible=!0,ee()&&(z.style.visibility="visible");ie(),de(),$.state.isMounted||(z.style.transition="none");if(ee()){var u=re(),p=u.box,f=u.content;b([p,f],0)}A=function(){var e;if($.state.isVisible&&!_){if(_=!0,z.offsetHeight,z.style.transition=$.props.moveTransition,ee()&&$.props.animation){var t=re(),n=t.box,r=t.content;b([n,r],s),y([n,r],"visible")}se(),ue(),c(U,$),null==(e=$.popperInstance)||e.forceUpdate(),ae("onMount",[$]),$.props.animation&&ee()&&function(e,t){me(e,t)}(s,(function(){$.state.isShown=!0,ae("onShown",[$])}))}},function(){var e,t=$.props.appendTo,r=te();e=$.props.interactive&&t===n||"parent"===t?r.parentNode:i(t,[r]);e.contains(z)||e.appendChild(z);$.state.isMounted=!0,Ce()}()},hide:function(){var e=!$.state.isVisible,t=$.state.isDestroyed,n=!$.state.isEnabled,o=r($.props.duration,1,R.duration);if(e||t||n)return;if(ae("onHide",[$],!1),!1===$.props.onHide($))return;$.state.isVisible=!1,$.state.isShown=!1,_=!1,V=!1,ee()&&(z.style.visibility="hidden");if(ce(),ve(),ie(!0),ee()){var i=re(),a=i.box,s=i.content;$.props.animation&&(b([a,s],o),y([a,s],"hidden"))}se(),ue(),$.props.animation?ee()&&function(e,t){me(e,(function(){!$.state.isVisible&&z.parentNode&&z.parentNode.contains(z)&&t()}))}(o,$.unmount):$.unmount()},hideWithInteractivity:function(e){ne().addEventListener("mousemove",W),c(H,W),W(e)},enable:function(){$.state.isEnabled=!0},disable:function(){$.hide(),$.state.isEnabled=!1},unmount:function(){$.state.isVisible&&$.hide();if(!$.state.isMounted)return;Te(),Ae().forEach((function(e){e._tippy.unmount()})),z.parentNode&&z.parentNode.removeChild(z);U=U.filter((function(e){return e!==$})),$.state.isMounted=!1,ae("onHidden",[$])},destroy:function(){if($.state.isDestroyed)return;$.clearDelayTimeouts(),$.unmount(),be(),delete o._tippy,$.state.isDestroyed=!0,ae("onDestroy",[$])}};if(!M.render)return $;var q=M.render($),z=q.popper,J=q.onUpdate;z.setAttribute("data-tippy-root",""),z.id="tippy-"+$.id,$.popper=z,o._tippy=$,z._tippy=$;var G=Y.map((function(e){return e.fn($)})),K=o.hasAttribute("aria-expanded");return he(),ue(),ie(),ae("onCreate",[$]),M.showOnCreate&&Le(),z.addEventListener("mouseenter",(function(){$.props.interactive&&$.state.isVisible&&$.clearDelayTimeouts()})),z.addEventListener("mouseleave",(function(){$.props.interactive&&$.props.trigger.indexOf("mouseenter")>=0&&ne().addEventListener("mousemove",W)})),$;function Q(){var e=$.props.touch;return Array.isArray(e)?e:[e,0]}function Z(){return"hold"===Q()[0]}function ee(){var e;return!(null==(e=$.props.render)||!e.$$tippy)}function te(){return L||o}function ne(){var e=te().parentNode;return e?w(e):document}function re(){return S(z)}function oe(e){return $.state.isMounted&&!$.state.isVisible||x.isTouch||C&&"focus"===C.type?0:r($.props.delay,e?0:1,R.delay)}function ie(e){void 0===e&&(e=!1),z.style.pointerEvents=$.props.interactive&&!e?"":"none",z.style.zIndex=""+$.props.zIndex}function ae(e,t,n){var r;(void 0===n&&(n=!0),G.forEach((function(n){n[e]&&n[e].apply(n,t)})),n)&&(r=$.props)[e].apply(r,t)}function se(){var e=$.props.aria;if(e.content){var t="aria-"+e.content,n=z.id;u($.props.triggerTarget||o).forEach((function(e){var r=e.getAttribute(t);if($.state.isVisible)e.setAttribute(t,r?r+" "+n:n);else{var o=r&&r.replace(n,"").trim();o?e.setAttribute(t,o):e.removeAttribute(t)}}))}}function ue(){!K&&$.props.aria.expanded&&u($.props.triggerTarget||o).forEach((function(e){$.props.interactive?e.setAttribute("aria-expanded",$.state.isVisible&&e===te()?"true":"false"):e.removeAttribute("aria-expanded")}))}function ce(){ne().removeEventListener("mousemove",W),H=H.filter((function(e){return e!==W}))}function pe(e){if(!x.isTouch||!N&&"mousedown"!==e.type){var t=e.composedPath&&e.composedPath()[0]||e.target;if(!$.props.interactive||!O(z,t)){if(u($.props.triggerTarget||o).some((function(e){return O(e,t)}))){if(x.isTouch)return;if($.state.isVisible&&$.props.trigger.indexOf("click")>=0)return}else ae("onClickOutside",[$,e]);!0===$.props.hideOnClick&&($.clearDelayTimeouts(),$.hide(),I=!0,setTimeout((function(){I=!1})),$.state.isMounted||ve())}}}function fe(){N=!0}function le(){N=!1}function de(){var e=ne();e.addEventListener("mousedown",pe,!0),e.addEventListener("touchend",pe,t),e.addEventListener("touchstart",le,t),e.addEventListener("touchmove",fe,t)}function ve(){var e=ne();e.removeEventListener("mousedown",pe,!0),e.removeEventListener("touchend",pe,t),e.removeEventListener("touchstart",le,t),e.removeEventListener("touchmove",fe,t)}function me(e,t){var n=re().box;function r(e){e.target===n&&(E(n,"remove",r),t())}if(0===e)return t();E(n,"remove",T),E(n,"add",r),T=r}function ge(e,t,n){void 0===n&&(n=!1),u($.props.triggerTarget||o).forEach((function(r){r.addEventListener(e,t,n),F.push({node:r,eventType:e,handler:t,options:n})}))}function he(){var e;Z()&&(ge("touchstart",ye,{passive:!0}),ge("touchend",Ee,{passive:!0})),(e=$.props.trigger,e.split(/\s+/).filter(Boolean)).forEach((function(e){if("manual"!==e)switch(ge(e,ye),e){case"mouseenter":ge("mouseleave",Ee);break;case"focus":ge(D?"focusout":"blur",Oe);break;case"focusin":ge("focusout",Oe)}}))}function be(){F.forEach((function(e){var t=e.node,n=e.eventType,r=e.handler,o=e.options;t.removeEventListener(n,r,o)})),F=[]}function ye(e){var t,n=!1;if($.state.isEnabled&&!xe(e)&&!I){var r="focus"===(null==(t=C)?void 0:t.type);C=e,L=e.currentTarget,ue(),!$.state.isVisible&&m(e)&&H.forEach((function(t){return t(e)})),"click"===e.type&&($.props.trigger.indexOf("mouseenter")<0||V)&&!1!==$.props.hideOnClick&&$.state.isVisible?n=!0:Le(e),"click"===e.type&&(V=!n),n&&!r&&De(e)}}function we(e){var t=e.target,n=te().contains(t)||z.contains(t);"mousemove"===e.type&&n||function(e,t){var n=t.clientX,r=t.clientY;return e.every((function(e){var t=e.popperRect,o=e.popperState,i=e.props.interactiveBorder,a=p(o.placement),s=o.modifiersData.offset;if(!s)return!0;var u="bottom"===a?s.top.y:0,c="top"===a?s.bottom.y:0,f="right"===a?s.left.x:0,l="left"===a?s.right.x:0,d=t.top-r+u>i,v=r-t.bottom-c>i,m=t.left-n+f>i,g=n-t.right-l>i;return d||v||m||g}))}(Ae().concat(z).map((function(e){var t,n=null==(t=e._tippy.popperInstance)?void 0:t.state;return n?{popperRect:e.getBoundingClientRect(),popperState:n,props:M}:null})).filter(Boolean),e)&&(ce(),De(e))}function Ee(e){xe(e)||$.props.trigger.indexOf("click")>=0&&V||($.props.interactive?$.hideWithInteractivity(e):De(e))}function Oe(e){$.props.trigger.indexOf("focusin")<0&&e.target!==te()||$.props.interactive&&e.relatedTarget&&z.contains(e.relatedTarget)||De(e)}function xe(e){return!!x.isTouch&&Z()!==e.type.indexOf("touch")>=0}function Ce(){Te();var t=$.props,n=t.popperOptions,r=t.placement,i=t.offset,a=t.getReferenceClientRect,s=t.moveTransition,u=ee()?S(z).arrow:null,c=a?{getBoundingClientRect:a,contextElement:a.contextElement||te()}:o,p=[{name:"offset",options:{offset:i}},{name:"preventOverflow",options:{padding:{top:2,bottom:2,left:5,right:5}}},{name:"flip",options:{padding:5}},{name:"computeStyles",options:{adaptive:!s}},{name:"$$tippy",enabled:!0,phase:"beforeWrite",requires:["computeStyles"],fn:function(e){var t=e.state;if(ee()){var n=re().box;["placement","reference-hidden","escaped"].forEach((function(e){"placement"===e?n.setAttribute("data-placement",t.placement):t.attributes.popper["data-popper-"+e]?n.setAttribute("data-"+e,""):n.removeAttribute("data-"+e)})),t.attributes.popper={}}}}];ee()&&u&&p.push({name:"arrow",options:{element:u,padding:3}}),p.push.apply(p,(null==n?void 0:n.modifiers)||[]),$.popperInstance=e.createPopper(c,z,Object.assign({},n,{placement:r,onFirstUpdate:A,modifiers:p}))}function Te(){$.popperInstance&&($.popperInstance.destroy(),$.popperInstance=null)}function Ae(){return f(z.querySelectorAll("[data-tippy-root]"))}function Le(e){$.clearDelayTimeouts(),e&&ae("onTrigger",[$,e]),de();var t=oe(!0),n=Q(),r=n[0],o=n[1];x.isTouch&&"hold"===r&&o&&(t=o),t?v=setTimeout((function(){$.show()}),t):$.show()}function De(e){if($.clearDelayTimeouts(),ae("onUntrigger",[$,e]),$.state.isVisible){if(!($.props.trigger.indexOf("mouseenter")>=0&&$.props.trigger.indexOf("click")>=0&&["mouseleave","mousemove"].indexOf(e.type)>=0&&V)){var t=oe(!1);t?g=setTimeout((function(){$.state.isVisible&&$.hide()}),t):h=requestAnimationFrame((function(){$.hide()}))}}else ve()}}function F(e,n){void 0===n&&(n={});var r=R.plugins.concat(n.plugins||[]);document.addEventListener("touchstart",T,t),window.addEventListener("blur",L);var o=Object.assign({},n,{plugins:r}),i=h(e).reduce((function(e,t){var n=t&&_(t,o);return n&&e.push(n),e}),[]);return v(e)?i[0]:i}F.defaultProps=R,F.setDefaultProps=function(e){Object.keys(e).forEach((function(t){R[t]=e[t]}))},F.currentInput=x;var W=Object.assign({},e.applyStyles,{effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow)}}),X={mouseover:"mouseenter",focusin:"focus",click:"click"};var Y={name:"animateFill",defaultValue:!1,fn:function(e){var t;if(null==(t=e.props.render)||!t.$$tippy)return{};var n=S(e.popper),r=n.box,o=n.content,i=e.props.animateFill?function(){var e=d();return e.className="tippy-backdrop",y([e],"hidden"),e}():null;return{onCreate:function(){i&&(r.insertBefore(i,r.firstElementChild),r.setAttribute("data-animatefill",""),r.style.overflow="hidden",e.setProps({arrow:!1,animation:"shift-away"}))},onMount:function(){if(i){var e=r.style.transitionDuration,t=Number(e.replace("ms",""));o.style.transitionDelay=Math.round(t/10)+"ms",i.style.transitionDuration=e,y([i],"visible")}},onShow:function(){i&&(i.style.transitionDuration="0ms")},onHide:function(){i&&y([i],"hidden")}}}};var $={clientX:0,clientY:0},q=[];function z(e){var t=e.clientX,n=e.clientY;$={clientX:t,clientY:n}}var J={name:"followCursor",defaultValue:!1,fn:function(e){var t=e.reference,n=w(e.props.triggerTarget||t),r=!1,o=!1,i=!0,a=e.props;function s(){return"initial"===e.props.followCursor&&e.state.isVisible}function u(){n.addEventListener("mousemove",f)}function c(){n.removeEventListener("mousemove",f)}function p(){r=!0,e.setProps({getReferenceClientRect:null}),r=!1}function f(n){var r=!n.target||t.contains(n.target),o=e.props.followCursor,i=n.clientX,a=n.clientY,s=t.getBoundingClientRect(),u=i-s.left,c=a-s.top;!r&&e.props.interactive||e.setProps({getReferenceClientRect:function(){var e=t.getBoundingClientRect(),n=i,r=a;"initial"===o&&(n=e.left+u,r=e.top+c);var s="horizontal"===o?e.top:r,p="vertical"===o?e.right:n,f="horizontal"===o?e.bottom:r,l="vertical"===o?e.left:n;return{width:p-l,height:f-s,top:s,right:p,bottom:f,left:l}}})}function l(){e.props.followCursor&&(q.push({instance:e,doc:n}),function(e){e.addEventListener("mousemove",z)}(n))}function d(){0===(q=q.filter((function(t){return t.instance!==e}))).filter((function(e){return e.doc===n})).length&&function(e){e.removeEventListener("mousemove",z)}(n)}return{onCreate:l,onDestroy:d,onBeforeUpdate:function(){a=e.props},onAfterUpdate:function(t,n){var i=n.followCursor;r||void 0!==i&&a.followCursor!==i&&(d(),i?(l(),!e.state.isMounted||o||s()||u()):(c(),p()))},onMount:function(){e.props.followCursor&&!o&&(i&&(f($),i=!1),s()||u())},onTrigger:function(e,t){m(t)&&($={clientX:t.clientX,clientY:t.clientY}),o="focus"===t.type},onHidden:function(){e.props.followCursor&&(p(),c(),i=!0)}}}};var G={name:"inlinePositioning",defaultValue:!1,fn:function(e){var t,n=e.reference;var r=-1,o=!1,i=[],a={name:"tippyInlinePositioning",enabled:!0,phase:"afterWrite",fn:function(o){var a=o.state;e.props.inlinePositioning&&(-1!==i.indexOf(a.placement)&&(i=[]),t!==a.placement&&-1===i.indexOf(a.placement)&&(i.push(a.placement),e.setProps({getReferenceClientRect:function(){return function(e){return function(e,t,n,r){if(n.length<2||null===e)return t;if(2===n.length&&r>=0&&n[0].left>n[1].right)return n[r]||t;switch(e){case"top":case"bottom":var o=n[0],i=n[n.length-1],a="top"===e,s=o.top,u=i.bottom,c=a?o.left:i.left,p=a?o.right:i.right;return{top:s,bottom:u,left:c,right:p,width:p-c,height:u-s};case"left":case"right":var f=Math.min.apply(Math,n.map((function(e){return e.left}))),l=Math.max.apply(Math,n.map((function(e){return e.right}))),d=n.filter((function(t){return"left"===e?t.left===f:t.right===l})),v=d[0].top,m=d[d.length-1].bottom;return{top:v,bottom:m,left:f,right:l,width:l-f,height:m-v};default:return t}}(p(e),n.getBoundingClientRect(),f(n.getClientRects()),r)}(a.placement)}})),t=a.placement)}};function s(){var t;o||(t=function(e,t){var n;return{popperOptions:Object.assign({},e.popperOptions,{modifiers:[].concat(((null==(n=e.popperOptions)?void 0:n.modifiers)||[]).filter((function(e){return e.name!==t.name})),[t])})}}(e.props,a),o=!0,e.setProps(t),o=!1)}return{onCreate:s,onAfterUpdate:s,onTrigger:function(t,n){if(m(n)){var o=f(e.reference.getClientRects()),i=o.find((function(e){return e.left-2<=n.clientX&&e.right+2>=n.clientX&&e.top-2<=n.clientY&&e.bottom+2>=n.clientY})),a=o.indexOf(i);r=a>-1?a:r}},onHidden:function(){r=-1}}}};var K={name:"sticky",defaultValue:!1,fn:function(e){var t=e.reference,n=e.popper;function r(t){return!0===e.props.sticky||e.props.sticky===t}var o=null,i=null;function a(){var s=r("reference")?(e.popperInstance?e.popperInstance.state.elements.reference:t).getBoundingClientRect():null,u=r("popper")?n.getBoundingClientRect():null;(s&&Q(o,s)||u&&Q(i,u))&&e.popperInstance&&e.popperInstance.update(),o=s,i=u,e.state.isMounted&&requestAnimationFrame(a)}return{onMount:function(){e.props.sticky&&a()}}}};function Q(e,t){return!e||!t||(e.top!==t.top||e.right!==t.right||e.bottom!==t.bottom||e.left!==t.left)}return F.setDefaultProps({plugins:[Y,J,G,K],render:N}),F.createSingleton=function(e,t){var n;void 0===t&&(t={});var r,o=e,i=[],a=[],c=t.overrides,p=[],f=!1;function l(){a=o.map((function(e){return u(e.props.triggerTarget||e.reference)})).reduce((function(e,t){return e.concat(t)}),[])}function v(){i=o.map((function(e){return e.reference}))}function m(e){o.forEach((function(t){e?t.enable():t.disable()}))}function g(e){return o.map((function(t){var n=t.setProps;return t.setProps=function(o){n(o),t.reference===r&&e.setProps(o)},function(){t.setProps=n}}))}function h(e,t){var n=a.indexOf(t);if(t!==r){r=t;var s=(c||[]).concat("content").reduce((function(e,t){return e[t]=o[n].props[t],e}),{});e.setProps(Object.assign({},s,{getReferenceClientRect:"function"==typeof s.getReferenceClientRect?s.getReferenceClientRect:function(){var e;return null==(e=i[n])?void 0:e.getBoundingClientRect()}}))}}m(!1),v(),l();var b={fn:function(){return{onDestroy:function(){m(!0)},onHidden:function(){r=null},onClickOutside:function(e){e.props.showOnCreate&&!f&&(f=!0,r=null)},onShow:function(e){e.props.showOnCreate&&!f&&(f=!0,h(e,i[0]))},onTrigger:function(e,t){h(e,t.currentTarget)}}}},y=F(d(),Object.assign({},s(t,["overrides"]),{plugins:[b].concat(t.plugins||[]),triggerTarget:a,popperOptions:Object.assign({},t.popperOptions,{modifiers:[].concat((null==(n=t.popperOptions)?void 0:n.modifiers)||[],[W])})})),w=y.show;y.show=function(e){if(w(),!r&&null==e)return h(y,i[0]);if(!r||null!=e){if("number"==typeof e)return i[e]&&h(y,i[e]);if(o.indexOf(e)>=0){var t=e.reference;return h(y,t)}return i.indexOf(e)>=0?h(y,e):void 0}},y.showNext=function(){var e=i[0];if(!r)return y.show(0);var t=i.indexOf(r);y.show(i[t+1]||e)},y.showPrevious=function(){var e=i[i.length-1];if(!r)return y.show(e);var t=i.indexOf(r),n=i[t-1]||e;y.show(n)};var E=y.setProps;return y.setProps=function(e){c=e.overrides||c,E(e)},y.setInstances=function(e){m(!0),p.forEach((function(e){return e()})),o=e,m(!1),v(),l(),p=g(y),y.setProps({triggerTarget:a})},p=g(y),y},F.delegate=function(e,n){var r=[],o=[],i=!1,a=n.target,c=s(n,["target"]),p=Object.assign({},c,{trigger:"manual",touch:!1}),f=Object.assign({touch:R.touch},c,{showOnCreate:!0}),l=F(e,p);function d(e){if(e.target&&!i){var t=e.target.closest(a);if(t){var r=t.getAttribute("data-tippy-trigger")||n.trigger||R.trigger;if(!t._tippy&&!("touchstart"===e.type&&"boolean"==typeof f.touch||"touchstart"!==e.type&&r.indexOf(X[e.type])<0)){var s=F(t,f);s&&(o=o.concat(s))}}}}function v(e,t,n,o){void 0===o&&(o=!1),e.addEventListener(t,n,o),r.push({node:e,eventType:t,handler:n,options:o})}return u(l).forEach((function(e){var n=e.destroy,a=e.enable,s=e.disable;e.destroy=function(e){void 0===e&&(e=!0),e&&o.forEach((function(e){e.destroy()})),o=[],r.forEach((function(e){var t=e.node,n=e.eventType,r=e.handler,o=e.options;t.removeEventListener(n,r,o)})),r=[],n()},e.enable=function(){a(),o.forEach((function(e){return e.enable()})),i=!1},e.disable=function(){s(),o.forEach((function(e){return e.disable()})),i=!0},function(e){var n=e.reference;v(n,"touchstart",d,t),v(n,"mouseover",d),v(n,"focusin",d),v(n,"click",d)}(e)})),l},F.hideAll=function(e){var t=void 0===e?{}:e,n=t.exclude,r=t.duration;U.forEach((function(e){var t=!1;if(n&&(t=g(n)?e.reference===n:e.popper===n.popper),!t){var o=e.props.duration;e.setProps({duration:r}),e.hide(),e.state.isDestroyed||e.setProps({duration:o})}}))},F.roundArrow=' ',F}));
+
diff --git a/3 Cognitive change/project-presentation_files/libs/revealjs/dist/reset.css b/3 Cognitive change/project-presentation_files/libs/revealjs/dist/reset.css
new file mode 100644
index 0000000..e238539
--- /dev/null
+++ b/3 Cognitive change/project-presentation_files/libs/revealjs/dist/reset.css
@@ -0,0 +1,30 @@
+/* http://meyerweb.com/eric/tools/css/reset/
+ v4.0 | 20180602
+ License: none (public domain)
+*/
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+main, menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure,
+footer, header, hgroup, main, menu, nav, section {
+ display: block;
+}
\ No newline at end of file
diff --git a/3 Cognitive change/project-presentation_files/libs/revealjs/dist/reveal.css b/3 Cognitive change/project-presentation_files/libs/revealjs/dist/reveal.css
new file mode 100644
index 0000000..5f80fd0
--- /dev/null
+++ b/3 Cognitive change/project-presentation_files/libs/revealjs/dist/reveal.css
@@ -0,0 +1,8 @@
+/*!
+* reveal.js 4.3.1
+* https://revealjs.com
+* MIT licensed
+*
+* Copyright (C) 2011-2022 Hakim El Hattab, https://hakim.se
+*/
+.reveal .r-stretch,.reveal .stretch{max-width:none;max-height:none}.reveal pre.r-stretch code,.reveal pre.stretch code{height:100%;max-height:100%;box-sizing:border-box}.reveal .r-fit-text{display:inline-block;white-space:nowrap}.reveal .r-stack{display:grid}.reveal .r-stack>*{grid-area:1/1;margin:auto}.reveal .r-hstack,.reveal .r-vstack{display:flex}.reveal .r-hstack img,.reveal .r-hstack video,.reveal .r-vstack img,.reveal .r-vstack video{min-width:0;min-height:0;-o-object-fit:contain;object-fit:contain}.reveal .r-vstack{flex-direction:column;align-items:center;justify-content:center}.reveal .r-hstack{flex-direction:row;align-items:center;justify-content:center}.reveal .items-stretch{align-items:stretch}.reveal .items-start{align-items:flex-start}.reveal .items-center{align-items:center}.reveal .items-end{align-items:flex-end}.reveal .justify-between{justify-content:space-between}.reveal .justify-around{justify-content:space-around}.reveal .justify-start{justify-content:flex-start}.reveal .justify-center{justify-content:center}.reveal .justify-end{justify-content:flex-end}html.reveal-full-page{width:100%;height:100%;height:100vh;height:calc(var(--vh,1vh) * 100);overflow:hidden}.reveal-viewport{height:100%;overflow:hidden;position:relative;line-height:1;margin:0;background-color:#fff;color:#000}.reveal-viewport:-webkit-full-screen{top:0!important;left:0!important;width:100%!important;height:100%!important;transform:none!important}.reveal-viewport:-ms-fullscreen{top:0!important;left:0!important;width:100%!important;height:100%!important;transform:none!important}.reveal-viewport:fullscreen{top:0!important;left:0!important;width:100%!important;height:100%!important;transform:none!important}.reveal .slides section .fragment{opacity:0;visibility:hidden;transition:all .2s ease;will-change:opacity}.reveal .slides section .fragment.visible{opacity:1;visibility:inherit}.reveal .slides section .fragment.disabled{transition:none}.reveal .slides section .fragment.grow{opacity:1;visibility:inherit}.reveal .slides section .fragment.grow.visible{transform:scale(1.3)}.reveal .slides section .fragment.shrink{opacity:1;visibility:inherit}.reveal .slides section .fragment.shrink.visible{transform:scale(.7)}.reveal .slides section .fragment.zoom-in{transform:scale(.1)}.reveal .slides section .fragment.zoom-in.visible{transform:none}.reveal .slides section .fragment.fade-out{opacity:1;visibility:inherit}.reveal .slides section .fragment.fade-out.visible{opacity:0;visibility:hidden}.reveal .slides section .fragment.semi-fade-out{opacity:1;visibility:inherit}.reveal .slides section .fragment.semi-fade-out.visible{opacity:.5;visibility:inherit}.reveal .slides section .fragment.strike{opacity:1;visibility:inherit}.reveal .slides section .fragment.strike.visible{text-decoration:line-through}.reveal .slides section .fragment.fade-up{transform:translate(0,40px)}.reveal .slides section .fragment.fade-up.visible{transform:translate(0,0)}.reveal .slides section .fragment.fade-down{transform:translate(0,-40px)}.reveal .slides section .fragment.fade-down.visible{transform:translate(0,0)}.reveal .slides section .fragment.fade-right{transform:translate(-40px,0)}.reveal .slides section .fragment.fade-right.visible{transform:translate(0,0)}.reveal .slides section .fragment.fade-left{transform:translate(40px,0)}.reveal .slides section .fragment.fade-left.visible{transform:translate(0,0)}.reveal .slides section .fragment.current-visible,.reveal .slides section .fragment.fade-in-then-out{opacity:0;visibility:hidden}.reveal .slides section .fragment.current-visible.current-fragment,.reveal .slides section .fragment.fade-in-then-out.current-fragment{opacity:1;visibility:inherit}.reveal .slides section .fragment.fade-in-then-semi-out{opacity:0;visibility:hidden}.reveal .slides section .fragment.fade-in-then-semi-out.visible{opacity:.5;visibility:inherit}.reveal .slides section .fragment.fade-in-then-semi-out.current-fragment{opacity:1;visibility:inherit}.reveal .slides section .fragment.highlight-blue,.reveal .slides section .fragment.highlight-current-blue,.reveal .slides section .fragment.highlight-current-green,.reveal .slides section .fragment.highlight-current-red,.reveal .slides section .fragment.highlight-green,.reveal .slides section .fragment.highlight-red{opacity:1;visibility:inherit}.reveal .slides section .fragment.highlight-red.visible{color:#ff2c2d}.reveal .slides section .fragment.highlight-green.visible{color:#17ff2e}.reveal .slides section .fragment.highlight-blue.visible{color:#1b91ff}.reveal .slides section .fragment.highlight-current-red.current-fragment{color:#ff2c2d}.reveal .slides section .fragment.highlight-current-green.current-fragment{color:#17ff2e}.reveal .slides section .fragment.highlight-current-blue.current-fragment{color:#1b91ff}.reveal:after{content:"";font-style:italic}.reveal iframe{z-index:1}.reveal a{position:relative}@keyframes bounce-right{0%,10%,25%,40%,50%{transform:translateX(0)}20%{transform:translateX(10px)}30%{transform:translateX(-5px)}}@keyframes bounce-left{0%,10%,25%,40%,50%{transform:translateX(0)}20%{transform:translateX(-10px)}30%{transform:translateX(5px)}}@keyframes bounce-down{0%,10%,25%,40%,50%{transform:translateY(0)}20%{transform:translateY(10px)}30%{transform:translateY(-5px)}}.reveal .controls{display:none;position:absolute;top:auto;bottom:12px;right:12px;left:auto;z-index:11;color:#000;pointer-events:none;font-size:10px}.reveal .controls button{position:absolute;padding:0;background-color:transparent;border:0;outline:0;cursor:pointer;color:currentColor;transform:scale(.9999);transition:color .2s ease,opacity .2s ease,transform .2s ease;z-index:2;pointer-events:auto;font-size:inherit;visibility:hidden;opacity:0;-webkit-appearance:none;-webkit-tap-highlight-color:transparent}.reveal .controls .controls-arrow:after,.reveal .controls .controls-arrow:before{content:"";position:absolute;top:0;left:0;width:2.6em;height:.5em;border-radius:.25em;background-color:currentColor;transition:all .15s ease,background-color .8s ease;transform-origin:.2em 50%;will-change:transform}.reveal .controls .controls-arrow{position:relative;width:3.6em;height:3.6em}.reveal .controls .controls-arrow:before{transform:translateX(.5em) translateY(1.55em) rotate(45deg)}.reveal .controls .controls-arrow:after{transform:translateX(.5em) translateY(1.55em) rotate(-45deg)}.reveal .controls .controls-arrow:hover:before{transform:translateX(.5em) translateY(1.55em) rotate(40deg)}.reveal .controls .controls-arrow:hover:after{transform:translateX(.5em) translateY(1.55em) rotate(-40deg)}.reveal .controls .controls-arrow:active:before{transform:translateX(.5em) translateY(1.55em) rotate(36deg)}.reveal .controls .controls-arrow:active:after{transform:translateX(.5em) translateY(1.55em) rotate(-36deg)}.reveal .controls .navigate-left{right:6.4em;bottom:3.2em;transform:translateX(-10px)}.reveal .controls .navigate-left.highlight{animation:bounce-left 2s 50 both ease-out}.reveal .controls .navigate-right{right:0;bottom:3.2em;transform:translateX(10px)}.reveal .controls .navigate-right .controls-arrow{transform:rotate(180deg)}.reveal .controls .navigate-right.highlight{animation:bounce-right 2s 50 both ease-out}.reveal .controls .navigate-up{right:3.2em;bottom:6.4em;transform:translateY(-10px)}.reveal .controls .navigate-up .controls-arrow{transform:rotate(90deg)}.reveal .controls .navigate-down{right:3.2em;bottom:-1.4em;padding-bottom:1.4em;transform:translateY(10px)}.reveal .controls .navigate-down .controls-arrow{transform:rotate(-90deg)}.reveal .controls .navigate-down.highlight{animation:bounce-down 2s 50 both ease-out}.reveal .controls[data-controls-back-arrows=faded] .navigate-up.enabled{opacity:.3}.reveal .controls[data-controls-back-arrows=faded] .navigate-up.enabled:hover{opacity:1}.reveal .controls[data-controls-back-arrows=hidden] .navigate-up.enabled{opacity:0;visibility:hidden}.reveal .controls .enabled{visibility:visible;opacity:.9;cursor:pointer;transform:none}.reveal .controls .enabled.fragmented{opacity:.5}.reveal .controls .enabled.fragmented:hover,.reveal .controls .enabled:hover{opacity:1}.reveal:not(.rtl) .controls[data-controls-back-arrows=faded] .navigate-left.enabled{opacity:.3}.reveal:not(.rtl) .controls[data-controls-back-arrows=faded] .navigate-left.enabled:hover{opacity:1}.reveal:not(.rtl) .controls[data-controls-back-arrows=hidden] .navigate-left.enabled{opacity:0;visibility:hidden}.reveal.rtl .controls[data-controls-back-arrows=faded] .navigate-right.enabled{opacity:.3}.reveal.rtl .controls[data-controls-back-arrows=faded] .navigate-right.enabled:hover{opacity:1}.reveal.rtl .controls[data-controls-back-arrows=hidden] .navigate-right.enabled{opacity:0;visibility:hidden}.reveal[data-navigation-mode=linear].has-horizontal-slides .navigate-down,.reveal[data-navigation-mode=linear].has-horizontal-slides .navigate-up{display:none}.reveal:not(.has-vertical-slides) .controls .navigate-left,.reveal[data-navigation-mode=linear].has-horizontal-slides .navigate-left{bottom:1.4em;right:5.5em}.reveal:not(.has-vertical-slides) .controls .navigate-right,.reveal[data-navigation-mode=linear].has-horizontal-slides .navigate-right{bottom:1.4em;right:.5em}.reveal:not(.has-horizontal-slides) .controls .navigate-up{right:1.4em;bottom:5em}.reveal:not(.has-horizontal-slides) .controls .navigate-down{right:1.4em;bottom:.5em}.reveal.has-dark-background .controls{color:#fff}.reveal.has-light-background .controls{color:#000}.reveal.no-hover .controls .controls-arrow:active:before,.reveal.no-hover .controls .controls-arrow:hover:before{transform:translateX(.5em) translateY(1.55em) rotate(45deg)}.reveal.no-hover .controls .controls-arrow:active:after,.reveal.no-hover .controls .controls-arrow:hover:after{transform:translateX(.5em) translateY(1.55em) rotate(-45deg)}@media screen and (min-width:500px){.reveal .controls[data-controls-layout=edges]{top:0;right:0;bottom:0;left:0}.reveal .controls[data-controls-layout=edges] .navigate-down,.reveal .controls[data-controls-layout=edges] .navigate-left,.reveal .controls[data-controls-layout=edges] .navigate-right,.reveal .controls[data-controls-layout=edges] .navigate-up{bottom:auto;right:auto}.reveal .controls[data-controls-layout=edges] .navigate-left{top:50%;left:.8em;margin-top:-1.8em}.reveal .controls[data-controls-layout=edges] .navigate-right{top:50%;right:.8em;margin-top:-1.8em}.reveal .controls[data-controls-layout=edges] .navigate-up{top:.8em;left:50%;margin-left:-1.8em}.reveal .controls[data-controls-layout=edges] .navigate-down{bottom:-.3em;left:50%;margin-left:-1.8em}}.reveal .progress{position:absolute;display:none;height:3px;width:100%;bottom:0;left:0;z-index:10;background-color:rgba(0,0,0,.2);color:#fff}.reveal .progress:after{content:"";display:block;position:absolute;height:10px;width:100%;top:-10px}.reveal .progress span{display:block;height:100%;width:100%;background-color:currentColor;transition:transform .8s cubic-bezier(.26,.86,.44,.985);transform-origin:0 0;transform:scaleX(0)}.reveal .slide-number{position:absolute;display:block;right:8px;bottom:8px;z-index:31;font-family:Helvetica,sans-serif;font-size:12px;line-height:1;color:#fff;background-color:rgba(0,0,0,.4);padding:5px}.reveal .slide-number a{color:currentColor}.reveal .slide-number-delimiter{margin:0 3px}.reveal{position:relative;width:100%;height:100%;overflow:hidden;touch-action:pinch-zoom}.reveal.embedded{touch-action:pan-y}.reveal .slides{position:absolute;width:100%;height:100%;top:0;right:0;bottom:0;left:0;margin:auto;pointer-events:none;overflow:visible;z-index:1;text-align:center;perspective:600px;perspective-origin:50% 40%}.reveal .slides>section{perspective:600px}.reveal .slides>section,.reveal .slides>section>section{display:none;position:absolute;width:100%;pointer-events:auto;z-index:10;transform-style:flat;transition:transform-origin .8s cubic-bezier(.26,.86,.44,.985),transform .8s cubic-bezier(.26,.86,.44,.985),visibility .8s cubic-bezier(.26,.86,.44,.985),opacity .8s cubic-bezier(.26,.86,.44,.985)}.reveal[data-transition-speed=fast] .slides section{transition-duration:.4s}.reveal[data-transition-speed=slow] .slides section{transition-duration:1.2s}.reveal .slides section[data-transition-speed=fast]{transition-duration:.4s}.reveal .slides section[data-transition-speed=slow]{transition-duration:1.2s}.reveal .slides>section.stack{padding-top:0;padding-bottom:0;pointer-events:none;height:100%}.reveal .slides>section.present,.reveal .slides>section>section.present{display:block;z-index:11;opacity:1}.reveal .slides>section:empty,.reveal .slides>section>section:empty,.reveal .slides>section>section[data-background-interactive],.reveal .slides>section[data-background-interactive]{pointer-events:none}.reveal.center,.reveal.center .slides,.reveal.center .slides section{min-height:0!important}.reveal .slides>section:not(.present),.reveal .slides>section>section:not(.present){pointer-events:none}.reveal.overview .slides>section,.reveal.overview .slides>section>section{pointer-events:auto}.reveal .slides>section.future,.reveal .slides>section.past,.reveal .slides>section>section.future,.reveal .slides>section>section.past{opacity:0}.reveal .slides>section[data-transition=slide].past,.reveal .slides>section[data-transition~=slide-out].past,.reveal.slide .slides>section:not([data-transition]).past{transform:translate(-150%,0)}.reveal .slides>section[data-transition=slide].future,.reveal .slides>section[data-transition~=slide-in].future,.reveal.slide .slides>section:not([data-transition]).future{transform:translate(150%,0)}.reveal .slides>section>section[data-transition=slide].past,.reveal .slides>section>section[data-transition~=slide-out].past,.reveal.slide .slides>section>section:not([data-transition]).past{transform:translate(0,-150%)}.reveal .slides>section>section[data-transition=slide].future,.reveal .slides>section>section[data-transition~=slide-in].future,.reveal.slide .slides>section>section:not([data-transition]).future{transform:translate(0,150%)}.reveal .slides>section[data-transition=linear].past,.reveal .slides>section[data-transition~=linear-out].past,.reveal.linear .slides>section:not([data-transition]).past{transform:translate(-150%,0)}.reveal .slides>section[data-transition=linear].future,.reveal .slides>section[data-transition~=linear-in].future,.reveal.linear .slides>section:not([data-transition]).future{transform:translate(150%,0)}.reveal .slides>section>section[data-transition=linear].past,.reveal .slides>section>section[data-transition~=linear-out].past,.reveal.linear .slides>section>section:not([data-transition]).past{transform:translate(0,-150%)}.reveal .slides>section>section[data-transition=linear].future,.reveal .slides>section>section[data-transition~=linear-in].future,.reveal.linear .slides>section>section:not([data-transition]).future{transform:translate(0,150%)}.reveal .slides section[data-transition=default].stack,.reveal.default .slides section.stack{transform-style:preserve-3d}.reveal .slides>section[data-transition=default].past,.reveal .slides>section[data-transition~=default-out].past,.reveal.default .slides>section:not([data-transition]).past{transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0)}.reveal .slides>section[data-transition=default].future,.reveal .slides>section[data-transition~=default-in].future,.reveal.default .slides>section:not([data-transition]).future{transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0)}.reveal .slides>section>section[data-transition=default].past,.reveal .slides>section>section[data-transition~=default-out].past,.reveal.default .slides>section>section:not([data-transition]).past{transform:translate3d(0,-300px,0) rotateX(70deg) translate3d(0,-300px,0)}.reveal .slides>section>section[data-transition=default].future,.reveal .slides>section>section[data-transition~=default-in].future,.reveal.default .slides>section>section:not([data-transition]).future{transform:translate3d(0,300px,0) rotateX(-70deg) translate3d(0,300px,0)}.reveal .slides section[data-transition=convex].stack,.reveal.convex .slides section.stack{transform-style:preserve-3d}.reveal .slides>section[data-transition=convex].past,.reveal .slides>section[data-transition~=convex-out].past,.reveal.convex .slides>section:not([data-transition]).past{transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0)}.reveal .slides>section[data-transition=convex].future,.reveal .slides>section[data-transition~=convex-in].future,.reveal.convex .slides>section:not([data-transition]).future{transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0)}.reveal .slides>section>section[data-transition=convex].past,.reveal .slides>section>section[data-transition~=convex-out].past,.reveal.convex .slides>section>section:not([data-transition]).past{transform:translate3d(0,-300px,0) rotateX(70deg) translate3d(0,-300px,0)}.reveal .slides>section>section[data-transition=convex].future,.reveal .slides>section>section[data-transition~=convex-in].future,.reveal.convex .slides>section>section:not([data-transition]).future{transform:translate3d(0,300px,0) rotateX(-70deg) translate3d(0,300px,0)}.reveal .slides section[data-transition=concave].stack,.reveal.concave .slides section.stack{transform-style:preserve-3d}.reveal .slides>section[data-transition=concave].past,.reveal .slides>section[data-transition~=concave-out].past,.reveal.concave .slides>section:not([data-transition]).past{transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0)}.reveal .slides>section[data-transition=concave].future,.reveal .slides>section[data-transition~=concave-in].future,.reveal.concave .slides>section:not([data-transition]).future{transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0)}.reveal .slides>section>section[data-transition=concave].past,.reveal .slides>section>section[data-transition~=concave-out].past,.reveal.concave .slides>section>section:not([data-transition]).past{transform:translate3d(0,-80%,0) rotateX(-70deg) translate3d(0,-80%,0)}.reveal .slides>section>section[data-transition=concave].future,.reveal .slides>section>section[data-transition~=concave-in].future,.reveal.concave .slides>section>section:not([data-transition]).future{transform:translate3d(0,80%,0) rotateX(70deg) translate3d(0,80%,0)}.reveal .slides section[data-transition=zoom],.reveal.zoom .slides section:not([data-transition]){transition-timing-function:ease}.reveal .slides>section[data-transition=zoom].past,.reveal .slides>section[data-transition~=zoom-out].past,.reveal.zoom .slides>section:not([data-transition]).past{visibility:hidden;transform:scale(16)}.reveal .slides>section[data-transition=zoom].future,.reveal .slides>section[data-transition~=zoom-in].future,.reveal.zoom .slides>section:not([data-transition]).future{visibility:hidden;transform:scale(.2)}.reveal .slides>section>section[data-transition=zoom].past,.reveal .slides>section>section[data-transition~=zoom-out].past,.reveal.zoom .slides>section>section:not([data-transition]).past{transform:scale(16)}.reveal .slides>section>section[data-transition=zoom].future,.reveal .slides>section>section[data-transition~=zoom-in].future,.reveal.zoom .slides>section>section:not([data-transition]).future{transform:scale(.2)}.reveal.cube .slides{perspective:1300px}.reveal.cube .slides section{padding:30px;min-height:700px;-webkit-backface-visibility:hidden;backface-visibility:hidden;box-sizing:border-box;transform-style:preserve-3d}.reveal.center.cube .slides section{min-height:0}.reveal.cube .slides section:not(.stack):before{content:"";position:absolute;display:block;width:100%;height:100%;left:0;top:0;background:rgba(0,0,0,.1);border-radius:4px;transform:translateZ(-20px)}.reveal.cube .slides section:not(.stack):after{content:"";position:absolute;display:block;width:90%;height:30px;left:5%;bottom:0;background:0 0;z-index:1;border-radius:4px;box-shadow:0 95px 25px rgba(0,0,0,.2);transform:translateZ(-90px) rotateX(65deg)}.reveal.cube .slides>section.stack{padding:0;background:0 0}.reveal.cube .slides>section.past{transform-origin:100% 0;transform:translate3d(-100%,0,0) rotateY(-90deg)}.reveal.cube .slides>section.future{transform-origin:0 0;transform:translate3d(100%,0,0) rotateY(90deg)}.reveal.cube .slides>section>section.past{transform-origin:0 100%;transform:translate3d(0,-100%,0) rotateX(90deg)}.reveal.cube .slides>section>section.future{transform-origin:0 0;transform:translate3d(0,100%,0) rotateX(-90deg)}.reveal.page .slides{perspective-origin:0 50%;perspective:3000px}.reveal.page .slides section{padding:30px;min-height:700px;box-sizing:border-box;transform-style:preserve-3d}.reveal.page .slides section.past{z-index:12}.reveal.page .slides section:not(.stack):before{content:"";position:absolute;display:block;width:100%;height:100%;left:0;top:0;background:rgba(0,0,0,.1);transform:translateZ(-20px)}.reveal.page .slides section:not(.stack):after{content:"";position:absolute;display:block;width:90%;height:30px;left:5%;bottom:0;background:0 0;z-index:1;border-radius:4px;box-shadow:0 95px 25px rgba(0,0,0,.2);-webkit-transform:translateZ(-90px) rotateX(65deg)}.reveal.page .slides>section.stack{padding:0;background:0 0}.reveal.page .slides>section.past{transform-origin:0 0;transform:translate3d(-40%,0,0) rotateY(-80deg)}.reveal.page .slides>section.future{transform-origin:100% 0;transform:translate3d(0,0,0)}.reveal.page .slides>section>section.past{transform-origin:0 0;transform:translate3d(0,-40%,0) rotateX(80deg)}.reveal.page .slides>section>section.future{transform-origin:0 100%;transform:translate3d(0,0,0)}.reveal .slides section[data-transition=fade],.reveal.fade .slides section:not([data-transition]),.reveal.fade .slides>section>section:not([data-transition]){transform:none;transition:opacity .5s}.reveal.fade.overview .slides section,.reveal.fade.overview .slides>section>section{transition:none}.reveal .slides section[data-transition=none],.reveal.none .slides section:not([data-transition]){transform:none;transition:none}.reveal .pause-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:#000;visibility:hidden;opacity:0;z-index:100;transition:all 1s ease}.reveal .pause-overlay .resume-button{position:absolute;bottom:20px;right:20px;color:#ccc;border-radius:2px;padding:6px 14px;border:2px solid #ccc;font-size:16px;background:0 0;cursor:pointer}.reveal .pause-overlay .resume-button:hover{color:#fff;border-color:#fff}.reveal.paused .pause-overlay{visibility:visible;opacity:1}.reveal .no-transition,.reveal .no-transition *,.reveal .slides.disable-slide-transitions section{transition:none!important}.reveal .slides.disable-slide-transitions section{transform:none!important}.reveal .backgrounds{position:absolute;width:100%;height:100%;top:0;left:0;perspective:600px}.reveal .slide-background{display:none;position:absolute;width:100%;height:100%;opacity:0;visibility:hidden;overflow:hidden;background-color:rgba(0,0,0,0);transition:all .8s cubic-bezier(.26,.86,.44,.985)}.reveal .slide-background-content{position:absolute;width:100%;height:100%;background-position:50% 50%;background-repeat:no-repeat;background-size:cover}.reveal .slide-background.stack{display:block}.reveal .slide-background.present{opacity:1;visibility:visible;z-index:2}.print-pdf .reveal .slide-background{opacity:1!important;visibility:visible!important}.reveal .slide-background video{position:absolute;width:100%;height:100%;max-width:none;max-height:none;top:0;left:0;-o-object-fit:cover;object-fit:cover}.reveal .slide-background[data-background-size=contain] video{-o-object-fit:contain;object-fit:contain}.reveal>.backgrounds .slide-background[data-background-transition=none],.reveal[data-background-transition=none]>.backgrounds .slide-background:not([data-background-transition]){transition:none}.reveal>.backgrounds .slide-background[data-background-transition=slide],.reveal[data-background-transition=slide]>.backgrounds .slide-background:not([data-background-transition]){opacity:1}.reveal>.backgrounds .slide-background.past[data-background-transition=slide],.reveal[data-background-transition=slide]>.backgrounds .slide-background.past:not([data-background-transition]){transform:translate(-100%,0)}.reveal>.backgrounds .slide-background.future[data-background-transition=slide],.reveal[data-background-transition=slide]>.backgrounds .slide-background.future:not([data-background-transition]){transform:translate(100%,0)}.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=slide],.reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.past:not([data-background-transition]){transform:translate(0,-100%)}.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=slide],.reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.future:not([data-background-transition]){transform:translate(0,100%)}.reveal>.backgrounds .slide-background.past[data-background-transition=convex],.reveal[data-background-transition=convex]>.backgrounds .slide-background.past:not([data-background-transition]){opacity:0;transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0)}.reveal>.backgrounds .slide-background.future[data-background-transition=convex],.reveal[data-background-transition=convex]>.backgrounds .slide-background.future:not([data-background-transition]){opacity:0;transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0)}.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=convex],.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.past:not([data-background-transition]){opacity:0;transform:translate3d(0,-100%,0) rotateX(90deg) translate3d(0,-100%,0)}.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=convex],.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.future:not([data-background-transition]){opacity:0;transform:translate3d(0,100%,0) rotateX(-90deg) translate3d(0,100%,0)}.reveal>.backgrounds .slide-background.past[data-background-transition=concave],.reveal[data-background-transition=concave]>.backgrounds .slide-background.past:not([data-background-transition]){opacity:0;transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0)}.reveal>.backgrounds .slide-background.future[data-background-transition=concave],.reveal[data-background-transition=concave]>.backgrounds .slide-background.future:not([data-background-transition]){opacity:0;transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0)}.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=concave],.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.past:not([data-background-transition]){opacity:0;transform:translate3d(0,-100%,0) rotateX(-90deg) translate3d(0,-100%,0)}.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=concave],.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.future:not([data-background-transition]){opacity:0;transform:translate3d(0,100%,0) rotateX(90deg) translate3d(0,100%,0)}.reveal>.backgrounds .slide-background[data-background-transition=zoom],.reveal[data-background-transition=zoom]>.backgrounds .slide-background:not([data-background-transition]){transition-timing-function:ease}.reveal>.backgrounds .slide-background.past[data-background-transition=zoom],.reveal[data-background-transition=zoom]>.backgrounds .slide-background.past:not([data-background-transition]){opacity:0;visibility:hidden;transform:scale(16)}.reveal>.backgrounds .slide-background.future[data-background-transition=zoom],.reveal[data-background-transition=zoom]>.backgrounds .slide-background.future:not([data-background-transition]){opacity:0;visibility:hidden;transform:scale(.2)}.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=zoom],.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.past:not([data-background-transition]){opacity:0;visibility:hidden;transform:scale(16)}.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=zoom],.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.future:not([data-background-transition]){opacity:0;visibility:hidden;transform:scale(.2)}.reveal[data-transition-speed=fast]>.backgrounds .slide-background{transition-duration:.4s}.reveal[data-transition-speed=slow]>.backgrounds .slide-background{transition-duration:1.2s}.reveal [data-auto-animate-target^=unmatched]{will-change:opacity}.reveal section[data-auto-animate]:not(.stack):not([data-auto-animate=running]) [data-auto-animate-target^=unmatched]{opacity:0}.reveal.overview{perspective-origin:50% 50%;perspective:700px}.reveal.overview .slides{-moz-transform-style:preserve-3d}.reveal.overview .slides section{height:100%;top:0!important;opacity:1!important;overflow:hidden;visibility:visible!important;cursor:pointer;box-sizing:border-box}.reveal.overview .slides section.present,.reveal.overview .slides section:hover{outline:10px solid rgba(150,150,150,.4);outline-offset:10px}.reveal.overview .slides section .fragment{opacity:1;transition:none}.reveal.overview .slides section:after,.reveal.overview .slides section:before{display:none!important}.reveal.overview .slides>section.stack{padding:0;top:0!important;background:0 0;outline:0;overflow:visible}.reveal.overview .backgrounds{perspective:inherit;-moz-transform-style:preserve-3d}.reveal.overview .backgrounds .slide-background{opacity:1;visibility:visible;outline:10px solid rgba(150,150,150,.1);outline-offset:10px}.reveal.overview .backgrounds .slide-background.stack{overflow:visible}.reveal.overview .slides section,.reveal.overview-deactivating .slides section{transition:none}.reveal.overview .backgrounds .slide-background,.reveal.overview-deactivating .backgrounds .slide-background{transition:none}.reveal.rtl .slides,.reveal.rtl .slides h1,.reveal.rtl .slides h2,.reveal.rtl .slides h3,.reveal.rtl .slides h4,.reveal.rtl .slides h5,.reveal.rtl .slides h6{direction:rtl;font-family:sans-serif}.reveal.rtl code,.reveal.rtl pre{direction:ltr}.reveal.rtl ol,.reveal.rtl ul{text-align:right}.reveal.rtl .progress span{transform-origin:100% 0}.reveal.has-parallax-background .backgrounds{transition:all .8s ease}.reveal.has-parallax-background[data-transition-speed=fast] .backgrounds{transition-duration:.4s}.reveal.has-parallax-background[data-transition-speed=slow] .backgrounds{transition-duration:1.2s}.reveal>.overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1000;background:rgba(0,0,0,.9);transition:all .3s ease}.reveal>.overlay .spinner{position:absolute;display:block;top:50%;left:50%;width:32px;height:32px;margin:-16px 0 0 -16px;z-index:10;background-image:url(data:image/gif;base64,R0lGODlhIAAgAPMAAJmZmf%2F%2F%2F6%2Bvr8nJybW1tcDAwOjo6Nvb26ioqKOjo7Ozs%2FLy8vz8%2FAAAAAAAAAAAACH%2FC05FVFNDQVBFMi4wAwEAAAAh%2FhpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh%2BQQJCgAAACwAAAAAIAAgAAAE5xDISWlhperN52JLhSSdRgwVo1ICQZRUsiwHpTJT4iowNS8vyW2icCF6k8HMMBkCEDskxTBDAZwuAkkqIfxIQyhBQBFvAQSDITM5VDW6XNE4KagNh6Bgwe60smQUB3d4Rz1ZBApnFASDd0hihh12BkE9kjAJVlycXIg7CQIFA6SlnJ87paqbSKiKoqusnbMdmDC2tXQlkUhziYtyWTxIfy6BE8WJt5YJvpJivxNaGmLHT0VnOgSYf0dZXS7APdpB309RnHOG5gDqXGLDaC457D1zZ%2FV%2FnmOM82XiHRLYKhKP1oZmADdEAAAh%2BQQJCgAAACwAAAAAIAAgAAAE6hDISWlZpOrNp1lGNRSdRpDUolIGw5RUYhhHukqFu8DsrEyqnWThGvAmhVlteBvojpTDDBUEIFwMFBRAmBkSgOrBFZogCASwBDEY%2FCZSg7GSE0gSCjQBMVG023xWBhklAnoEdhQEfyNqMIcKjhRsjEdnezB%2BA4k8gTwJhFuiW4dokXiloUepBAp5qaKpp6%2BHo7aWW54wl7obvEe0kRuoplCGepwSx2jJvqHEmGt6whJpGpfJCHmOoNHKaHx61WiSR92E4lbFoq%2BB6QDtuetcaBPnW6%2BO7wDHpIiK9SaVK5GgV543tzjgGcghAgAh%2BQQJCgAAACwAAAAAIAAgAAAE7hDISSkxpOrN5zFHNWRdhSiVoVLHspRUMoyUakyEe8PTPCATW9A14E0UvuAKMNAZKYUZCiBMuBakSQKG8G2FzUWox2AUtAQFcBKlVQoLgQReZhQlCIJesQXI5B0CBnUMOxMCenoCfTCEWBsJColTMANldx15BGs8B5wlCZ9Po6OJkwmRpnqkqnuSrayqfKmqpLajoiW5HJq7FL1Gr2mMMcKUMIiJgIemy7xZtJsTmsM4xHiKv5KMCXqfyUCJEonXPN2rAOIAmsfB3uPoAK%2B%2BG%2Bw48edZPK%2BM6hLJpQg484enXIdQFSS1u6UhksENEQAAIfkECQoAAAAsAAAAACAAIAAABOcQyEmpGKLqzWcZRVUQnZYg1aBSh2GUVEIQ2aQOE%2BG%2BcD4ntpWkZQj1JIiZIogDFFyHI0UxQwFugMSOFIPJftfVAEoZLBbcLEFhlQiqGp1Vd140AUklUN3eCA51C1EWMzMCezCBBmkxVIVHBWd3HHl9JQOIJSdSnJ0TDKChCwUJjoWMPaGqDKannasMo6WnM562R5YluZRwur0wpgqZE7NKUm%2BFNRPIhjBJxKZteWuIBMN4zRMIVIhffcgojwCF117i4nlLnY5ztRLsnOk%2BaV%2BoJY7V7m76PdkS4trKcdg0Zc0tTcKkRAAAIfkECQoAAAAsAAAAACAAIAAABO4QyEkpKqjqzScpRaVkXZWQEximw1BSCUEIlDohrft6cpKCk5xid5MNJTaAIkekKGQkWyKHkvhKsR7ARmitkAYDYRIbUQRQjWBwJRzChi9CRlBcY1UN4g0%2FVNB0AlcvcAYHRyZPdEQFYV8ccwR5HWxEJ02YmRMLnJ1xCYp0Y5idpQuhopmmC2KgojKasUQDk5BNAwwMOh2RtRq5uQuPZKGIJQIGwAwGf6I0JXMpC8C7kXWDBINFMxS4DKMAWVWAGYsAdNqW5uaRxkSKJOZKaU3tPOBZ4DuK2LATgJhkPJMgTwKCdFjyPHEnKxFCDhEAACH5BAkKAAAALAAAAAAgACAAAATzEMhJaVKp6s2nIkolIJ2WkBShpkVRWqqQrhLSEu9MZJKK9y1ZrqYK9WiClmvoUaF8gIQSNeF1Er4MNFn4SRSDARWroAIETg1iVwuHjYB1kYc1mwruwXKC9gmsJXliGxc%2BXiUCby9ydh1sOSdMkpMTBpaXBzsfhoc5l58Gm5yToAaZhaOUqjkDgCWNHAULCwOLaTmzswadEqggQwgHuQsHIoZCHQMMQgQGubVEcxOPFAcMDAYUA85eWARmfSRQCdcMe0zeP1AAygwLlJtPNAAL19DARdPzBOWSm1brJBi45soRAWQAAkrQIykShQ9wVhHCwCQCACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiRMDjI0Fd30%2FiI2UA5GSS5UDj2l6NoqgOgN4gksEBgYFf0FDqKgHnyZ9OX8HrgYHdHpcHQULXAS2qKpENRg7eAMLC7kTBaixUYFkKAzWAAnLC7FLVxLWDBLKCwaKTULgEwbLA4hJtOkSBNqITT3xEgfLpBtzE%2FjiuL04RGEBgwWhShRgQExHBAAh%2BQQJCgAAACwAAAAAIAAgAAAE7xDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfZiCqGk5dTESJeaOAlClzsJsqwiJwiqnFrb2nS9kmIcgEsjQydLiIlHehhpejaIjzh9eomSjZR%2BipslWIRLAgMDOR2DOqKogTB9pCUJBagDBXR6XB0EBkIIsaRsGGMMAxoDBgYHTKJiUYEGDAzHC9EACcUGkIgFzgwZ0QsSBcXHiQvOwgDdEwfFs0sDzt4S6BK4xYjkDOzn0unFeBzOBijIm1Dgmg5YFQwsCMjp1oJ8LyIAACH5BAkKAAAALAAAAAAgACAAAATwEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GGl6NoiPOH16iZKNlH6KmyWFOggHhEEvAwwMA0N9GBsEC6amhnVcEwavDAazGwIDaH1ipaYLBUTCGgQDA8NdHz0FpqgTBwsLqAbWAAnIA4FWKdMLGdYGEgraigbT0OITBcg5QwPT4xLrROZL6AuQAPUS7bxLpoWidY0JtxLHKhwwMJBTHgPKdEQAACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GAULDJCRiXo1CpGXDJOUjY%2BYip9DhToJA4RBLwMLCwVDfRgbBAaqqoZ1XBMHswsHtxtFaH1iqaoGNgAIxRpbFAgfPQSqpbgGBqUD1wBXeCYp1AYZ19JJOYgH1KwA4UBvQwXUBxPqVD9L3sbp2BNk2xvvFPJd%2BMFCN6HAAIKgNggY0KtEBAAh%2BQQJCgAAACwAAAAAIAAgAAAE6BDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfYIDMaAFdTESJeaEDAIMxYFqrOUaNW4E4ObYcCXaiBVEgULe0NJaxxtYksjh2NLkZISgDgJhHthkpU4mW6blRiYmZOlh4JWkDqILwUGBnE6TYEbCgevr0N1gH4At7gHiRpFaLNrrq8HNgAJA70AWxQIH1%2BvsYMDAzZQPC9VCNkDWUhGkuE5PxJNwiUK4UfLzOlD4WvzAHaoG9nxPi5d%2BjYUqfAhhykOFwJWiAAAIfkECQoAAAAsAAAAACAAIAAABPAQyElpUqnqzaciSoVkXVUMFaFSwlpOCcMYlErAavhOMnNLNo8KsZsMZItJEIDIFSkLGQoQTNhIsFehRww2CQLKF0tYGKYSg%2BygsZIuNqJksKgbfgIGepNo2cIUB3V1B3IvNiBYNQaDSTtfhhx0CwVPI0UJe0%2Bbm4g5VgcGoqOcnjmjqDSdnhgEoamcsZuXO1aWQy8KAwOAuTYYGwi7w5h%2BKr0SJ8MFihpNbx%2B4Erq7BYBuzsdiH1jCAzoSfl0rVirNbRXlBBlLX%2BBP0XJLAPGzTkAuAOqb0WT5AH7OcdCm5B8TgRwSRKIHQtaLCwg1RAAAOwAAAAAAAAAAAA%3D%3D);visibility:visible;opacity:.6;transition:all .3s ease}.reveal>.overlay header{position:absolute;left:0;top:0;width:100%;padding:5px;z-index:2;box-sizing:border-box}.reveal>.overlay header a{display:inline-block;width:40px;height:40px;line-height:36px;padding:0 10px;float:right;opacity:.6;box-sizing:border-box}.reveal>.overlay header a:hover{opacity:1}.reveal>.overlay header a .icon{display:inline-block;width:20px;height:20px;background-position:50% 50%;background-size:100%;background-repeat:no-repeat}.reveal>.overlay header a.close .icon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABkklEQVRYR8WX4VHDMAxG6wnoJrABZQPYBCaBTWAD2g1gE5gg6OOsXuxIlr40d81dfrSJ9V4c2VLK7spHuTJ/5wpM07QXuXc5X0opX2tEJcadjHuV80li/FgxTIEK/5QBCICBD6xEhSMGHgQPgBgLiYVAB1dpSqKDawxTohFw4JSEA3clzgIBPCURwE2JucBR7rhPJJv5OpJwDX+SfDjgx1wACQeJG1aChP9K/IMmdZ8DtESV1WyP3Bt4MwM6sj4NMxMYiqUWHQu4KYA/SYkIjOsm3BXYWMKFDwU2khjCQ4ELJUJ4SmClRArOCmSXGuKma0fYD5CbzHxFpCSGAhfAVSSUGDUk2BWZaff2g6GE15BsBQ9nwmpIGDiyHQddwNTMKkbZaf9fajXQca1EX44puJZUsnY0ObGmITE3GVLCbEhQUjGVt146j6oasWN+49Vph2w1pZ5EansNZqKBm1txbU57iRRcZ86RWMDdWtBJUHBHwoQPi1GV+JCbntmvok7iTX4/Up9mgyTc/FJYDTcndgH/AA5A/CHsyEkVAAAAAElFTkSuQmCC)}.reveal>.overlay header a.external .icon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAcElEQVRYR+2WSQoAIQwEzf8f7XiOMkUQxUPlGkM3hVmiQfQR9GYnH1SsAQlI4DiBqkCMoNb9y2e90IAEJPAcgdznU9+engMaeJ7Azh5Y1U67gAho4DqBqmB1buAf0MB1AlVBek83ZPkmJMGc1wAR+AAqod/B97TRpQAAAABJRU5ErkJggg==)}.reveal>.overlay .viewport{position:absolute;display:flex;top:50px;right:0;bottom:0;left:0}.reveal>.overlay.overlay-preview .viewport iframe{width:100%;height:100%;max-width:100%;max-height:100%;border:0;opacity:0;visibility:hidden;transition:all .3s ease}.reveal>.overlay.overlay-preview.loaded .viewport iframe{opacity:1;visibility:visible}.reveal>.overlay.overlay-preview.loaded .viewport-inner{position:absolute;z-index:-1;left:0;top:45%;width:100%;text-align:center;letter-spacing:normal}.reveal>.overlay.overlay-preview .x-frame-error{opacity:0;transition:opacity .3s ease .3s}.reveal>.overlay.overlay-preview.loaded .x-frame-error{opacity:1}.reveal>.overlay.overlay-preview.loaded .spinner{opacity:0;visibility:hidden;transform:scale(.2)}.reveal>.overlay.overlay-help .viewport{overflow:auto;color:#fff}.reveal>.overlay.overlay-help .viewport .viewport-inner{width:600px;margin:auto;padding:20px 20px 80px 20px;text-align:center;letter-spacing:normal}.reveal>.overlay.overlay-help .viewport .viewport-inner .title{font-size:20px}.reveal>.overlay.overlay-help .viewport .viewport-inner table{border:1px solid #fff;border-collapse:collapse;font-size:16px}.reveal>.overlay.overlay-help .viewport .viewport-inner table td,.reveal>.overlay.overlay-help .viewport .viewport-inner table th{width:200px;padding:14px;border:1px solid #fff;vertical-align:middle}.reveal>.overlay.overlay-help .viewport .viewport-inner table th{padding-top:20px;padding-bottom:20px}.reveal .playback{position:absolute;left:15px;bottom:20px;z-index:30;cursor:pointer;transition:all .4s ease;-webkit-tap-highlight-color:transparent}.reveal.overview .playback{opacity:0;visibility:hidden}.reveal .hljs{min-height:100%}.reveal .hljs table{margin:initial}.reveal .hljs-ln-code,.reveal .hljs-ln-numbers{padding:0;border:0}.reveal .hljs-ln-numbers{opacity:.6;padding-right:.75em;text-align:right;vertical-align:top}.reveal .hljs.has-highlights tr:not(.highlight-line){opacity:.4}.reveal .hljs:not(:first-child).fragment{position:absolute;top:0;left:0;width:100%;box-sizing:border-box}.reveal pre[data-auto-animate-target]{overflow:hidden}.reveal pre[data-auto-animate-target] code{height:100%}.reveal .roll{display:inline-block;line-height:1.2;overflow:hidden;vertical-align:top;perspective:400px;perspective-origin:50% 50%}.reveal .roll:hover{background:0 0;text-shadow:none}.reveal .roll span{display:block;position:relative;padding:0 2px;pointer-events:none;transition:all .4s ease;transform-origin:50% 0;transform-style:preserve-3d;-webkit-backface-visibility:hidden;backface-visibility:hidden}.reveal .roll:hover span{background:rgba(0,0,0,.5);transform:translate3d(0,0,-45px) rotateX(90deg)}.reveal .roll span:after{content:attr(data-title);display:block;position:absolute;left:0;top:0;padding:0 2px;-webkit-backface-visibility:hidden;backface-visibility:hidden;transform-origin:50% 0;transform:translate3d(0,110%,0) rotateX(-90deg)}.reveal aside.notes{display:none}.reveal .speaker-notes{display:none;position:absolute;width:33.3333333333%;height:100%;top:0;left:100%;padding:14px 18px 14px 18px;z-index:1;font-size:18px;line-height:1.4;border:1px solid rgba(0,0,0,.05);color:#222;background-color:#f5f5f5;overflow:auto;box-sizing:border-box;text-align:left;font-family:Helvetica,sans-serif;-webkit-overflow-scrolling:touch}.reveal .speaker-notes .notes-placeholder{color:#ccc;font-style:italic}.reveal .speaker-notes:focus{outline:0}.reveal .speaker-notes:before{content:"Speaker notes";display:block;margin-bottom:10px;opacity:.5}.reveal.show-notes{max-width:75%;overflow:visible}.reveal.show-notes .speaker-notes{display:block}@media screen and (min-width:1600px){.reveal .speaker-notes{font-size:20px}}@media screen and (max-width:1024px){.reveal.show-notes{border-left:0;max-width:none;max-height:70%;max-height:70vh;overflow:visible}.reveal.show-notes .speaker-notes{top:100%;left:0;width:100%;height:30vh;border:0}}@media screen and (max-width:600px){.reveal.show-notes{max-height:60%;max-height:60vh}.reveal.show-notes .speaker-notes{top:100%;height:40vh}.reveal .speaker-notes{font-size:14px}}.zoomed .reveal *,.zoomed .reveal :after,.zoomed .reveal :before{-webkit-backface-visibility:visible!important;backface-visibility:visible!important}.zoomed .reveal .controls,.zoomed .reveal .progress{opacity:0}.zoomed .reveal .roll span{background:0 0}.zoomed .reveal .roll span:after{visibility:hidden}html.print-pdf *{-webkit-print-color-adjust:exact}html.print-pdf{width:100%;height:100%;overflow:visible}html.print-pdf body{margin:0 auto!important;border:0;padding:0;float:none!important;overflow:visible}html.print-pdf .nestedarrow,html.print-pdf .reveal .controls,html.print-pdf .reveal .playback,html.print-pdf .reveal .progress,html.print-pdf .reveal.overview,html.print-pdf .state-background{display:none!important}html.print-pdf .reveal pre code{overflow:hidden!important;font-family:Courier,"Courier New",monospace!important}html.print-pdf .reveal{width:auto!important;height:auto!important;overflow:hidden!important}html.print-pdf .reveal .slides{position:static;width:100%!important;height:auto!important;zoom:1!important;pointer-events:initial;left:auto;top:auto;margin:0!important;padding:0!important;overflow:visible;display:block;perspective:none;perspective-origin:50% 50%}html.print-pdf .reveal .slides .pdf-page{position:relative;overflow:hidden;z-index:1;page-break-after:always}html.print-pdf .reveal .slides section{visibility:visible!important;display:block!important;position:absolute!important;margin:0!important;padding:0!important;box-sizing:border-box!important;min-height:1px;opacity:1!important;transform-style:flat!important;transform:none!important}html.print-pdf .reveal section.stack{position:relative!important;margin:0!important;padding:0!important;page-break-after:avoid!important;height:auto!important;min-height:auto!important}html.print-pdf .reveal img{box-shadow:none}html.print-pdf .reveal .backgrounds{display:none}html.print-pdf .reveal .slide-background{display:block!important;position:absolute;top:0;left:0;width:100%;height:100%;z-index:auto!important}html.print-pdf .reveal.show-notes{max-width:none;max-height:none}html.print-pdf .reveal .speaker-notes-pdf{display:block;width:100%;height:auto;max-height:none;top:auto;right:auto;bottom:auto;left:auto;z-index:100}html.print-pdf .reveal .speaker-notes-pdf[data-layout=separate-page]{position:relative;color:inherit;background-color:transparent;padding:20px;page-break-after:always;border:0}html.print-pdf .reveal .slide-number-pdf{display:block;position:absolute;font-size:14px}html.print-pdf .aria-status{display:none}@media print{html:not(.print-pdf){background:#fff;width:auto;height:auto;overflow:visible}html:not(.print-pdf) body{background:#fff;font-size:20pt;width:auto;height:auto;border:0;margin:0 5%;padding:0;overflow:visible;float:none!important}html:not(.print-pdf) .controls,html:not(.print-pdf) .fork-reveal,html:not(.print-pdf) .nestedarrow,html:not(.print-pdf) .reveal .backgrounds,html:not(.print-pdf) .reveal .progress,html:not(.print-pdf) .reveal .slide-number,html:not(.print-pdf) .share-reveal,html:not(.print-pdf) .state-background{display:none!important}html:not(.print-pdf) body,html:not(.print-pdf) li,html:not(.print-pdf) p,html:not(.print-pdf) td{font-size:20pt!important;color:#000}html:not(.print-pdf) h1,html:not(.print-pdf) h2,html:not(.print-pdf) h3,html:not(.print-pdf) h4,html:not(.print-pdf) h5,html:not(.print-pdf) h6{color:#000!important;height:auto;line-height:normal;text-align:left;letter-spacing:normal}html:not(.print-pdf) h1{font-size:28pt!important}html:not(.print-pdf) h2{font-size:24pt!important}html:not(.print-pdf) h3{font-size:22pt!important}html:not(.print-pdf) h4{font-size:22pt!important;font-variant:small-caps}html:not(.print-pdf) h5{font-size:21pt!important}html:not(.print-pdf) h6{font-size:20pt!important;font-style:italic}html:not(.print-pdf) a:link,html:not(.print-pdf) a:visited{color:#000!important;font-weight:700;text-decoration:underline}html:not(.print-pdf) div,html:not(.print-pdf) ol,html:not(.print-pdf) p,html:not(.print-pdf) ul{visibility:visible;position:static;width:auto;height:auto;display:block;overflow:visible;margin:0;text-align:left!important}html:not(.print-pdf) .reveal pre,html:not(.print-pdf) .reveal table{margin-left:0;margin-right:0}html:not(.print-pdf) .reveal pre code{padding:20px}html:not(.print-pdf) .reveal blockquote{margin:20px 0}html:not(.print-pdf) .reveal .slides{position:static!important;width:auto!important;height:auto!important;left:0!important;top:0!important;margin-left:0!important;margin-top:0!important;padding:0!important;zoom:1!important;transform:none!important;overflow:visible!important;display:block!important;text-align:left!important;perspective:none;perspective-origin:50% 50%}html:not(.print-pdf) .reveal .slides section{visibility:visible!important;position:static!important;width:auto!important;height:auto!important;display:block!important;overflow:visible!important;left:0!important;top:0!important;margin-left:0!important;margin-top:0!important;padding:60px 20px!important;z-index:auto!important;opacity:1!important;page-break-after:always!important;transform-style:flat!important;transform:none!important;transition:none!important}html:not(.print-pdf) .reveal .slides section.stack{padding:0!important}html:not(.print-pdf) .reveal section:last-of-type{page-break-after:avoid!important}html:not(.print-pdf) .reveal section .fragment{opacity:1!important;visibility:visible!important;transform:none!important}html:not(.print-pdf) .reveal section img{display:block;margin:15px 0;background:#fff;border:1px solid #666;box-shadow:none}html:not(.print-pdf) .reveal section small{font-size:.8em}html:not(.print-pdf) .reveal .hljs{max-height:100%;white-space:pre-wrap;word-wrap:break-word;word-break:break-word;font-size:15pt}html:not(.print-pdf) .reveal .hljs .hljs-ln-numbers{white-space:nowrap}html:not(.print-pdf) .reveal .hljs td{font-size:inherit!important;color:inherit!important}}
\ No newline at end of file
diff --git a/3 Cognitive change/project-presentation_files/libs/revealjs/dist/reveal.esm.js b/3 Cognitive change/project-presentation_files/libs/revealjs/dist/reveal.esm.js
new file mode 100644
index 0000000..f18da89
--- /dev/null
+++ b/3 Cognitive change/project-presentation_files/libs/revealjs/dist/reveal.esm.js
@@ -0,0 +1,9 @@
+/*!
+* reveal.js 4.3.1
+* https://revealjs.com
+* MIT licensed
+*
+* Copyright (C) 2011-2022 Hakim El Hattab, https://hakim.se
+*/
+const e=(e,t)=>{for(let i in t)e[i]=t[i];return e},t=(e,t)=>Array.from(e.querySelectorAll(t)),i=(e,t,i)=>{i?e.classList.add(t):e.classList.remove(t)},s=e=>{if("string"==typeof e){if("null"===e)return null;if("true"===e)return!0;if("false"===e)return!1;if(e.match(/^-?[\d\.]+$/))return parseFloat(e)}return e},a=(e,t)=>{e.style.transform=t},n=(e,t)=>{let i=e.matches||e.matchesSelector||e.msMatchesSelector;return!(!i||!i.call(e,t))},r=(e,t)=>{if("function"==typeof e.closest)return e.closest(t);for(;e;){if(n(e,t))return e;e=e.parentNode}return null},o=(e,t,i,s="")=>{let a=e.querySelectorAll("."+i);for(let t=0;t{let t=document.createElement("style");return t.type="text/css",e&&e.length>0&&(t.styleSheet?t.styleSheet.cssText=e:t.appendChild(document.createTextNode(e))),document.head.appendChild(t),t},d=()=>{let e={};location.search.replace(/[A-Z0-9]+?=([\w\.%-]*)/gi,(t=>{e[t.split("=").shift()]=t.split("=").pop()}));for(let t in e){let i=e[t];e[t]=s(unescape(i))}return void 0!==e.dependencies&&delete e.dependencies,e},c=(e,t=0)=>{if(e){let i,s=e.style.height;return e.style.height="0px",e.parentNode.style.height="auto",i=t-e.parentNode.offsetHeight,e.style.height=s+"px",e.parentNode.style.removeProperty("height"),i}return t},h={mp4:"video/mp4",m4a:"video/mp4",ogv:"video/ogg",mpeg:"video/mpeg",webm:"video/webm"},u=navigator.userAgent,g=/(iphone|ipod|ipad|android)/gi.test(u)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1;/chrome/i.test(u)&&/edge/i.test(u);const v=/android/gi.test(u);var p={};Object.defineProperty(p,"__esModule",{value:!0});var m=Object.assign||function(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:{};return"string"==typeof e?x(t(document.querySelectorAll(e)),i):x([e],i)[0]}}("undefined"==typeof window?null:window);class b{constructor(e){this.Reveal=e,this.startEmbeddedIframe=this.startEmbeddedIframe.bind(this)}shouldPreload(e){let t=this.Reveal.getConfig().preloadIframes;return"boolean"!=typeof t&&(t=e.hasAttribute("data-preload")),t}load(e,i={}){e.style.display=this.Reveal.getConfig().display,t(e,"img[data-src], video[data-src], audio[data-src], iframe[data-src]").forEach((e=>{("IFRAME"!==e.tagName||this.shouldPreload(e))&&(e.setAttribute("src",e.getAttribute("data-src")),e.setAttribute("data-lazy-loaded",""),e.removeAttribute("data-src"))})),t(e,"video, audio").forEach((e=>{let i=0;t(e,"source[data-src]").forEach((e=>{e.setAttribute("src",e.getAttribute("data-src")),e.removeAttribute("data-src"),e.setAttribute("data-lazy-loaded",""),i+=1})),g&&"VIDEO"===e.tagName&&e.setAttribute("playsinline",""),i>0&&e.load()}));let s=e.slideBackgroundElement;if(s){s.style.display="block";let t=e.slideBackgroundContentElement,a=e.getAttribute("data-background-iframe");if(!1===s.hasAttribute("data-loaded")){s.setAttribute("data-loaded","true");let n=e.getAttribute("data-background-image"),r=e.getAttribute("data-background-video"),o=e.hasAttribute("data-background-video-loop"),l=e.hasAttribute("data-background-video-muted");if(n)/^data:/.test(n.trim())?t.style.backgroundImage=`url(${n.trim()})`:t.style.backgroundImage=n.split(",").map((e=>`url(${encodeURI(e.trim())})`)).join(",");else if(r&&!this.Reveal.isSpeakerNotes()){let e=document.createElement("video");o&&e.setAttribute("loop",""),l&&(e.muted=!0),g&&(e.muted=!0,e.setAttribute("playsinline","")),r.split(",").forEach((t=>{let i=((e="")=>h[e.split(".").pop()])(t);e.innerHTML+=i?``:``})),t.appendChild(e)}else if(a&&!0!==i.excludeIframes){let e=document.createElement("iframe");e.setAttribute("allowfullscreen",""),e.setAttribute("mozallowfullscreen",""),e.setAttribute("webkitallowfullscreen",""),e.setAttribute("allow","autoplay"),e.setAttribute("data-src",a),e.style.width="100%",e.style.height="100%",e.style.maxHeight="100%",e.style.maxWidth="100%",t.appendChild(e)}}let n=t.querySelector("iframe[data-src]");n&&this.shouldPreload(s)&&!/autoplay=(1|true|yes)/gi.test(a)&&n.getAttribute("src")!==a&&n.setAttribute("src",a)}this.layout(e)}layout(e){Array.from(e.querySelectorAll(".r-fit-text")).forEach((e=>{f(e,{minSize:24,maxSize:.8*this.Reveal.getConfig().height,observeMutations:!1,observeWindow:!1})}))}unload(e){e.style.display="none";let i=this.Reveal.getSlideBackground(e);i&&(i.style.display="none",t(i,"iframe[src]").forEach((e=>{e.removeAttribute("src")}))),t(e,"video[data-lazy-loaded][src], audio[data-lazy-loaded][src], iframe[data-lazy-loaded][src]").forEach((e=>{e.setAttribute("data-src",e.getAttribute("src")),e.removeAttribute("src")})),t(e,"video[data-lazy-loaded] source[src], audio source[src]").forEach((e=>{e.setAttribute("data-src",e.getAttribute("src")),e.removeAttribute("src")}))}formatEmbeddedContent(){let e=(e,i,s)=>{t(this.Reveal.getSlidesElement(),"iframe["+e+'*="'+i+'"]').forEach((t=>{let i=t.getAttribute(e);i&&-1===i.indexOf(s)&&t.setAttribute(e,i+(/\?/.test(i)?"&":"?")+s)}))};e("src","youtube.com/embed/","enablejsapi=1"),e("data-src","youtube.com/embed/","enablejsapi=1"),e("src","player.vimeo.com/","api=1"),e("data-src","player.vimeo.com/","api=1")}startEmbeddedContent(e){e&&!this.Reveal.isSpeakerNotes()&&(t(e,'img[src$=".gif"]').forEach((e=>{e.setAttribute("src",e.getAttribute("src"))})),t(e,"video, audio").forEach((e=>{if(r(e,".fragment")&&!r(e,".fragment.visible"))return;let t=this.Reveal.getConfig().autoPlayMedia;if("boolean"!=typeof t&&(t=e.hasAttribute("data-autoplay")||!!r(e,".slide-background")),t&&"function"==typeof e.play)if(e.readyState>1)this.startEmbeddedMedia({target:e});else if(g){let t=e.play();t&&"function"==typeof t.catch&&!1===e.controls&&t.catch((()=>{e.controls=!0,e.addEventListener("play",(()=>{e.controls=!1}))}))}else e.removeEventListener("loadeddata",this.startEmbeddedMedia),e.addEventListener("loadeddata",this.startEmbeddedMedia)})),t(e,"iframe[src]").forEach((e=>{r(e,".fragment")&&!r(e,".fragment.visible")||this.startEmbeddedIframe({target:e})})),t(e,"iframe[data-src]").forEach((e=>{r(e,".fragment")&&!r(e,".fragment.visible")||e.getAttribute("src")!==e.getAttribute("data-src")&&(e.removeEventListener("load",this.startEmbeddedIframe),e.addEventListener("load",this.startEmbeddedIframe),e.setAttribute("src",e.getAttribute("data-src")))})))}startEmbeddedMedia(e){let t=!!r(e.target,"html"),i=!!r(e.target,".present");t&&i&&(e.target.currentTime=0,e.target.play()),e.target.removeEventListener("loadeddata",this.startEmbeddedMedia)}startEmbeddedIframe(e){let t=e.target;if(t&&t.contentWindow){let i=!!r(e.target,"html"),s=!!r(e.target,".present");if(i&&s){let e=this.Reveal.getConfig().autoPlayMedia;"boolean"!=typeof e&&(e=t.hasAttribute("data-autoplay")||!!r(t,".slide-background")),/youtube\.com\/embed\//.test(t.getAttribute("src"))&&e?t.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}',"*"):/player\.vimeo\.com\//.test(t.getAttribute("src"))&&e?t.contentWindow.postMessage('{"method":"play"}',"*"):t.contentWindow.postMessage("slide:start","*")}}}stopEmbeddedContent(i,s={}){s=e({unloadIframes:!0},s),i&&i.parentNode&&(t(i,"video, audio").forEach((e=>{e.hasAttribute("data-ignore")||"function"!=typeof e.pause||(e.setAttribute("data-paused-by-reveal",""),e.pause())})),t(i,"iframe").forEach((e=>{e.contentWindow&&e.contentWindow.postMessage("slide:stop","*"),e.removeEventListener("load",this.startEmbeddedIframe)})),t(i,'iframe[src*="youtube.com/embed/"]').forEach((e=>{!e.hasAttribute("data-ignore")&&e.contentWindow&&"function"==typeof e.contentWindow.postMessage&&e.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}',"*")})),t(i,'iframe[src*="player.vimeo.com/"]').forEach((e=>{!e.hasAttribute("data-ignore")&&e.contentWindow&&"function"==typeof e.contentWindow.postMessage&&e.contentWindow.postMessage('{"method":"pause"}',"*")})),!0===s.unloadIframes&&t(i,"iframe[data-src]").forEach((e=>{e.setAttribute("src","about:blank"),e.removeAttribute("src")})))}}class y{constructor(e){this.Reveal=e}render(){this.element=document.createElement("div"),this.element.className="slide-number",this.Reveal.getRevealElement().appendChild(this.element)}configure(e,t){let i="none";e.slideNumber&&!this.Reveal.isPrintingPDF()&&("all"===e.showSlideNumber||"speaker"===e.showSlideNumber&&this.Reveal.isSpeakerNotes())&&(i="block"),this.element.style.display=i}update(){this.Reveal.getConfig().slideNumber&&this.element&&(this.element.innerHTML=this.getSlideNumber())}getSlideNumber(e=this.Reveal.getCurrentSlide()){let t,i=this.Reveal.getConfig(),s="h.v";if("function"==typeof i.slideNumber)t=i.slideNumber(e);else{"string"==typeof i.slideNumber&&(s=i.slideNumber),/c/.test(s)||1!==this.Reveal.getHorizontalSlides().length||(s="c");let a=e&&"uncounted"===e.dataset.visibility?0:1;switch(t=[],s){case"c":t.push(this.Reveal.getSlidePastCount(e)+a);break;case"c/t":t.push(this.Reveal.getSlidePastCount(e)+a,"/",this.Reveal.getTotalSlides());break;default:let i=this.Reveal.getIndices(e);t.push(i.h+a);let n="h/v"===s?"/":".";this.Reveal.isVerticalSlide(e)&&t.push(n,i.v+1)}}let a="#"+this.Reveal.location.getHash(e);return this.formatNumber(t[0],t[1],t[2],a)}formatNumber(e,t,i,s="#"+this.Reveal.location.getHash()){return"number"!=typeof i||isNaN(i)?`\n\t\t\t\t\t${e} \n\t\t\t\t\t `:`\n\t\t\t\t\t${e} \n\t\t\t\t\t${t} \n\t\t\t\t\t${i} \n\t\t\t\t\t `}destroy(){this.element.remove()}}const w=e=>{let t=e.match(/^#([0-9a-f]{3})$/i);if(t&&t[1])return t=t[1],{r:17*parseInt(t.charAt(0),16),g:17*parseInt(t.charAt(1),16),b:17*parseInt(t.charAt(2),16)};let i=e.match(/^#([0-9a-f]{6})$/i);if(i&&i[1])return i=i[1],{r:parseInt(i.slice(0,2),16),g:parseInt(i.slice(2,4),16),b:parseInt(i.slice(4,6),16)};let s=e.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i);if(s)return{r:parseInt(s[1],10),g:parseInt(s[2],10),b:parseInt(s[3],10)};let a=e.match(/^rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\,\s*([\d]+|[\d]*.[\d]+)\s*\)$/i);return a?{r:parseInt(a[1],10),g:parseInt(a[2],10),b:parseInt(a[3],10),a:parseFloat(a[4])}:null};class E{constructor(e){this.Reveal=e}render(){this.element=document.createElement("div"),this.element.className="backgrounds",this.Reveal.getRevealElement().appendChild(this.element)}create(){this.element.innerHTML="",this.element.classList.add("no-transition"),this.Reveal.getHorizontalSlides().forEach((e=>{let i=this.createBackground(e,this.element);t(e,"section").forEach((e=>{this.createBackground(e,i),i.classList.add("stack")}))})),this.Reveal.getConfig().parallaxBackgroundImage?(this.element.style.backgroundImage='url("'+this.Reveal.getConfig().parallaxBackgroundImage+'")',this.element.style.backgroundSize=this.Reveal.getConfig().parallaxBackgroundSize,this.element.style.backgroundRepeat=this.Reveal.getConfig().parallaxBackgroundRepeat,this.element.style.backgroundPosition=this.Reveal.getConfig().parallaxBackgroundPosition,setTimeout((()=>{this.Reveal.getRevealElement().classList.add("has-parallax-background")}),1)):(this.element.style.backgroundImage="",this.Reveal.getRevealElement().classList.remove("has-parallax-background"))}createBackground(e,t){let i=document.createElement("div");i.className="slide-background "+e.className.replace(/present|past|future/,"");let s=document.createElement("div");return s.className="slide-background-content",i.appendChild(s),t.appendChild(i),e.slideBackgroundElement=i,e.slideBackgroundContentElement=s,this.sync(e),i}sync(e){const t=e.slideBackgroundElement,i=e.slideBackgroundContentElement,s={background:e.getAttribute("data-background"),backgroundSize:e.getAttribute("data-background-size"),backgroundImage:e.getAttribute("data-background-image"),backgroundVideo:e.getAttribute("data-background-video"),backgroundIframe:e.getAttribute("data-background-iframe"),backgroundColor:e.getAttribute("data-background-color"),backgroundRepeat:e.getAttribute("data-background-repeat"),backgroundPosition:e.getAttribute("data-background-position"),backgroundTransition:e.getAttribute("data-background-transition"),backgroundOpacity:e.getAttribute("data-background-opacity")},a=e.hasAttribute("data-preload");e.classList.remove("has-dark-background"),e.classList.remove("has-light-background"),t.removeAttribute("data-loaded"),t.removeAttribute("data-background-hash"),t.removeAttribute("data-background-size"),t.removeAttribute("data-background-transition"),t.style.backgroundColor="",i.style.backgroundSize="",i.style.backgroundRepeat="",i.style.backgroundPosition="",i.style.backgroundImage="",i.style.opacity="",i.innerHTML="",s.background&&(/^(http|file|\/\/)/gi.test(s.background)||/\.(svg|png|jpg|jpeg|gif|bmp)([?#\s]|$)/gi.test(s.background)?e.setAttribute("data-background-image",s.background):t.style.background=s.background),(s.background||s.backgroundColor||s.backgroundImage||s.backgroundVideo||s.backgroundIframe)&&t.setAttribute("data-background-hash",s.background+s.backgroundSize+s.backgroundImage+s.backgroundVideo+s.backgroundIframe+s.backgroundColor+s.backgroundRepeat+s.backgroundPosition+s.backgroundTransition+s.backgroundOpacity),s.backgroundSize&&t.setAttribute("data-background-size",s.backgroundSize),s.backgroundColor&&(t.style.backgroundColor=s.backgroundColor),s.backgroundTransition&&t.setAttribute("data-background-transition",s.backgroundTransition),a&&t.setAttribute("data-preload",""),s.backgroundSize&&(i.style.backgroundSize=s.backgroundSize),s.backgroundRepeat&&(i.style.backgroundRepeat=s.backgroundRepeat),s.backgroundPosition&&(i.style.backgroundPosition=s.backgroundPosition),s.backgroundOpacity&&(i.style.opacity=s.backgroundOpacity);let n=s.backgroundColor;if(!n||!w(n)){let e=window.getComputedStyle(t);e&&e.backgroundColor&&(n=e.backgroundColor)}if(n){const t=w(n);t&&0!==t.a&&("string"==typeof(r=n)&&(r=w(r)),(r?(299*r.r+587*r.g+114*r.b)/1e3:null)<128?e.classList.add("has-dark-background"):e.classList.add("has-light-background"))}var r}update(e=!1){let i=this.Reveal.getCurrentSlide(),s=this.Reveal.getIndices(),a=null,n=this.Reveal.getConfig().rtl?"future":"past",r=this.Reveal.getConfig().rtl?"past":"future";if(Array.from(this.element.childNodes).forEach(((i,o)=>{i.classList.remove("past","present","future"),os.h?i.classList.add(r):(i.classList.add("present"),a=i),(e||o===s.h)&&t(i,".slide-background").forEach(((e,t)=>{e.classList.remove("past","present","future"),ts.v?e.classList.add("future"):(e.classList.add("present"),o===s.h&&(a=e))}))})),this.previousBackground&&this.Reveal.slideContent.stopEmbeddedContent(this.previousBackground,{unloadIframes:!this.Reveal.slideContent.shouldPreload(this.previousBackground)}),a){this.Reveal.slideContent.startEmbeddedContent(a);let e=a.querySelector(".slide-background-content");if(e){let t=e.style.backgroundImage||"";/\.gif/i.test(t)&&(e.style.backgroundImage="",window.getComputedStyle(e).opacity,e.style.backgroundImage=t)}let t=this.previousBackground?this.previousBackground.getAttribute("data-background-hash"):null,i=a.getAttribute("data-background-hash");i&&i===t&&a!==this.previousBackground&&this.element.classList.add("no-transition"),this.previousBackground=a}i&&["has-light-background","has-dark-background"].forEach((e=>{i.classList.contains(e)?this.Reveal.getRevealElement().classList.add(e):this.Reveal.getRevealElement().classList.remove(e)}),this),setTimeout((()=>{this.element.classList.remove("no-transition")}),1)}updateParallax(){let e=this.Reveal.getIndices();if(this.Reveal.getConfig().parallaxBackgroundImage){let t,i,s=this.Reveal.getHorizontalSlides(),a=this.Reveal.getVerticalSlides(),n=this.element.style.backgroundSize.split(" ");1===n.length?t=i=parseInt(n[0],10):(t=parseInt(n[0],10),i=parseInt(n[1],10));let r,o,l=this.element.offsetWidth,d=s.length;r="number"==typeof this.Reveal.getConfig().parallaxBackgroundHorizontal?this.Reveal.getConfig().parallaxBackgroundHorizontal:d>1?(t-l)/(d-1):0,o=r*e.h*-1;let c,h,u=this.element.offsetHeight,g=a.length;c="number"==typeof this.Reveal.getConfig().parallaxBackgroundVertical?this.Reveal.getConfig().parallaxBackgroundVertical:(i-u)/(g-1),h=g>0?c*e.v:0,this.element.style.backgroundPosition=o+"px "+-h+"px"}}destroy(){this.element.remove()}}const R=/registerPlugin|registerKeyboardShortcut|addKeyBinding|addEventListener/,S=/fade-(down|up|right|left|out|in-then-out|in-then-semi-out)|semi-fade-out|current-visible|shrink|grow/;let A=0;class k{constructor(e){this.Reveal=e}run(e,t){this.reset();let i=this.Reveal.getSlides(),s=i.indexOf(t),a=i.indexOf(e);if(e.hasAttribute("data-auto-animate")&&t.hasAttribute("data-auto-animate")&&e.getAttribute("data-auto-animate-id")===t.getAttribute("data-auto-animate-id")&&!(s>a?t:e).hasAttribute("data-auto-animate-restart")){this.autoAnimateStyleSheet=this.autoAnimateStyleSheet||l();let i=this.getAutoAnimateOptions(t);e.dataset.autoAnimate="pending",t.dataset.autoAnimate="pending",i.slideDirection=s>a?"forward":"backward";let n=this.getAutoAnimatableElements(e,t).map((e=>this.autoAnimateElements(e.from,e.to,e.options||{},i,A++)));if("false"!==t.dataset.autoAnimateUnmatched&&!0===this.Reveal.getConfig().autoAnimateUnmatched){let e=.8*i.duration,s=.2*i.duration;this.getUnmatchedAutoAnimateElements(t).forEach((e=>{let t=this.getAutoAnimateOptions(e,i),s="unmatched";t.duration===i.duration&&t.delay===i.delay||(s="unmatched-"+A++,n.push(`[data-auto-animate="running"] [data-auto-animate-target="${s}"] { transition: opacity ${t.duration}s ease ${t.delay}s; }`)),e.dataset.autoAnimateTarget=s}),this),n.push(`[data-auto-animate="running"] [data-auto-animate-target="unmatched"] { transition: opacity ${e}s ease ${s}s; }`)}this.autoAnimateStyleSheet.innerHTML=n.join(""),requestAnimationFrame((()=>{this.autoAnimateStyleSheet&&(getComputedStyle(this.autoAnimateStyleSheet).fontWeight,t.dataset.autoAnimate="running")})),this.Reveal.dispatchEvent({type:"autoanimate",data:{fromSlide:e,toSlide:t,sheet:this.autoAnimateStyleSheet}})}}reset(){t(this.Reveal.getRevealElement(),'[data-auto-animate]:not([data-auto-animate=""])').forEach((e=>{e.dataset.autoAnimate=""})),t(this.Reveal.getRevealElement(),"[data-auto-animate-target]").forEach((e=>{delete e.dataset.autoAnimateTarget})),this.autoAnimateStyleSheet&&this.autoAnimateStyleSheet.parentNode&&(this.autoAnimateStyleSheet.parentNode.removeChild(this.autoAnimateStyleSheet),this.autoAnimateStyleSheet=null)}autoAnimateElements(e,t,i,s,a){e.dataset.autoAnimateTarget="",t.dataset.autoAnimateTarget=a;let n=this.getAutoAnimateOptions(t,s);void 0!==i.delay&&(n.delay=i.delay),void 0!==i.duration&&(n.duration=i.duration),void 0!==i.easing&&(n.easing=i.easing);let r=this.getAutoAnimatableProperties("from",e,i),o=this.getAutoAnimatableProperties("to",t,i);if(t.classList.contains("fragment")&&(delete o.styles.opacity,e.classList.contains("fragment"))){(e.className.match(S)||[""])[0]===(t.className.match(S)||[""])[0]&&"forward"===s.slideDirection&&t.classList.add("visible","disabled")}if(!1!==i.translate||!1!==i.scale){let e=this.Reveal.getScale(),t={x:(r.x-o.x)/e,y:(r.y-o.y)/e,scaleX:r.width/o.width,scaleY:r.height/o.height};t.x=Math.round(1e3*t.x)/1e3,t.y=Math.round(1e3*t.y)/1e3,t.scaleX=Math.round(1e3*t.scaleX)/1e3,t.scaleX=Math.round(1e3*t.scaleX)/1e3;let s=!1!==i.translate&&(0!==t.x||0!==t.y),a=!1!==i.scale&&(0!==t.scaleX||0!==t.scaleY);if(s||a){let e=[];s&&e.push(`translate(${t.x}px, ${t.y}px)`),a&&e.push(`scale(${t.scaleX}, ${t.scaleY})`),r.styles.transform=e.join(" "),r.styles["transform-origin"]="top left",o.styles.transform="none"}}for(let e in o.styles){const t=o.styles[e],i=r.styles[e];t===i?delete o.styles[e]:(!0===t.explicitValue&&(o.styles[e]=t.value),!0===i.explicitValue&&(r.styles[e]=i.value))}let l="",d=Object.keys(o.styles);if(d.length>0){r.styles.transition="none",o.styles.transition=`all ${n.duration}s ${n.easing} ${n.delay}s`,o.styles["transition-property"]=d.join(", "),o.styles["will-change"]=d.join(", "),l='[data-auto-animate-target="'+a+'"] {'+Object.keys(r.styles).map((e=>e+": "+r.styles[e]+" !important;")).join("")+'}[data-auto-animate="running"] [data-auto-animate-target="'+a+'"] {'+Object.keys(o.styles).map((e=>e+": "+o.styles[e]+" !important;")).join("")+"}"}return l}getAutoAnimateOptions(t,i){let s={easing:this.Reveal.getConfig().autoAnimateEasing,duration:this.Reveal.getConfig().autoAnimateDuration,delay:0};if(s=e(s,i),t.parentNode){let e=r(t.parentNode,"[data-auto-animate-target]");e&&(s=this.getAutoAnimateOptions(e,s))}return t.dataset.autoAnimateEasing&&(s.easing=t.dataset.autoAnimateEasing),t.dataset.autoAnimateDuration&&(s.duration=parseFloat(t.dataset.autoAnimateDuration)),t.dataset.autoAnimateDelay&&(s.delay=parseFloat(t.dataset.autoAnimateDelay)),s}getAutoAnimatableProperties(e,t,i){let s=this.Reveal.getConfig(),a={styles:[]};if(!1!==i.translate||!1!==i.scale){let e;if("function"==typeof i.measure)e=i.measure(t);else if(s.center)e=t.getBoundingClientRect();else{let i=this.Reveal.getScale();e={x:t.offsetLeft*i,y:t.offsetTop*i,width:t.offsetWidth*i,height:t.offsetHeight*i}}a.x=e.x,a.y=e.y,a.width=e.width,a.height=e.height}const n=getComputedStyle(t);return(i.styles||s.autoAnimateStyles).forEach((t=>{let i;"string"==typeof t&&(t={property:t}),i=void 0!==t.from&&"from"===e?{value:t.from,explicitValue:!0}:void 0!==t.to&&"to"===e?{value:t.to,explicitValue:!0}:n[t.property],""!==i&&(a.styles[t.property]=i)})),a}getAutoAnimatableElements(e,t){let i=("function"==typeof this.Reveal.getConfig().autoAnimateMatcher?this.Reveal.getConfig().autoAnimateMatcher:this.getAutoAnimatePairs).call(this,e,t),s=[];return i.filter(((e,t)=>{if(-1===s.indexOf(e.to))return s.push(e.to),!0}))}getAutoAnimatePairs(e,t){let i=[];const s="h1, h2, h3, h4, h5, h6, p, li";return this.findAutoAnimateMatches(i,e,t,"[data-id]",(e=>e.nodeName+":::"+e.getAttribute("data-id"))),this.findAutoAnimateMatches(i,e,t,s,(e=>e.nodeName+":::"+e.innerText)),this.findAutoAnimateMatches(i,e,t,"img, video, iframe",(e=>e.nodeName+":::"+(e.getAttribute("src")||e.getAttribute("data-src")))),this.findAutoAnimateMatches(i,e,t,"pre",(e=>e.nodeName+":::"+e.innerText)),i.forEach((e=>{n(e.from,s)?e.options={scale:!1}:n(e.from,"pre")&&(e.options={scale:!1,styles:["width","height"]},this.findAutoAnimateMatches(i,e.from,e.to,".hljs .hljs-ln-code",(e=>e.textContent),{scale:!1,styles:[],measure:this.getLocalBoundingBox.bind(this)}),this.findAutoAnimateMatches(i,e.from,e.to,".hljs .hljs-ln-line[data-line-number]",(e=>e.getAttribute("data-line-number")),{scale:!1,styles:["width"],measure:this.getLocalBoundingBox.bind(this)}))}),this),i}getLocalBoundingBox(e){const t=this.Reveal.getScale();return{x:Math.round(e.offsetLeft*t*100)/100,y:Math.round(e.offsetTop*t*100)/100,width:Math.round(e.offsetWidth*t*100)/100,height:Math.round(e.offsetHeight*t*100)/100}}findAutoAnimateMatches(e,t,i,s,a,n){let r={},o={};[].slice.call(t.querySelectorAll(s)).forEach(((e,t)=>{const i=a(e);"string"==typeof i&&i.length&&(r[i]=r[i]||[],r[i].push(e))})),[].slice.call(i.querySelectorAll(s)).forEach(((t,i)=>{const s=a(t);let l;if(o[s]=o[s]||[],o[s].push(t),r[s]){const e=o[s].length-1,t=r[s].length-1;r[s][e]?(l=r[s][e],r[s][e]=null):r[s][t]&&(l=r[s][t],r[s][t]=null)}l&&e.push({from:l,to:t,options:n})}))}getUnmatchedAutoAnimateElements(e){return[].slice.call(e.children).reduce(((e,t)=>{const i=t.querySelector("[data-auto-animate-target]");return t.hasAttribute("data-auto-animate-target")||i||e.push(t),t.querySelector("[data-auto-animate-target]")&&(e=e.concat(this.getUnmatchedAutoAnimateElements(t))),e}),[])}}class L{constructor(e){this.Reveal=e}configure(e,t){!1===e.fragments?this.disable():!1===t.fragments&&this.enable()}disable(){t(this.Reveal.getSlidesElement(),".fragment").forEach((e=>{e.classList.add("visible"),e.classList.remove("current-fragment")}))}enable(){t(this.Reveal.getSlidesElement(),".fragment").forEach((e=>{e.classList.remove("visible"),e.classList.remove("current-fragment")}))}availableRoutes(){let e=this.Reveal.getCurrentSlide();if(e&&this.Reveal.getConfig().fragments){let t=e.querySelectorAll(".fragment:not(.disabled)"),i=e.querySelectorAll(".fragment:not(.disabled):not(.visible)");return{prev:t.length-i.length>0,next:!!i.length}}return{prev:!1,next:!1}}sort(e,t=!1){e=Array.from(e);let i=[],s=[],a=[];e.forEach((e=>{if(e.hasAttribute("data-fragment-index")){let t=parseInt(e.getAttribute("data-fragment-index"),10);i[t]||(i[t]=[]),i[t].push(e)}else s.push([e])})),i=i.concat(s);let n=0;return i.forEach((e=>{e.forEach((e=>{a.push(e),e.setAttribute("data-fragment-index",n)})),n++})),!0===t?i:a}sortAll(){this.Reveal.getHorizontalSlides().forEach((e=>{let i=t(e,"section");i.forEach(((e,t)=>{this.sort(e.querySelectorAll(".fragment"))}),this),0===i.length&&this.sort(e.querySelectorAll(".fragment"))}))}update(e,t){let i={shown:[],hidden:[]},s=this.Reveal.getCurrentSlide();if(s&&this.Reveal.getConfig().fragments&&(t=t||this.sort(s.querySelectorAll(".fragment"))).length){let a=0;if("number"!=typeof e){let t=this.sort(s.querySelectorAll(".fragment.visible")).pop();t&&(e=parseInt(t.getAttribute("data-fragment-index")||0,10))}Array.from(t).forEach(((t,s)=>{if(t.hasAttribute("data-fragment-index")&&(s=parseInt(t.getAttribute("data-fragment-index"),10)),a=Math.max(a,s),s<=e){let a=t.classList.contains("visible");t.classList.add("visible"),t.classList.remove("current-fragment"),s===e&&(this.Reveal.announceStatus(this.Reveal.getStatusText(t)),t.classList.add("current-fragment"),this.Reveal.slideContent.startEmbeddedContent(t)),a||(i.shown.push(t),this.Reveal.dispatchEvent({target:t,type:"visible",bubbles:!1}))}else{let e=t.classList.contains("visible");t.classList.remove("visible"),t.classList.remove("current-fragment"),e&&(this.Reveal.slideContent.stopEmbeddedContent(t),i.hidden.push(t),this.Reveal.dispatchEvent({target:t,type:"hidden",bubbles:!1}))}})),e="number"==typeof e?e:-1,e=Math.max(Math.min(e,a),-1),s.setAttribute("data-fragment",e)}return i}sync(e=this.Reveal.getCurrentSlide()){return this.sort(e.querySelectorAll(".fragment"))}goto(e,t=0){let i=this.Reveal.getCurrentSlide();if(i&&this.Reveal.getConfig().fragments){let s=this.sort(i.querySelectorAll(".fragment:not(.disabled)"));if(s.length){if("number"!=typeof e){let t=this.sort(i.querySelectorAll(".fragment:not(.disabled).visible")).pop();e=t?parseInt(t.getAttribute("data-fragment-index")||0,10):-1}e+=t;let a=this.update(e,s);return a.hidden.length&&this.Reveal.dispatchEvent({type:"fragmenthidden",data:{fragment:a.hidden[0],fragments:a.hidden}}),a.shown.length&&this.Reveal.dispatchEvent({type:"fragmentshown",data:{fragment:a.shown[0],fragments:a.shown}}),this.Reveal.controls.update(),this.Reveal.progress.update(),this.Reveal.getConfig().fragmentInURL&&this.Reveal.location.writeURL(),!(!a.shown.length&&!a.hidden.length)}}return!1}next(){return this.goto(null,1)}prev(){return this.goto(null,-1)}}class C{constructor(e){this.Reveal=e,this.active=!1,this.onSlideClicked=this.onSlideClicked.bind(this)}activate(){if(this.Reveal.getConfig().overview&&!this.isActive()){this.active=!0,this.Reveal.getRevealElement().classList.add("overview"),this.Reveal.cancelAutoSlide(),this.Reveal.getSlidesElement().appendChild(this.Reveal.getBackgroundsElement()),t(this.Reveal.getRevealElement(),".slides section").forEach((e=>{e.classList.contains("stack")||e.addEventListener("click",this.onSlideClicked,!0)}));const e=70,i=this.Reveal.getComputedSlideSize();this.overviewSlideWidth=i.width+e,this.overviewSlideHeight=i.height+e,this.Reveal.getConfig().rtl&&(this.overviewSlideWidth=-this.overviewSlideWidth),this.Reveal.updateSlidesVisibility(),this.layout(),this.update(),this.Reveal.layout();const s=this.Reveal.getIndices();this.Reveal.dispatchEvent({type:"overviewshown",data:{indexh:s.h,indexv:s.v,currentSlide:this.Reveal.getCurrentSlide()}})}}layout(){this.Reveal.getHorizontalSlides().forEach(((e,i)=>{e.setAttribute("data-index-h",i),a(e,"translate3d("+i*this.overviewSlideWidth+"px, 0, 0)"),e.classList.contains("stack")&&t(e,"section").forEach(((e,t)=>{e.setAttribute("data-index-h",i),e.setAttribute("data-index-v",t),a(e,"translate3d(0, "+t*this.overviewSlideHeight+"px, 0)")}))})),Array.from(this.Reveal.getBackgroundsElement().childNodes).forEach(((e,i)=>{a(e,"translate3d("+i*this.overviewSlideWidth+"px, 0, 0)"),t(e,".slide-background").forEach(((e,t)=>{a(e,"translate3d(0, "+t*this.overviewSlideHeight+"px, 0)")}))}))}update(){const e=Math.min(window.innerWidth,window.innerHeight),t=Math.max(e/5,150)/e,i=this.Reveal.getIndices();this.Reveal.transformSlides({overview:["scale("+t+")","translateX("+-i.h*this.overviewSlideWidth+"px)","translateY("+-i.v*this.overviewSlideHeight+"px)"].join(" ")})}deactivate(){if(this.Reveal.getConfig().overview){this.active=!1,this.Reveal.getRevealElement().classList.remove("overview"),this.Reveal.getRevealElement().classList.add("overview-deactivating"),setTimeout((()=>{this.Reveal.getRevealElement().classList.remove("overview-deactivating")}),1),this.Reveal.getRevealElement().appendChild(this.Reveal.getBackgroundsElement()),t(this.Reveal.getRevealElement(),".slides section").forEach((e=>{a(e,""),e.removeEventListener("click",this.onSlideClicked,!0)})),t(this.Reveal.getBackgroundsElement(),".slide-background").forEach((e=>{a(e,"")})),this.Reveal.transformSlides({overview:""});const e=this.Reveal.getIndices();this.Reveal.slide(e.h,e.v),this.Reveal.layout(),this.Reveal.cueAutoSlide(),this.Reveal.dispatchEvent({type:"overviewhidden",data:{indexh:e.h,indexv:e.v,currentSlide:this.Reveal.getCurrentSlide()}})}}toggle(e){"boolean"==typeof e?e?this.activate():this.deactivate():this.isActive()?this.deactivate():this.activate()}isActive(){return this.active}onSlideClicked(e){if(this.isActive()){e.preventDefault();let t=e.target;for(;t&&!t.nodeName.match(/section/gi);)t=t.parentNode;if(t&&!t.classList.contains("disabled")&&(this.deactivate(),t.nodeName.match(/section/gi))){let e=parseInt(t.getAttribute("data-index-h"),10),i=parseInt(t.getAttribute("data-index-v"),10);this.Reveal.slide(e,i)}}}}class x{constructor(e){this.Reveal=e,this.shortcuts={},this.bindings={},this.onDocumentKeyDown=this.onDocumentKeyDown.bind(this),this.onDocumentKeyPress=this.onDocumentKeyPress.bind(this)}configure(e,t){"linear"===e.navigationMode?(this.shortcuts["→ , ↓ , SPACE , N , L , J"]="Next slide",this.shortcuts["← , ↑ , P , H , K"]="Previous slide"):(this.shortcuts["N , SPACE"]="Next slide",this.shortcuts["P , Shift SPACE"]="Previous slide",this.shortcuts["← , H"]="Navigate left",this.shortcuts["→ , L"]="Navigate right",this.shortcuts["↑ , K"]="Navigate up",this.shortcuts["↓ , J"]="Navigate down"),this.shortcuts["Alt + ←/↑/→/↓"]="Navigate without fragments",this.shortcuts["Shift + ←/↑/→/↓"]="Jump to first/last slide",this.shortcuts["B , ."]="Pause",this.shortcuts.F="Fullscreen",this.shortcuts["ESC, O"]="Slide overview"}bind(){document.addEventListener("keydown",this.onDocumentKeyDown,!1),document.addEventListener("keypress",this.onDocumentKeyPress,!1)}unbind(){document.removeEventListener("keydown",this.onDocumentKeyDown,!1),document.removeEventListener("keypress",this.onDocumentKeyPress,!1)}addKeyBinding(e,t){"object"==typeof e&&e.keyCode?this.bindings[e.keyCode]={callback:t,key:e.key,description:e.description}:this.bindings[e]={callback:t,key:null,description:null}}removeKeyBinding(e){delete this.bindings[e]}triggerKey(e){this.onDocumentKeyDown({keyCode:e})}registerKeyboardShortcut(e,t){this.shortcuts[e]=t}getShortcuts(){return this.shortcuts}getBindings(){return this.bindings}onDocumentKeyPress(e){e.shiftKey&&63===e.charCode&&this.Reveal.toggleHelp()}onDocumentKeyDown(e){let t=this.Reveal.getConfig();if("function"==typeof t.keyboardCondition&&!1===t.keyboardCondition(e))return!0;if("focused"===t.keyboardCondition&&!this.Reveal.isFocused())return!0;let i=e.keyCode,s=!this.Reveal.isAutoSliding();this.Reveal.onUserInput(e);let a=document.activeElement&&!0===document.activeElement.isContentEditable,n=document.activeElement&&document.activeElement.tagName&&/input|textarea/i.test(document.activeElement.tagName),r=document.activeElement&&document.activeElement.className&&/speaker-notes/i.test(document.activeElement.className),o=!(-1!==[32,37,38,39,40,78,80].indexOf(e.keyCode)&&e.shiftKey||e.altKey)&&(e.shiftKey||e.altKey||e.ctrlKey||e.metaKey);if(a||n||r||o)return;let l,d=[66,86,190,191];if("object"==typeof t.keyboard)for(l in t.keyboard)"togglePause"===t.keyboard[l]&&d.push(parseInt(l,10));if(this.Reveal.isPaused()&&-1===d.indexOf(i))return!1;let c="linear"===t.navigationMode||!this.Reveal.hasHorizontalSlides()||!this.Reveal.hasVerticalSlides(),h=!1;if("object"==typeof t.keyboard)for(l in t.keyboard)if(parseInt(l,10)===i){let i=t.keyboard[l];"function"==typeof i?i.apply(null,[e]):"string"==typeof i&&"function"==typeof this.Reveal[i]&&this.Reveal[i].call(),h=!0}if(!1===h)for(l in this.bindings)if(parseInt(l,10)===i){let t=this.bindings[l].callback;"function"==typeof t?t.apply(null,[e]):"string"==typeof t&&"function"==typeof this.Reveal[t]&&this.Reveal[t].call(),h=!0}!1===h&&(h=!0,80===i||33===i?this.Reveal.prev({skipFragments:e.altKey}):78===i||34===i?this.Reveal.next({skipFragments:e.altKey}):72===i||37===i?e.shiftKey?this.Reveal.slide(0):!this.Reveal.overview.isActive()&&c?this.Reveal.prev({skipFragments:e.altKey}):this.Reveal.left({skipFragments:e.altKey}):76===i||39===i?e.shiftKey?this.Reveal.slide(this.Reveal.getHorizontalSlides().length-1):!this.Reveal.overview.isActive()&&c?this.Reveal.next({skipFragments:e.altKey}):this.Reveal.right({skipFragments:e.altKey}):75===i||38===i?e.shiftKey?this.Reveal.slide(void 0,0):!this.Reveal.overview.isActive()&&c?this.Reveal.prev({skipFragments:e.altKey}):this.Reveal.up({skipFragments:e.altKey}):74===i||40===i?e.shiftKey?this.Reveal.slide(void 0,Number.MAX_VALUE):!this.Reveal.overview.isActive()&&c?this.Reveal.next({skipFragments:e.altKey}):this.Reveal.down({skipFragments:e.altKey}):36===i?this.Reveal.slide(0):35===i?this.Reveal.slide(this.Reveal.getHorizontalSlides().length-1):32===i?(this.Reveal.overview.isActive()&&this.Reveal.overview.deactivate(),e.shiftKey?this.Reveal.prev({skipFragments:e.altKey}):this.Reveal.next({skipFragments:e.altKey})):58===i||59===i||66===i||86===i||190===i||191===i?this.Reveal.togglePause():70===i?(e=>{let t=(e=e||document.documentElement).requestFullscreen||e.webkitRequestFullscreen||e.webkitRequestFullScreen||e.mozRequestFullScreen||e.msRequestFullscreen;t&&t.apply(e)})(t.embedded?this.Reveal.getViewportElement():document.documentElement):65===i?t.autoSlideStoppable&&this.Reveal.toggleAutoSlide(s):h=!1),h?e.preventDefault&&e.preventDefault():27!==i&&79!==i||(!1===this.Reveal.closeOverlay()&&this.Reveal.overview.toggle(),e.preventDefault&&e.preventDefault()),this.Reveal.cueAutoSlide()}}class P{constructor(e){var t,i,s;s=1e3,(i="MAX_REPLACE_STATE_FREQUENCY")in(t=this)?Object.defineProperty(t,i,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[i]=s,this.Reveal=e,this.writeURLTimeout=0,this.replaceStateTimestamp=0,this.onWindowHashChange=this.onWindowHashChange.bind(this)}bind(){window.addEventListener("hashchange",this.onWindowHashChange,!1)}unbind(){window.removeEventListener("hashchange",this.onWindowHashChange,!1)}getIndicesFromHash(e=window.location.hash){let t=e.replace(/^#\/?/,""),i=t.split("/");if(/^[0-9]*$/.test(i[0])||!t.length){const e=this.Reveal.getConfig();let t,s=e.hashOneBasedIndex?1:0,a=parseInt(i[0],10)-s||0,n=parseInt(i[1],10)-s||0;return e.fragmentInURL&&(t=parseInt(i[2],10),isNaN(t)&&(t=void 0)),{h:a,v:n,f:t}}{let e,i;/\/[-\d]+$/g.test(t)&&(i=parseInt(t.split("/").pop(),10),i=isNaN(i)?void 0:i,t=t.split("/").shift());try{e=document.getElementById(decodeURIComponent(t))}catch(e){}if(e)return{...this.Reveal.getIndices(e),f:i}}return null}readURL(){const e=this.Reveal.getIndices(),t=this.getIndicesFromHash();t?t.h===e.h&&t.v===e.v&&void 0===t.f||this.Reveal.slide(t.h,t.v,t.f):this.Reveal.slide(e.h||0,e.v||0)}writeURL(e){let t=this.Reveal.getConfig(),i=this.Reveal.getCurrentSlide();if(clearTimeout(this.writeURLTimeout),"number"==typeof e)this.writeURLTimeout=setTimeout(this.writeURL,e);else if(i){let e=this.getHash();t.history?window.location.hash=e:t.hash&&("/"===e?this.debouncedReplaceState(window.location.pathname+window.location.search):this.debouncedReplaceState("#"+e))}}replaceState(e){window.history.replaceState(null,null,e),this.replaceStateTimestamp=Date.now()}debouncedReplaceState(e){clearTimeout(this.replaceStateTimeout),Date.now()-this.replaceStateTimestamp>this.MAX_REPLACE_STATE_FREQUENCY?this.replaceState(e):this.replaceStateTimeout=setTimeout((()=>this.replaceState(e)),this.MAX_REPLACE_STATE_FREQUENCY)}getHash(e){let t="/",i=e||this.Reveal.getCurrentSlide(),s=i?i.getAttribute("id"):null;s&&(s=encodeURIComponent(s));let a=this.Reveal.getIndices(e);if(this.Reveal.getConfig().fragmentInURL||(a.f=void 0),"string"==typeof s&&s.length)t="/"+s,a.f>=0&&(t+="/"+a.f);else{let e=this.Reveal.getConfig().hashOneBasedIndex?1:0;(a.h>0||a.v>0||a.f>=0)&&(t+=a.h+e),(a.v>0||a.f>=0)&&(t+="/"+(a.v+e)),a.f>=0&&(t+="/"+a.f)}return t}onWindowHashChange(e){this.readURL()}}class N{constructor(e){this.Reveal=e,this.onNavigateLeftClicked=this.onNavigateLeftClicked.bind(this),this.onNavigateRightClicked=this.onNavigateRightClicked.bind(this),this.onNavigateUpClicked=this.onNavigateUpClicked.bind(this),this.onNavigateDownClicked=this.onNavigateDownClicked.bind(this),this.onNavigatePrevClicked=this.onNavigatePrevClicked.bind(this),this.onNavigateNextClicked=this.onNavigateNextClicked.bind(this)}render(){const e=this.Reveal.getConfig().rtl,i=this.Reveal.getRevealElement();this.element=document.createElement("aside"),this.element.className="controls",this.element.innerHTML=`
\n\t\t\t
\n\t\t\t
\n\t\t\t
`,this.Reveal.getRevealElement().appendChild(this.element),this.controlsLeft=t(i,".navigate-left"),this.controlsRight=t(i,".navigate-right"),this.controlsUp=t(i,".navigate-up"),this.controlsDown=t(i,".navigate-down"),this.controlsPrev=t(i,".navigate-prev"),this.controlsNext=t(i,".navigate-next"),this.controlsRightArrow=this.element.querySelector(".navigate-right"),this.controlsLeftArrow=this.element.querySelector(".navigate-left"),this.controlsDownArrow=this.element.querySelector(".navigate-down")}configure(e,t){this.element.style.display=e.controls?"block":"none",this.element.setAttribute("data-controls-layout",e.controlsLayout),this.element.setAttribute("data-controls-back-arrows",e.controlsBackArrows)}bind(){let e=["touchstart","click"];v&&(e=["touchstart"]),e.forEach((e=>{this.controlsLeft.forEach((t=>t.addEventListener(e,this.onNavigateLeftClicked,!1))),this.controlsRight.forEach((t=>t.addEventListener(e,this.onNavigateRightClicked,!1))),this.controlsUp.forEach((t=>t.addEventListener(e,this.onNavigateUpClicked,!1))),this.controlsDown.forEach((t=>t.addEventListener(e,this.onNavigateDownClicked,!1))),this.controlsPrev.forEach((t=>t.addEventListener(e,this.onNavigatePrevClicked,!1))),this.controlsNext.forEach((t=>t.addEventListener(e,this.onNavigateNextClicked,!1)))}))}unbind(){["touchstart","click"].forEach((e=>{this.controlsLeft.forEach((t=>t.removeEventListener(e,this.onNavigateLeftClicked,!1))),this.controlsRight.forEach((t=>t.removeEventListener(e,this.onNavigateRightClicked,!1))),this.controlsUp.forEach((t=>t.removeEventListener(e,this.onNavigateUpClicked,!1))),this.controlsDown.forEach((t=>t.removeEventListener(e,this.onNavigateDownClicked,!1))),this.controlsPrev.forEach((t=>t.removeEventListener(e,this.onNavigatePrevClicked,!1))),this.controlsNext.forEach((t=>t.removeEventListener(e,this.onNavigateNextClicked,!1)))}))}update(){let e=this.Reveal.availableRoutes();[...this.controlsLeft,...this.controlsRight,...this.controlsUp,...this.controlsDown,...this.controlsPrev,...this.controlsNext].forEach((e=>{e.classList.remove("enabled","fragmented"),e.setAttribute("disabled","disabled")})),e.left&&this.controlsLeft.forEach((e=>{e.classList.add("enabled"),e.removeAttribute("disabled")})),e.right&&this.controlsRight.forEach((e=>{e.classList.add("enabled"),e.removeAttribute("disabled")})),e.up&&this.controlsUp.forEach((e=>{e.classList.add("enabled"),e.removeAttribute("disabled")})),e.down&&this.controlsDown.forEach((e=>{e.classList.add("enabled"),e.removeAttribute("disabled")})),(e.left||e.up)&&this.controlsPrev.forEach((e=>{e.classList.add("enabled"),e.removeAttribute("disabled")})),(e.right||e.down)&&this.controlsNext.forEach((e=>{e.classList.add("enabled"),e.removeAttribute("disabled")}));let t=this.Reveal.getCurrentSlide();if(t){let e=this.Reveal.fragments.availableRoutes();e.prev&&this.controlsPrev.forEach((e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")})),e.next&&this.controlsNext.forEach((e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")})),this.Reveal.isVerticalSlide(t)?(e.prev&&this.controlsUp.forEach((e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")})),e.next&&this.controlsDown.forEach((e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")}))):(e.prev&&this.controlsLeft.forEach((e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")})),e.next&&this.controlsRight.forEach((e=>{e.classList.add("fragmented","enabled"),e.removeAttribute("disabled")})))}if(this.Reveal.getConfig().controlsTutorial){let t=this.Reveal.getIndices();!this.Reveal.hasNavigatedVertically()&&e.down?this.controlsDownArrow.classList.add("highlight"):(this.controlsDownArrow.classList.remove("highlight"),this.Reveal.getConfig().rtl?!this.Reveal.hasNavigatedHorizontally()&&e.left&&0===t.v?this.controlsLeftArrow.classList.add("highlight"):this.controlsLeftArrow.classList.remove("highlight"):!this.Reveal.hasNavigatedHorizontally()&&e.right&&0===t.v?this.controlsRightArrow.classList.add("highlight"):this.controlsRightArrow.classList.remove("highlight"))}}destroy(){this.unbind(),this.element.remove()}onNavigateLeftClicked(e){e.preventDefault(),this.Reveal.onUserInput(),"linear"===this.Reveal.getConfig().navigationMode?this.Reveal.prev():this.Reveal.left()}onNavigateRightClicked(e){e.preventDefault(),this.Reveal.onUserInput(),"linear"===this.Reveal.getConfig().navigationMode?this.Reveal.next():this.Reveal.right()}onNavigateUpClicked(e){e.preventDefault(),this.Reveal.onUserInput(),this.Reveal.up()}onNavigateDownClicked(e){e.preventDefault(),this.Reveal.onUserInput(),this.Reveal.down()}onNavigatePrevClicked(e){e.preventDefault(),this.Reveal.onUserInput(),this.Reveal.prev()}onNavigateNextClicked(e){e.preventDefault(),this.Reveal.onUserInput(),this.Reveal.next()}}class M{constructor(e){this.Reveal=e,this.onProgressClicked=this.onProgressClicked.bind(this)}render(){this.element=document.createElement("div"),this.element.className="progress",this.Reveal.getRevealElement().appendChild(this.element),this.bar=document.createElement("span"),this.element.appendChild(this.bar)}configure(e,t){this.element.style.display=e.progress?"block":"none"}bind(){this.Reveal.getConfig().progress&&this.element&&this.element.addEventListener("click",this.onProgressClicked,!1)}unbind(){this.Reveal.getConfig().progress&&this.element&&this.element.removeEventListener("click",this.onProgressClicked,!1)}update(){if(this.Reveal.getConfig().progress&&this.bar){let e=this.Reveal.getProgress();this.Reveal.getTotalSlides()<2&&(e=0),this.bar.style.transform="scaleX("+e+")"}}getMaxWidth(){return this.Reveal.getRevealElement().offsetWidth}onProgressClicked(e){this.Reveal.onUserInput(e),e.preventDefault();let t=this.Reveal.getSlides(),i=t.length,s=Math.floor(e.clientX/this.getMaxWidth()*i);this.Reveal.getConfig().rtl&&(s=i-s);let a=this.Reveal.getIndices(t[s]);this.Reveal.slide(a.h,a.v)}destroy(){this.element.remove()}}class D{constructor(e){this.Reveal=e,this.lastMouseWheelStep=0,this.cursorHidden=!1,this.cursorInactiveTimeout=0,this.onDocumentCursorActive=this.onDocumentCursorActive.bind(this),this.onDocumentMouseScroll=this.onDocumentMouseScroll.bind(this)}configure(e,t){e.mouseWheel?(document.addEventListener("DOMMouseScroll",this.onDocumentMouseScroll,!1),document.addEventListener("mousewheel",this.onDocumentMouseScroll,!1)):(document.removeEventListener("DOMMouseScroll",this.onDocumentMouseScroll,!1),document.removeEventListener("mousewheel",this.onDocumentMouseScroll,!1)),e.hideInactiveCursor?(document.addEventListener("mousemove",this.onDocumentCursorActive,!1),document.addEventListener("mousedown",this.onDocumentCursorActive,!1)):(this.showCursor(),document.removeEventListener("mousemove",this.onDocumentCursorActive,!1),document.removeEventListener("mousedown",this.onDocumentCursorActive,!1))}showCursor(){this.cursorHidden&&(this.cursorHidden=!1,this.Reveal.getRevealElement().style.cursor="")}hideCursor(){!1===this.cursorHidden&&(this.cursorHidden=!0,this.Reveal.getRevealElement().style.cursor="none")}destroy(){this.showCursor(),document.removeEventListener("DOMMouseScroll",this.onDocumentMouseScroll,!1),document.removeEventListener("mousewheel",this.onDocumentMouseScroll,!1),document.removeEventListener("mousemove",this.onDocumentCursorActive,!1),document.removeEventListener("mousedown",this.onDocumentCursorActive,!1)}onDocumentCursorActive(e){this.showCursor(),clearTimeout(this.cursorInactiveTimeout),this.cursorInactiveTimeout=setTimeout(this.hideCursor.bind(this),this.Reveal.getConfig().hideCursorTime)}onDocumentMouseScroll(e){if(Date.now()-this.lastMouseWheelStep>1e3){this.lastMouseWheelStep=Date.now();let t=e.detail||-e.wheelDelta;t>0?this.Reveal.next():t<0&&this.Reveal.prev()}}}const I=(e,t)=>{const i=document.createElement("script");i.type="text/javascript",i.async=!1,i.defer=!1,i.src=e,"function"==typeof t&&(i.onload=i.onreadystatechange=e=>{("load"===e.type||/loaded|complete/.test(i.readyState))&&(i.onload=i.onreadystatechange=i.onerror=null,t())},i.onerror=e=>{i.onload=i.onreadystatechange=i.onerror=null,t(new Error("Failed loading script: "+i.src+"\n"+e))});const s=document.querySelector("head");s.insertBefore(i,s.lastChild)};class T{constructor(e){this.Reveal=e,this.state="idle",this.registeredPlugins={},this.asyncDependencies=[]}load(e,t){return this.state="loading",e.forEach(this.registerPlugin.bind(this)),new Promise((e=>{let i=[],s=0;if(t.forEach((e=>{e.condition&&!e.condition()||(e.async?this.asyncDependencies.push(e):i.push(e))})),i.length){s=i.length;const t=t=>{t&&"function"==typeof t.callback&&t.callback(),0==--s&&this.initPlugins().then(e)};i.forEach((e=>{"string"==typeof e.id?(this.registerPlugin(e),t(e)):"string"==typeof e.src?I(e.src,(()=>t(e))):(console.warn("Unrecognized plugin format",e),t())}))}else this.initPlugins().then(e)}))}initPlugins(){return new Promise((e=>{let t=Object.values(this.registeredPlugins),i=t.length;if(0===i)this.loadAsync().then(e);else{let s,a=()=>{0==--i?this.loadAsync().then(e):s()},n=0;s=()=>{let e=t[n++];if("function"==typeof e.init){let t=e.init(this.Reveal);t&&"function"==typeof t.then?t.then(a):a()}else a()},s()}}))}loadAsync(){return this.state="loaded",this.asyncDependencies.length&&this.asyncDependencies.forEach((e=>{I(e.src,e.callback)})),Promise.resolve()}registerPlugin(e){2===arguments.length&&"string"==typeof arguments[0]?(e=arguments[1]).id=arguments[0]:"function"==typeof e&&(e=e());let t=e.id;"string"!=typeof t?console.warn("Unrecognized plugin format; can't find plugin.id",e):void 0===this.registeredPlugins[t]?(this.registeredPlugins[t]=e,"loaded"===this.state&&"function"==typeof e.init&&e.init(this.Reveal)):console.warn('reveal.js: "'+t+'" plugin has already been registered')}hasPlugin(e){return!!this.registeredPlugins[e]}getPlugin(e){return this.registeredPlugins[e]}getRegisteredPlugins(){return this.registeredPlugins}destroy(){Object.values(this.registeredPlugins).forEach((e=>{"function"==typeof e.destroy&&e.destroy()})),this.registeredPlugins={},this.asyncDependencies=[]}}class F{constructor(e){this.Reveal=e}async setupPDF(){const e=this.Reveal.getConfig(),i=t(this.Reveal.getRevealElement(),".slides section"),s=e.slideNumber&&/all|print/i.test(e.showSlideNumber),a=this.Reveal.getComputedSlideSize(window.innerWidth,window.innerHeight),n=Math.floor(a.width*(1+e.margin)),r=Math.floor(a.height*(1+e.margin)),o=a.width,d=a.height;await new Promise(requestAnimationFrame),l("@page{size:"+n+"px "+r+"px; margin: 0px;}"),l(".reveal section>img, .reveal section>video, .reveal section>iframe{max-width: "+o+"px; max-height:"+d+"px}"),document.documentElement.classList.add("print-pdf"),document.body.style.width=n+"px",document.body.style.height=r+"px";const c=document.querySelector(".reveal-viewport");let h;if(c){const e=window.getComputedStyle(c);e&&e.background&&(h=e.background)}await new Promise(requestAnimationFrame),this.Reveal.layoutSlideContents(o,d),await new Promise(requestAnimationFrame);const u=i.map((e=>e.scrollHeight)),g=[],v=i[0].parentNode;i.forEach((function(i,a){if(!1===i.classList.contains("stack")){let l=(n-o)/2,c=(r-d)/2;const v=u[a];let p=Math.max(Math.ceil(v/r),1);p=Math.min(p,e.pdfMaxPagesPerSlide),(1===p&&e.center||i.classList.contains("center"))&&(c=Math.max((r-v)/2,0));const m=document.createElement("div");if(g.push(m),m.className="pdf-page",m.style.height=(r+e.pdfPageHeightOffset)*p+"px",h&&(m.style.background=h),m.appendChild(i),i.style.left=l+"px",i.style.top=c+"px",i.style.width=o+"px",this.Reveal.slideContent.layout(i),i.slideBackgroundElement&&m.insertBefore(i.slideBackgroundElement,i),e.showNotes){const t=this.Reveal.getSlideNotes(i);if(t){const i=8,s="string"==typeof e.showNotes?e.showNotes:"inline",a=document.createElement("div");a.classList.add("speaker-notes"),a.classList.add("speaker-notes-pdf"),a.setAttribute("data-layout",s),a.innerHTML=t,"separate-page"===s?g.push(a):(a.style.left=i+"px",a.style.bottom=i+"px",a.style.width=n-2*i+"px",m.appendChild(a))}}if(s){const e=a+1,t=document.createElement("div");t.classList.add("slide-number"),t.classList.add("slide-number-pdf"),t.innerHTML=e,m.appendChild(t)}if(e.pdfSeparateFragments){const e=this.Reveal.fragments.sort(m.querySelectorAll(".fragment"),!0);let t;e.forEach((function(e){t&&t.forEach((function(e){e.classList.remove("current-fragment")})),e.forEach((function(e){e.classList.add("visible","current-fragment")}),this);const i=m.cloneNode(!0);g.push(i),t=e}),this),e.forEach((function(e){e.forEach((function(e){e.classList.remove("visible","current-fragment")}))}))}else t(m,".fragment:not(.fade-out)").forEach((function(e){e.classList.add("visible")}))}}),this),await new Promise(requestAnimationFrame),g.forEach((e=>v.appendChild(e))),this.Reveal.dispatchEvent({type:"pdf-ready"})}isPrintingPDF(){return/print-pdf/gi.test(window.location.search)}}class z{constructor(e){this.Reveal=e,this.touchStartX=0,this.touchStartY=0,this.touchStartCount=0,this.touchCaptured=!1,this.onPointerDown=this.onPointerDown.bind(this),this.onPointerMove=this.onPointerMove.bind(this),this.onPointerUp=this.onPointerUp.bind(this),this.onTouchStart=this.onTouchStart.bind(this),this.onTouchMove=this.onTouchMove.bind(this),this.onTouchEnd=this.onTouchEnd.bind(this)}bind(){let e=this.Reveal.getRevealElement();"onpointerdown"in window?(e.addEventListener("pointerdown",this.onPointerDown,!1),e.addEventListener("pointermove",this.onPointerMove,!1),e.addEventListener("pointerup",this.onPointerUp,!1)):window.navigator.msPointerEnabled?(e.addEventListener("MSPointerDown",this.onPointerDown,!1),e.addEventListener("MSPointerMove",this.onPointerMove,!1),e.addEventListener("MSPointerUp",this.onPointerUp,!1)):(e.addEventListener("touchstart",this.onTouchStart,!1),e.addEventListener("touchmove",this.onTouchMove,!1),e.addEventListener("touchend",this.onTouchEnd,!1))}unbind(){let e=this.Reveal.getRevealElement();e.removeEventListener("pointerdown",this.onPointerDown,!1),e.removeEventListener("pointermove",this.onPointerMove,!1),e.removeEventListener("pointerup",this.onPointerUp,!1),e.removeEventListener("MSPointerDown",this.onPointerDown,!1),e.removeEventListener("MSPointerMove",this.onPointerMove,!1),e.removeEventListener("MSPointerUp",this.onPointerUp,!1),e.removeEventListener("touchstart",this.onTouchStart,!1),e.removeEventListener("touchmove",this.onTouchMove,!1),e.removeEventListener("touchend",this.onTouchEnd,!1)}isSwipePrevented(e){if(n(e,"video, audio"))return!0;for(;e&&"function"==typeof e.hasAttribute;){if(e.hasAttribute("data-prevent-swipe"))return!0;e=e.parentNode}return!1}onTouchStart(e){if(this.isSwipePrevented(e.target))return!0;this.touchStartX=e.touches[0].clientX,this.touchStartY=e.touches[0].clientY,this.touchStartCount=e.touches.length}onTouchMove(e){if(this.isSwipePrevented(e.target))return!0;let t=this.Reveal.getConfig();if(this.touchCaptured)v&&e.preventDefault();else{this.Reveal.onUserInput(e);let i=e.touches[0].clientX,s=e.touches[0].clientY;if(1===e.touches.length&&2!==this.touchStartCount){let a=this.Reveal.availableRoutes({includeFragments:!0}),n=i-this.touchStartX,r=s-this.touchStartY;n>40&&Math.abs(n)>Math.abs(r)?(this.touchCaptured=!0,"linear"===t.navigationMode?t.rtl?this.Reveal.next():this.Reveal.prev():this.Reveal.left()):n<-40&&Math.abs(n)>Math.abs(r)?(this.touchCaptured=!0,"linear"===t.navigationMode?t.rtl?this.Reveal.prev():this.Reveal.next():this.Reveal.right()):r>40&&a.up?(this.touchCaptured=!0,"linear"===t.navigationMode?this.Reveal.prev():this.Reveal.up()):r<-40&&a.down&&(this.touchCaptured=!0,"linear"===t.navigationMode?this.Reveal.next():this.Reveal.down()),t.embedded?(this.touchCaptured||this.Reveal.isVerticalSlide())&&e.preventDefault():e.preventDefault()}}}onTouchEnd(e){this.touchCaptured=!1}onPointerDown(e){e.pointerType!==e.MSPOINTER_TYPE_TOUCH&&"touch"!==e.pointerType||(e.touches=[{clientX:e.clientX,clientY:e.clientY}],this.onTouchStart(e))}onPointerMove(e){e.pointerType!==e.MSPOINTER_TYPE_TOUCH&&"touch"!==e.pointerType||(e.touches=[{clientX:e.clientX,clientY:e.clientY}],this.onTouchMove(e))}onPointerUp(e){e.pointerType!==e.MSPOINTER_TYPE_TOUCH&&"touch"!==e.pointerType||(e.touches=[{clientX:e.clientX,clientY:e.clientY}],this.onTouchEnd(e))}}class H{constructor(e){this.Reveal=e,this.onRevealPointerDown=this.onRevealPointerDown.bind(this),this.onDocumentPointerDown=this.onDocumentPointerDown.bind(this)}configure(e,t){e.embedded?this.blur():(this.focus(),this.unbind())}bind(){this.Reveal.getConfig().embedded&&this.Reveal.getRevealElement().addEventListener("pointerdown",this.onRevealPointerDown,!1)}unbind(){this.Reveal.getRevealElement().removeEventListener("pointerdown",this.onRevealPointerDown,!1),document.removeEventListener("pointerdown",this.onDocumentPointerDown,!1)}focus(){"focus"!==this.state&&(this.Reveal.getRevealElement().classList.add("focused"),document.addEventListener("pointerdown",this.onDocumentPointerDown,!1)),this.state="focus"}blur(){"blur"!==this.state&&(this.Reveal.getRevealElement().classList.remove("focused"),document.removeEventListener("pointerdown",this.onDocumentPointerDown,!1)),this.state="blur"}isFocused(){return"focus"===this.state}destroy(){this.Reveal.getRevealElement().classList.remove("focused")}onRevealPointerDown(e){this.focus()}onDocumentPointerDown(e){let t=r(e.target,".reveal");t&&t===this.Reveal.getRevealElement()||this.blur()}}class q{constructor(e){this.Reveal=e}render(){this.element=document.createElement("div"),this.element.className="speaker-notes",this.element.setAttribute("data-prevent-swipe",""),this.element.setAttribute("tabindex","0"),this.Reveal.getRevealElement().appendChild(this.element)}configure(e,t){e.showNotes&&this.element.setAttribute("data-layout","string"==typeof e.showNotes?e.showNotes:"inline")}update(){this.Reveal.getConfig().showNotes&&this.element&&this.Reveal.getCurrentSlide()&&!this.Reveal.print.isPrintingPDF()&&(this.element.innerHTML=this.getSlideNotes()||'No notes on this slide. ')}updateVisibility(){this.Reveal.getConfig().showNotes&&this.hasNotes()&&!this.Reveal.print.isPrintingPDF()?this.Reveal.getRevealElement().classList.add("show-notes"):this.Reveal.getRevealElement().classList.remove("show-notes")}hasNotes(){return this.Reveal.getSlidesElement().querySelectorAll("[data-notes], aside.notes").length>0}isSpeakerNotesWindow(){return!!window.location.search.match(/receiver/gi)}getSlideNotes(e=this.Reveal.getCurrentSlide()){if(e.hasAttribute("data-notes"))return e.getAttribute("data-notes");let t=e.querySelector("aside.notes");return t?t.innerHTML:null}destroy(){this.element.remove()}}class B{constructor(e,t){this.diameter=100,this.diameter2=this.diameter/2,this.thickness=6,this.playing=!1,this.progress=0,this.progressOffset=1,this.container=e,this.progressCheck=t,this.canvas=document.createElement("canvas"),this.canvas.className="playback",this.canvas.width=this.diameter,this.canvas.height=this.diameter,this.canvas.style.width=this.diameter2+"px",this.canvas.style.height=this.diameter2+"px",this.context=this.canvas.getContext("2d"),this.container.appendChild(this.canvas),this.render()}setPlaying(e){const t=this.playing;this.playing=e,!t&&this.playing?this.animate():this.render()}animate(){const e=this.progress;this.progress=this.progressCheck(),e>.8&&this.progress<.2&&(this.progressOffset=this.progress),this.render(),this.playing&&requestAnimationFrame(this.animate.bind(this))}render(){let e=this.playing?this.progress:0,t=this.diameter2-this.thickness,i=this.diameter2,s=this.diameter2,a=28;this.progressOffset+=.1*(1-this.progressOffset);const n=-Math.PI/2+e*(2*Math.PI),r=-Math.PI/2+this.progressOffset*(2*Math.PI);this.context.save(),this.context.clearRect(0,0,this.diameter,this.diameter),this.context.beginPath(),this.context.arc(i,s,t+4,0,2*Math.PI,!1),this.context.fillStyle="rgba( 0, 0, 0, 0.4 )",this.context.fill(),this.context.beginPath(),this.context.arc(i,s,t,0,2*Math.PI,!1),this.context.lineWidth=this.thickness,this.context.strokeStyle="rgba( 255, 255, 255, 0.2 )",this.context.stroke(),this.playing&&(this.context.beginPath(),this.context.arc(i,s,t,r,n,!1),this.context.lineWidth=this.thickness,this.context.strokeStyle="#fff",this.context.stroke()),this.context.translate(i-14,s-14),this.playing?(this.context.fillStyle="#fff",this.context.fillRect(0,0,10,a),this.context.fillRect(18,0,10,a)):(this.context.beginPath(),this.context.translate(4,0),this.context.moveTo(0,0),this.context.lineTo(24,14),this.context.lineTo(0,a),this.context.fillStyle="#fff",this.context.fill()),this.context.restore()}on(e,t){this.canvas.addEventListener(e,t,!1)}off(e,t){this.canvas.removeEventListener(e,t,!1)}destroy(){this.playing=!1,this.canvas.parentNode&&this.container.removeChild(this.canvas)}}var O={width:960,height:700,margin:.04,minScale:.2,maxScale:2,controls:!0,controlsTutorial:!0,controlsLayout:"bottom-right",controlsBackArrows:"faded",progress:!0,slideNumber:!1,showSlideNumber:"all",hashOneBasedIndex:!1,hash:!1,respondToHashChanges:!0,history:!1,keyboard:!0,keyboardCondition:null,disableLayout:!1,overview:!0,center:!0,touch:!0,loop:!1,rtl:!1,navigationMode:"default",shuffle:!1,fragments:!0,fragmentInURL:!0,embedded:!1,help:!0,pause:!0,showNotes:!1,showHiddenSlides:!1,autoPlayMedia:null,preloadIframes:null,autoAnimate:!0,autoAnimateMatcher:null,autoAnimateEasing:"ease",autoAnimateDuration:1,autoAnimateUnmatched:!0,autoAnimateStyles:["opacity","color","background-color","padding","font-size","line-height","letter-spacing","border-width","border-color","border-radius","outline","outline-offset"],autoSlide:0,autoSlideStoppable:!0,autoSlideMethod:null,defaultTiming:null,mouseWheel:!1,previewLinks:!1,postMessage:!0,postMessageEvents:!1,focusBodyOnPageVisibilityChange:!0,transition:"slide",transitionSpeed:"default",backgroundTransition:"fade",parallaxBackgroundImage:"",parallaxBackgroundSize:"",parallaxBackgroundRepeat:"",parallaxBackgroundPosition:"",parallaxBackgroundHorizontal:null,parallaxBackgroundVertical:null,pdfMaxPagesPerSlide:Number.POSITIVE_INFINITY,pdfSeparateFragments:!0,pdfPageHeightOffset:-1,viewDistance:3,mobileViewDistance:2,display:"block",hideInactiveCursor:!0,hideCursorTime:5e3,dependencies:[],plugins:[]};function U(n,l){arguments.length<2&&(l=arguments[0],n=document.querySelector(".reveal"));const h={};let u,v,p,m,f,w={},S=!1,A={hasNavigatedHorizontally:!1,hasNavigatedVertically:!1},I=[],U=1,W={layout:"",overview:""},K={},V="idle",$=0,j=0,X=-1,Y=!1,_=new b(h),J=new y(h),Q=new k(h),Z=new E(h),G=new L(h),ee=new C(h),te=new x(h),ie=new P(h),se=new N(h),ae=new M(h),ne=new D(h),re=new T(h),oe=new F(h),le=new H(h),de=new z(h),ce=new q(h);function he(e){if(!n)throw'Unable to find presentation root ().';if(K.wrapper=n,K.slides=n.querySelector(".slides"),!K.slides)throw'Unable to find slides container (
).';return w={...O,...w,...l,...e,...d()},ue(),window.addEventListener("load",He,!1),re.load(w.plugins,w.dependencies).then(ge),new Promise((e=>h.on("ready",e)))}function ue(){!0===w.embedded?K.viewport=r(n,".reveal-viewport")||n:(K.viewport=document.body,document.documentElement.classList.add("reveal-full-page")),K.viewport.classList.add("reveal-viewport")}function ge(){S=!0,ve(),pe(),Ee(),ye(),we(),tt(),Re(),ie.readURL(),Z.update(!0),setTimeout((()=>{K.slides.classList.remove("no-transition"),K.wrapper.classList.add("ready"),Pe({type:"ready",data:{indexh:u,indexv:v,currentSlide:m}})}),1),oe.isPrintingPDF()&&(Ae(),"complete"===document.readyState?oe.setupPDF():window.addEventListener("load",(()=>{oe.setupPDF()})))}function ve(){w.showHiddenSlides||t(K.wrapper,'section[data-visibility="hidden"]').forEach((e=>{e.parentNode.removeChild(e)}))}function pe(){K.slides.classList.add("no-transition"),g?K.wrapper.classList.add("no-hover"):K.wrapper.classList.remove("no-hover"),Z.render(),J.render(),se.render(),ae.render(),ce.render(),K.pauseOverlay=o(K.wrapper,"div","pause-overlay",w.controls?'
Resume presentation ':null),K.statusElement=me(),K.wrapper.setAttribute("role","application")}function me(){let e=K.wrapper.querySelector(".aria-status");return e||(e=document.createElement("div"),e.style.position="absolute",e.style.height="1px",e.style.width="1px",e.style.overflow="hidden",e.style.clip="rect( 1px, 1px, 1px, 1px )",e.classList.add("aria-status"),e.setAttribute("aria-live","polite"),e.setAttribute("aria-atomic","true"),K.wrapper.appendChild(e)),e}function fe(e){K.statusElement.textContent=e}function be(e){let t="";if(3===e.nodeType)t+=e.textContent;else if(1===e.nodeType){let i=e.getAttribute("aria-hidden"),s="none"===window.getComputedStyle(e).display;"true"===i||s||Array.from(e.childNodes).forEach((e=>{t+=be(e)}))}return t=t.trim(),""===t?"":t+" "}function ye(){setInterval((()=>{0===K.wrapper.scrollTop&&0===K.wrapper.scrollLeft||(K.wrapper.scrollTop=0,K.wrapper.scrollLeft=0)}),1e3)}function we(){document.addEventListener("fullscreenchange",Ht),document.addEventListener("webkitfullscreenchange",Ht)}function Ee(){w.postMessage&&window.addEventListener("message",Dt,!1)}function Re(t){const s={...w};if("object"==typeof t&&e(w,t),!1===h.isReady())return;const a=K.wrapper.querySelectorAll(".slides section").length;K.wrapper.classList.remove(s.transition),K.wrapper.classList.add(w.transition),K.wrapper.setAttribute("data-transition-speed",w.transitionSpeed),K.wrapper.setAttribute("data-background-transition",w.backgroundTransition),K.viewport.style.setProperty("--slide-width",w.width+"px"),K.viewport.style.setProperty("--slide-height",w.height+"px"),w.shuffle&&it(),i(K.wrapper,"embedded",w.embedded),i(K.wrapper,"rtl",w.rtl),i(K.wrapper,"center",w.center),!1===w.pause&&Xe(),w.previewLinks?(Me(),De("[data-preview-link=false]")):(De(),Me("[data-preview-link]:not([data-preview-link=false])")),Q.reset(),f&&(f.destroy(),f=null),a>1&&w.autoSlide&&w.autoSlideStoppable&&(f=new B(K.wrapper,(()=>Math.min(Math.max((Date.now()-X)/$,0),1))),f.on("click",Bt),Y=!1),"default"!==w.navigationMode?K.wrapper.setAttribute("data-navigation-mode",w.navigationMode):K.wrapper.removeAttribute("data-navigation-mode"),ce.configure(w,s),le.configure(w,s),ne.configure(w,s),se.configure(w,s),ae.configure(w,s),te.configure(w,s),G.configure(w,s),J.configure(w,s),Ge()}function Se(){window.addEventListener("resize",Ft,!1),w.touch&&de.bind(),w.keyboard&&te.bind(),w.progress&&ae.bind(),w.respondToHashChanges&&ie.bind(),se.bind(),le.bind(),K.slides.addEventListener("click",Tt,!1),K.slides.addEventListener("transitionend",It,!1),K.pauseOverlay.addEventListener("click",Xe,!1),w.focusBodyOnPageVisibilityChange&&document.addEventListener("visibilitychange",zt,!1)}function Ae(){de.unbind(),le.unbind(),te.unbind(),se.unbind(),ae.unbind(),ie.unbind(),window.removeEventListener("resize",Ft,!1),K.slides.removeEventListener("click",Tt,!1),K.slides.removeEventListener("transitionend",It,!1),K.pauseOverlay.removeEventListener("click",Xe,!1)}function ke(){Ae(),Rt(),De(),ce.destroy(),le.destroy(),re.destroy(),ne.destroy(),se.destroy(),ae.destroy(),Z.destroy(),J.destroy(),document.removeEventListener("fullscreenchange",Ht),document.removeEventListener("webkitfullscreenchange",Ht),document.removeEventListener("visibilitychange",zt,!1),window.removeEventListener("message",Dt,!1),window.removeEventListener("load",He,!1),K.pauseOverlay&&K.pauseOverlay.remove(),K.statusElement&&K.statusElement.remove(),document.documentElement.classList.remove("reveal-full-page"),K.wrapper.classList.remove("ready","center","has-horizontal-slides","has-vertical-slides"),K.wrapper.removeAttribute("data-transition-speed"),K.wrapper.removeAttribute("data-background-transition"),K.viewport.classList.remove("reveal-viewport"),K.viewport.style.removeProperty("--slide-width"),K.viewport.style.removeProperty("--slide-height"),K.slides.style.removeProperty("width"),K.slides.style.removeProperty("height"),K.slides.style.removeProperty("zoom"),K.slides.style.removeProperty("left"),K.slides.style.removeProperty("top"),K.slides.style.removeProperty("bottom"),K.slides.style.removeProperty("right"),K.slides.style.removeProperty("transform"),Array.from(K.wrapper.querySelectorAll(".slides section")).forEach((e=>{e.style.removeProperty("display"),e.style.removeProperty("top"),e.removeAttribute("hidden"),e.removeAttribute("aria-hidden")}))}function Le(e,t,i){n.addEventListener(e,t,i)}function Ce(e,t,i){n.removeEventListener(e,t,i)}function xe(e){"string"==typeof e.layout&&(W.layout=e.layout),"string"==typeof e.overview&&(W.overview=e.overview),W.layout?a(K.slides,W.layout+" "+W.overview):a(K.slides,W.overview)}function Pe({target:t=K.wrapper,type:i,data:s,bubbles:a=!0}){let n=document.createEvent("HTMLEvents",1,2);return n.initEvent(i,a,!0),e(n,s),t.dispatchEvent(n),t===K.wrapper&&Ne(i),n}function Ne(t,i){if(w.postMessageEvents&&window.parent!==window.self){let s={namespace:"reveal",eventName:t,state:yt()};e(s,i),window.parent.postMessage(JSON.stringify(s),"*")}}function Me(e="a"){Array.from(K.wrapper.querySelectorAll(e)).forEach((e=>{/^(http|www)/gi.test(e.getAttribute("href"))&&e.addEventListener("click",qt,!1)}))}function De(e="a"){Array.from(K.wrapper.querySelectorAll(e)).forEach((e=>{/^(http|www)/gi.test(e.getAttribute("href"))&&e.removeEventListener("click",qt,!1)}))}function Ie(e){ze(),K.overlay=document.createElement("div"),K.overlay.classList.add("overlay"),K.overlay.classList.add("overlay-preview"),K.wrapper.appendChild(K.overlay),K.overlay.innerHTML=`
\n\t\t\t\t \n\t\t\t\t \n\t\t\t \n\t\t\t
\n\t\t\t
\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\tUnable to load iframe. This is likely due to the site's policy (x-frame-options). \n\t\t\t\t \n\t\t\t
`,K.overlay.querySelector("iframe").addEventListener("load",(e=>{K.overlay.classList.add("loaded")}),!1),K.overlay.querySelector(".close").addEventListener("click",(e=>{ze(),e.preventDefault()}),!1),K.overlay.querySelector(".external").addEventListener("click",(e=>{ze()}),!1)}function Te(e){"boolean"==typeof e?e?Fe():ze():K.overlay?ze():Fe()}function Fe(){if(w.help){ze(),K.overlay=document.createElement("div"),K.overlay.classList.add("overlay"),K.overlay.classList.add("overlay-help"),K.wrapper.appendChild(K.overlay);let e='
Keyboard Shortcuts
',t=te.getShortcuts(),i=te.getBindings();e+="
KEY ACTION ";for(let i in t)e+=`${i} ${t[i]} `;for(let t in i)i[t].key&&i[t].description&&(e+=`${i[t].key} ${i[t].description} `);e+="
",K.overlay.innerHTML=`\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
${e}
\n\t\t\t\t
\n\t\t\t`,K.overlay.querySelector(".close").addEventListener("click",(e=>{ze(),e.preventDefault()}),!1)}}function ze(){return!!K.overlay&&(K.overlay.parentNode.removeChild(K.overlay),K.overlay=null,!0)}function He(){if(K.wrapper&&!oe.isPrintingPDF()){if(!w.disableLayout){g&&!w.embedded&&document.documentElement.style.setProperty("--vh",.01*window.innerHeight+"px");const e=Be(),t=U;qe(w.width,w.height),K.slides.style.width=e.width+"px",K.slides.style.height=e.height+"px",U=Math.min(e.presentationWidth/e.width,e.presentationHeight/e.height),U=Math.max(U,w.minScale),U=Math.min(U,w.maxScale),1===U?(K.slides.style.zoom="",K.slides.style.left="",K.slides.style.top="",K.slides.style.bottom="",K.slides.style.right="",xe({layout:""})):(K.slides.style.zoom="",K.slides.style.left="50%",K.slides.style.top="50%",K.slides.style.bottom="auto",K.slides.style.right="auto",xe({layout:"translate(-50%, -50%) scale("+U+")"}));const i=Array.from(K.wrapper.querySelectorAll(".slides section"));for(let t=0,s=i.length;t
.stretch, section > .r-stretch").forEach((t=>{let s=c(t,i);if(/(img|video)/gi.test(t.nodeName)){const i=t.naturalWidth||t.videoWidth,a=t.naturalHeight||t.videoHeight,n=Math.min(e/i,s/a);t.style.width=i*n+"px",t.style.height=a*n+"px"}else t.style.width=e+"px",t.style.height=s+"px"}))}function Be(e,t){const i={width:w.width,height:w.height,presentationWidth:e||K.wrapper.offsetWidth,presentationHeight:t||K.wrapper.offsetHeight};return i.presentationWidth-=i.presentationWidth*w.margin,i.presentationHeight-=i.presentationHeight*w.margin,"string"==typeof i.width&&/%$/.test(i.width)&&(i.width=parseInt(i.width,10)/100*i.presentationWidth),"string"==typeof i.height&&/%$/.test(i.height)&&(i.height=parseInt(i.height,10)/100*i.presentationHeight),i}function Oe(e,t){"object"==typeof e&&"function"==typeof e.setAttribute&&e.setAttribute("data-previous-indexv",t||0)}function Ue(e){if("object"==typeof e&&"function"==typeof e.setAttribute&&e.classList.contains("stack")){const t=e.hasAttribute("data-start-indexv")?"data-start-indexv":"data-previous-indexv";return parseInt(e.getAttribute(t)||0,10)}return 0}function We(e=m){return e&&e.parentNode&&!!e.parentNode.nodeName.match(/section/i)}function Ke(){return!(!m||!We(m))&&!m.nextElementSibling}function Ve(){return 0===u&&0===v}function $e(){return!!m&&(!m.nextElementSibling&&(!We(m)||!m.parentNode.nextElementSibling))}function je(){if(w.pause){const e=K.wrapper.classList.contains("paused");Rt(),K.wrapper.classList.add("paused"),!1===e&&Pe({type:"paused"})}}function Xe(){const e=K.wrapper.classList.contains("paused");K.wrapper.classList.remove("paused"),Et(),e&&Pe({type:"resumed"})}function Ye(e){"boolean"==typeof e?e?je():Xe():_e()?Xe():je()}function _e(){return K.wrapper.classList.contains("paused")}function Je(e){"boolean"==typeof e?e?At():St():Y?At():St()}function Qe(){return!(!$||Y)}function Ze(e,t,i,s){if(Pe({type:"beforeslidechange",data:{indexh:void 0===e?u:e,indexv:void 0===t?v:t,origin:s}}).defaultPrevented)return;p=m;const a=K.wrapper.querySelectorAll(".slides>section");if(0===a.length)return;void 0!==t||ee.isActive()||(t=Ue(a[e])),p&&p.parentNode&&p.parentNode.classList.contains("stack")&&Oe(p.parentNode,v);const n=I.concat();I.length=0;let r=u||0,o=v||0;u=st(".slides>section",void 0===e?u:e),v=st(".slides>section.present>section",void 0===t?v:t);let l=u!==r||v!==o;l||(p=null);let d=a[u],c=d.querySelectorAll("section");m=c[v]||d;let h=!1;l&&p&&m&&!ee.isActive()&&(p.hasAttribute("data-auto-animate")&&m.hasAttribute("data-auto-animate")&&p.getAttribute("data-auto-animate-id")===m.getAttribute("data-auto-animate-id")&&!(u>r||v>o?m:p).hasAttribute("data-auto-animate-restart")&&(h=!0,K.slides.classList.add("disable-slide-transitions")),V="running"),at(),He(),ee.isActive()&&ee.update(),void 0!==i&&G.goto(i),p&&p!==m&&(p.classList.remove("present"),p.setAttribute("aria-hidden","true"),Ve()&&setTimeout((()=>{ut().forEach((e=>{Oe(e,0)}))}),0));e:for(let e=0,t=I.length;e{fe(be(m))})),ae.update(),se.update(),ce.update(),Z.update(),Z.updateParallax(),J.update(),G.update(),ie.writeURL(),Et(),h&&(setTimeout((()=>{K.slides.classList.remove("disable-slide-transitions")}),0),w.autoAnimate&&Q.run(p,m))}function Ge(){Ae(),Se(),He(),$=w.autoSlide,Et(),Z.create(),ie.writeURL(),G.sortAll(),se.update(),ae.update(),at(),ce.update(),ce.updateVisibility(),Z.update(!0),J.update(),_.formatEmbeddedContent(),!1===w.autoPlayMedia?_.stopEmbeddedContent(m,{unloadIframes:!1}):_.startEmbeddedContent(m),ee.isActive()&&ee.layout()}function et(e=m){Z.sync(e),G.sync(e),_.load(e),Z.update(),ce.update()}function tt(){ct().forEach((e=>{t(e,"section").forEach(((e,t)=>{t>0&&(e.classList.remove("present"),e.classList.remove("past"),e.classList.add("future"),e.setAttribute("aria-hidden","true"))}))}))}function it(e=ct()){e.forEach(((t,i)=>{let s=e[Math.floor(Math.random()*e.length)];s.parentNode===t.parentNode&&t.parentNode.insertBefore(t,s);let a=t.querySelectorAll("section");a.length&&it(a)}))}function st(e,i){let s=t(K.wrapper,e),a=s.length,n=oe.isPrintingPDF();if(a){w.loop&&(i%=a)<0&&(i=a+i),i=Math.max(Math.min(i,a-1),0);for(let e=0;e{e.classList.add("visible"),e.classList.remove("current-fragment")}))):e>i&&(a.classList.add(r?"past":"future"),w.fragments&&t(a,".fragment.visible").forEach((e=>{e.classList.remove("visible","current-fragment")})))}let e=s[i],r=e.classList.contains("present");e.classList.add("present"),e.removeAttribute("hidden"),e.removeAttribute("aria-hidden"),r||Pe({target:e,type:"visible",bubbles:!1});let o=e.getAttribute("data-state");o&&(I=I.concat(o.split(" ")))}else i=0;return i}function at(){let e,i,s=ct(),a=s.length;if(a&&void 0!==u){let n=ee.isActive()?10:w.viewDistance;g&&(n=ee.isActive()?6:w.mobileViewDistance),oe.isPrintingPDF()&&(n=Number.MAX_VALUE);for(let r=0;r section"),i=K.wrapper.querySelectorAll(".slides>section.present>section"),s={left:u>0,right:u0,down:v1&&(s.left=!0,s.right=!0),i.length>1&&(s.up=!0,s.down=!0)),t.length>1&&"linear"===w.navigationMode&&(s.right=s.right||s.down,s.left=s.left||s.up),!0===e){let e=G.availableRoutes();s.left=s.left||e.prev,s.up=s.up||e.prev,s.down=s.down||e.next,s.right=s.right||e.next}if(w.rtl){let e=s.left;s.left=s.right,s.right=e}return s}function rt(e=m){let t=ct(),i=0;e:for(let s=0;s0){let i=.9;t+=m.querySelectorAll(".fragment.visible").length/e.length*i}}return Math.min(t/(e-1),1)}function lt(e){let i,s=u,a=v;if(e){let i=We(e),n=i?e.parentNode:e,r=ct();s=Math.max(r.indexOf(n),0),a=void 0,i&&(a=Math.max(t(e.parentNode,"section").indexOf(e),0))}if(!e&&m){if(m.querySelectorAll(".fragment").length>0){let e=m.querySelector(".current-fragment");i=e&&e.hasAttribute("data-fragment-index")?parseInt(e.getAttribute("data-fragment-index"),10):m.querySelectorAll(".fragment.visible").length-1}}return{h:s,v:a,f:i}}function dt(){return t(K.wrapper,'.slides section:not(.stack):not([data-visibility="uncounted"])')}function ct(){return t(K.wrapper,".slides>section")}function ht(){return t(K.wrapper,".slides>section>section")}function ut(){return t(K.wrapper,".slides>section.stack")}function gt(){return ct().length>1}function vt(){return ht().length>1}function pt(){return dt().map((e=>{let t={};for(let i=0;i{e.hasAttribute("data-autoplay")&&$&&1e3*e.duration/e.playbackRate>$&&($=1e3*e.duration/e.playbackRate+1e3)}))),!$||Y||_e()||ee.isActive()||$e()&&!G.availableRoutes().next&&!0!==w.loop||(j=setTimeout((()=>{"function"==typeof w.autoSlideMethod?w.autoSlideMethod():Nt(),Et()}),$),X=Date.now()),f&&f.setPlaying(-1!==j)}}function Rt(){clearTimeout(j),j=-1}function St(){$&&!Y&&(Y=!0,Pe({type:"autoslidepaused"}),clearTimeout(j),f&&f.setPlaying(!1))}function At(){$&&Y&&(Y=!1,Pe({type:"autoslideresumed"}),Et())}function kt({skipFragments:e=!1}={}){A.hasNavigatedHorizontally=!0,w.rtl?(ee.isActive()||e||!1===G.next())&&nt().left&&Ze(u+1,"grid"===w.navigationMode?v:void 0):(ee.isActive()||e||!1===G.prev())&&nt().left&&Ze(u-1,"grid"===w.navigationMode?v:void 0)}function Lt({skipFragments:e=!1}={}){A.hasNavigatedHorizontally=!0,w.rtl?(ee.isActive()||e||!1===G.prev())&&nt().right&&Ze(u-1,"grid"===w.navigationMode?v:void 0):(ee.isActive()||e||!1===G.next())&&nt().right&&Ze(u+1,"grid"===w.navigationMode?v:void 0)}function Ct({skipFragments:e=!1}={}){(ee.isActive()||e||!1===G.prev())&&nt().up&&Ze(u,v-1)}function xt({skipFragments:e=!1}={}){A.hasNavigatedVertically=!0,(ee.isActive()||e||!1===G.next())&&nt().down&&Ze(u,v+1)}function Pt({skipFragments:e=!1}={}){if(e||!1===G.prev())if(nt().up)Ct({skipFragments:e});else{let i;if(i=w.rtl?t(K.wrapper,".slides>section.future").pop():t(K.wrapper,".slides>section.past").pop(),i&&i.classList.contains("stack")){let e=i.querySelectorAll("section").length-1||void 0;Ze(u-1,e)}else kt({skipFragments:e})}}function Nt({skipFragments:e=!1}={}){if(A.hasNavigatedHorizontally=!0,A.hasNavigatedVertically=!0,e||!1===G.next()){let t=nt();t.down&&t.right&&w.loop&&Ke()&&(t.down=!1),t.down?xt({skipFragments:e}):w.rtl?kt({skipFragments:e}):Lt({skipFragments:e})}}function Mt(e){w.autoSlideStoppable&&St()}function Dt(e){let t=e.data;if("string"==typeof t&&"{"===t.charAt(0)&&"}"===t.charAt(t.length-1)&&(t=JSON.parse(t),t.method&&"function"==typeof h[t.method]))if(!1===R.test(t.method)){const e=h[t.method].apply(h,t.args);Ne("callback",{method:t.method,result:e})}else console.warn('reveal.js: "'+t.method+'" is is blacklisted from the postMessage API')}function It(e){"running"===V&&/section/gi.test(e.target.nodeName)&&(V="idle",Pe({type:"slidetransitionend",data:{indexh:u,indexv:v,previousSlide:p,currentSlide:m}}))}function Tt(e){const t=r(e.target,'a[href^="#"]');if(t){const i=t.getAttribute("href"),s=ie.getIndicesFromHash(i);s&&(h.slide(s.h,s.v,s.f),e.preventDefault())}}function Ft(e){He()}function zt(e){!1===document.hidden&&document.activeElement!==document.body&&("function"==typeof document.activeElement.blur&&document.activeElement.blur(),document.body.focus())}function Ht(e){(document.fullscreenElement||document.webkitFullscreenElement)===K.wrapper&&(e.stopImmediatePropagation(),setTimeout((()=>{h.layout(),h.focus.focus()}),1))}function qt(e){if(e.currentTarget&&e.currentTarget.hasAttribute("href")){let t=e.currentTarget.getAttribute("href");t&&(Ie(t),e.preventDefault())}}function Bt(e){$e()&&!1===w.loop?(Ze(0,0),At()):Y?At():St()}const Ot={VERSION:"4.3.1",initialize:he,configure:Re,destroy:ke,sync:Ge,syncSlide:et,syncFragments:G.sync.bind(G),slide:Ze,left:kt,right:Lt,up:Ct,down:xt,prev:Pt,next:Nt,navigateLeft:kt,navigateRight:Lt,navigateUp:Ct,navigateDown:xt,navigatePrev:Pt,navigateNext:Nt,navigateFragment:G.goto.bind(G),prevFragment:G.prev.bind(G),nextFragment:G.next.bind(G),on:Le,off:Ce,addEventListener:Le,removeEventListener:Ce,layout:He,shuffle:it,availableRoutes:nt,availableFragments:G.availableRoutes.bind(G),toggleHelp:Te,toggleOverview:ee.toggle.bind(ee),togglePause:Ye,toggleAutoSlide:Je,isFirstSlide:Ve,isLastSlide:$e,isLastVerticalSlide:Ke,isVerticalSlide:We,isPaused:_e,isAutoSliding:Qe,isSpeakerNotes:ce.isSpeakerNotesWindow.bind(ce),isOverview:ee.isActive.bind(ee),isFocused:le.isFocused.bind(le),isPrintingPDF:oe.isPrintingPDF.bind(oe),isReady:()=>S,loadSlide:_.load.bind(_),unloadSlide:_.unload.bind(_),showPreview:Ie,hidePreview:ze,addEventListeners:Se,removeEventListeners:Ae,dispatchEvent:Pe,getState:yt,setState:wt,getProgress:ot,getIndices:lt,getSlidesAttributes:pt,getSlidePastCount:rt,getTotalSlides:mt,getSlide:ft,getPreviousSlide:()=>p,getCurrentSlide:()=>m,getSlideBackground:bt,getSlideNotes:ce.getSlideNotes.bind(ce),getSlides:dt,getHorizontalSlides:ct,getVerticalSlides:ht,hasHorizontalSlides:gt,hasVerticalSlides:vt,hasNavigatedHorizontally:()=>A.hasNavigatedHorizontally,hasNavigatedVertically:()=>A.hasNavigatedVertically,addKeyBinding:te.addKeyBinding.bind(te),removeKeyBinding:te.removeKeyBinding.bind(te),triggerKey:te.triggerKey.bind(te),registerKeyboardShortcut:te.registerKeyboardShortcut.bind(te),getComputedSlideSize:Be,getScale:()=>U,getConfig:()=>w,getQueryHash:d,getSlidePath:ie.getHash.bind(ie),getRevealElement:()=>n,getSlidesElement:()=>K.slides,getViewportElement:()=>K.viewport,getBackgroundsElement:()=>Z.element,registerPlugin:re.registerPlugin.bind(re),hasPlugin:re.hasPlugin.bind(re),getPlugin:re.getPlugin.bind(re),getPlugins:re.getRegisteredPlugins.bind(re)};return e(h,{...Ot,announceStatus:fe,getStatusText:be,print:oe,focus:le,progress:ae,controls:se,location:ie,overview:ee,fragments:G,slideContent:_,slideNumber:J,onUserInput:Mt,closeOverlay:ze,updateSlidesVisibility:at,layoutSlideContents:qe,transformSlides:xe,cueAutoSlide:Et,cancelAutoSlide:Rt}),Ot}let W=U,K=[];W.initialize=e=>(Object.assign(W,new U(document.querySelector(".reveal"),e)),K.map((e=>e(W))),W.initialize()),["configure","on","off","addEventListener","removeEventListener","registerPlugin"].forEach((e=>{W[e]=(...t)=>{K.push((i=>i[e].call(null,...t)))}})),W.isReady=()=>!1,W.VERSION="4.3.1";export default W;
+//# sourceMappingURL=reveal.esm.js.map
diff --git a/3 Cognitive change/project-presentation_files/libs/revealjs/dist/reveal.esm.js.map b/3 Cognitive change/project-presentation_files/libs/revealjs/dist/reveal.esm.js.map
new file mode 100644
index 0000000..286c75a
--- /dev/null
+++ b/3 Cognitive change/project-presentation_files/libs/revealjs/dist/reveal.esm.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"reveal.esm.js","sources":["../js/utils/util.js","../js/utils/device.js","../node_modules/fitty/dist/fitty.module.js","../js/controllers/slidecontent.js","../js/controllers/slidenumber.js","../js/utils/color.js","../js/controllers/backgrounds.js","../js/utils/constants.js","../js/controllers/autoanimate.js","../js/controllers/fragments.js","../js/controllers/overview.js","../js/controllers/keyboard.js","../js/controllers/location.js","../js/controllers/controls.js","../js/controllers/progress.js","../js/controllers/pointer.js","../js/utils/loader.js","../js/controllers/plugins.js","../js/controllers/print.js","../js/controllers/touch.js","../js/controllers/focus.js","../js/controllers/notes.js","../js/components/playback.js","../js/config.js","../js/reveal.js","../js/index.js"],"sourcesContent":["/**\n * Extend object a with the properties of object b.\n * If there's a conflict, object b takes precedence.\n *\n * @param {object} a\n * @param {object} b\n */\nexport const extend = ( a, b ) => {\n\n\tfor( let i in b ) {\n\t\ta[ i ] = b[ i ];\n\t}\n\n\treturn a;\n\n}\n\n/**\n * querySelectorAll but returns an Array.\n */\nexport const queryAll = ( el, selector ) => {\n\n\treturn Array.from( el.querySelectorAll( selector ) );\n\n}\n\n/**\n * classList.toggle() with cross browser support\n */\nexport const toggleClass = ( el, className, value ) => {\n\tif( value ) {\n\t\tel.classList.add( className );\n\t}\n\telse {\n\t\tel.classList.remove( className );\n\t}\n}\n\n/**\n * Utility for deserializing a value.\n *\n * @param {*} value\n * @return {*}\n */\nexport const deserialize = ( value ) => {\n\n\tif( typeof value === 'string' ) {\n\t\tif( value === 'null' ) return null;\n\t\telse if( value === 'true' ) return true;\n\t\telse if( value === 'false' ) return false;\n\t\telse if( value.match( /^-?[\\d\\.]+$/ ) ) return parseFloat( value );\n\t}\n\n\treturn value;\n\n}\n\n/**\n * Measures the distance in pixels between point a\n * and point b.\n *\n * @param {object} a point with x/y properties\n * @param {object} b point with x/y properties\n *\n * @return {number}\n */\nexport const distanceBetween = ( a, b ) => {\n\n\tlet dx = a.x - b.x,\n\t\tdy = a.y - b.y;\n\n\treturn Math.sqrt( dx*dx + dy*dy );\n\n}\n\n/**\n * Applies a CSS transform to the target element.\n *\n * @param {HTMLElement} element\n * @param {string} transform\n */\nexport const transformElement = ( element, transform ) => {\n\n\telement.style.transform = transform;\n\n}\n\n/**\n * Element.matches with IE support.\n *\n * @param {HTMLElement} target The element to match\n * @param {String} selector The CSS selector to match\n * the element against\n *\n * @return {Boolean}\n */\nexport const matches = ( target, selector ) => {\n\n\tlet matchesMethod = target.matches || target.matchesSelector || target.msMatchesSelector;\n\n\treturn !!( matchesMethod && matchesMethod.call( target, selector ) );\n\n}\n\n/**\n * Find the closest parent that matches the given\n * selector.\n *\n * @param {HTMLElement} target The child element\n * @param {String} selector The CSS selector to match\n * the parents against\n *\n * @return {HTMLElement} The matched parent or null\n * if no matching parent was found\n */\nexport const closest = ( target, selector ) => {\n\n\t// Native Element.closest\n\tif( typeof target.closest === 'function' ) {\n\t\treturn target.closest( selector );\n\t}\n\n\t// Polyfill\n\twhile( target ) {\n\t\tif( matches( target, selector ) ) {\n\t\t\treturn target;\n\t\t}\n\n\t\t// Keep searching\n\t\ttarget = target.parentNode;\n\t}\n\n\treturn null;\n\n}\n\n/**\n * Handling the fullscreen functionality via the fullscreen API\n *\n * @see http://fullscreen.spec.whatwg.org/\n * @see https://developer.mozilla.org/en-US/docs/DOM/Using_fullscreen_mode\n */\nexport const enterFullscreen = element => {\n\n\telement = element || document.documentElement;\n\n\t// Check which implementation is available\n\tlet requestMethod = element.requestFullscreen ||\n\t\t\t\t\t\telement.webkitRequestFullscreen ||\n\t\t\t\t\t\telement.webkitRequestFullScreen ||\n\t\t\t\t\t\telement.mozRequestFullScreen ||\n\t\t\t\t\t\telement.msRequestFullscreen;\n\n\tif( requestMethod ) {\n\t\trequestMethod.apply( element );\n\t}\n\n}\n\n/**\n * Creates an HTML element and returns a reference to it.\n * If the element already exists the existing instance will\n * be returned.\n *\n * @param {HTMLElement} container\n * @param {string} tagname\n * @param {string} classname\n * @param {string} innerHTML\n *\n * @return {HTMLElement}\n */\nexport const createSingletonNode = ( container, tagname, classname, innerHTML='' ) => {\n\n\t// Find all nodes matching the description\n\tlet nodes = container.querySelectorAll( '.' + classname );\n\n\t// Check all matches to find one which is a direct child of\n\t// the specified container\n\tfor( let i = 0; i < nodes.length; i++ ) {\n\t\tlet testNode = nodes[i];\n\t\tif( testNode.parentNode === container ) {\n\t\t\treturn testNode;\n\t\t}\n\t}\n\n\t// If no node was found, create it now\n\tlet node = document.createElement( tagname );\n\tnode.className = classname;\n\tnode.innerHTML = innerHTML;\n\tcontainer.appendChild( node );\n\n\treturn node;\n\n}\n\n/**\n * Injects the given CSS styles into the DOM.\n *\n * @param {string} value\n */\nexport const createStyleSheet = ( value ) => {\n\n\tlet tag = document.createElement( 'style' );\n\ttag.type = 'text/css';\n\n\tif( value && value.length > 0 ) {\n\t\tif( tag.styleSheet ) {\n\t\t\ttag.styleSheet.cssText = value;\n\t\t}\n\t\telse {\n\t\t\ttag.appendChild( document.createTextNode( value ) );\n\t\t}\n\t}\n\n\tdocument.head.appendChild( tag );\n\n\treturn tag;\n\n}\n\n/**\n * Returns a key:value hash of all query params.\n */\nexport const getQueryHash = () => {\n\n\tlet query = {};\n\n\tlocation.search.replace( /[A-Z0-9]+?=([\\w\\.%-]*)/gi, a => {\n\t\tquery[ a.split( '=' ).shift() ] = a.split( '=' ).pop();\n\t} );\n\n\t// Basic deserialization\n\tfor( let i in query ) {\n\t\tlet value = query[ i ];\n\n\t\tquery[ i ] = deserialize( unescape( value ) );\n\t}\n\n\t// Do not accept new dependencies via query config to avoid\n\t// the potential of malicious script injection\n\tif( typeof query['dependencies'] !== 'undefined' ) delete query['dependencies'];\n\n\treturn query;\n\n}\n\n/**\n * Returns the remaining height within the parent of the\n * target element.\n *\n * remaining height = [ configured parent height ] - [ current parent height ]\n *\n * @param {HTMLElement} element\n * @param {number} [height]\n */\nexport const getRemainingHeight = ( element, height = 0 ) => {\n\n\tif( element ) {\n\t\tlet newHeight, oldHeight = element.style.height;\n\n\t\t// Change the .stretch element height to 0 in order find the height of all\n\t\t// the other elements\n\t\telement.style.height = '0px';\n\n\t\t// In Overview mode, the parent (.slide) height is set of 700px.\n\t\t// Restore it temporarily to its natural height.\n\t\telement.parentNode.style.height = 'auto';\n\n\t\tnewHeight = height - element.parentNode.offsetHeight;\n\n\t\t// Restore the old height, just in case\n\t\telement.style.height = oldHeight + 'px';\n\n\t\t// Clear the parent (.slide) height. .removeProperty works in IE9+\n\t\telement.parentNode.style.removeProperty('height');\n\n\t\treturn newHeight;\n\t}\n\n\treturn height;\n\n}\n\nconst fileExtensionToMimeMap = {\n\t'mp4': 'video/mp4',\n\t'm4a': 'video/mp4',\n\t'ogv': 'video/ogg',\n\t'mpeg': 'video/mpeg',\n\t'webm': 'video/webm'\n}\n\n/**\n * Guess the MIME type for common file formats.\n */\nexport const getMimeTypeFromFile = ( filename='' ) => {\n\treturn fileExtensionToMimeMap[filename.split('.').pop()]\n}","const UA = navigator.userAgent;\n\nexport const isMobile = /(iphone|ipod|ipad|android)/gi.test( UA ) ||\n\t\t\t\t\t\t( navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1 ); // iPadOS\n\nexport const isChrome = /chrome/i.test( UA ) && !/edge/i.test( UA );\n\nexport const isAndroid = /android/gi.test( UA );","/*\n * fitty v2.3.3 - Snugly resizes text to fit its parent container\n * Copyright (c) 2020 Rik Schennink (https://pqina.nl/)\n */\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nexports.default = function (w) {\n\n // no window, early exit\n if (!w) return;\n\n // node list to array helper method\n var toArray = function toArray(nl) {\n return [].slice.call(nl);\n };\n\n // states\n var DrawState = {\n IDLE: 0,\n DIRTY_CONTENT: 1,\n DIRTY_LAYOUT: 2,\n DIRTY: 3\n };\n\n // all active fitty elements\n var fitties = [];\n\n // group all redraw calls till next frame, we cancel each frame request when a new one comes in. If no support for request animation frame, this is an empty function and supports for fitty stops.\n var redrawFrame = null;\n var requestRedraw = 'requestAnimationFrame' in w ? function () {\n w.cancelAnimationFrame(redrawFrame);\n redrawFrame = w.requestAnimationFrame(function () {\n return redraw(fitties.filter(function (f) {\n return f.dirty && f.active;\n }));\n });\n } : function () {};\n\n // sets all fitties to dirty so they are redrawn on the next redraw loop, then calls redraw\n var redrawAll = function redrawAll(type) {\n return function () {\n fitties.forEach(function (f) {\n return f.dirty = type;\n });\n requestRedraw();\n };\n };\n\n // redraws fitties so they nicely fit their parent container\n var redraw = function redraw(fitties) {\n\n // getting info from the DOM at this point should not trigger a reflow, let's gather as much intel as possible before triggering a reflow\n\n // check if styles of all fitties have been computed\n fitties.filter(function (f) {\n return !f.styleComputed;\n }).forEach(function (f) {\n f.styleComputed = computeStyle(f);\n });\n\n // restyle elements that require pre-styling, this triggers a reflow, please try to prevent by adding CSS rules (see docs)\n fitties.filter(shouldPreStyle).forEach(applyStyle);\n\n // we now determine which fitties should be redrawn\n var fittiesToRedraw = fitties.filter(shouldRedraw);\n\n // we calculate final styles for these fitties\n fittiesToRedraw.forEach(calculateStyles);\n\n // now we apply the calculated styles from our previous loop\n fittiesToRedraw.forEach(function (f) {\n applyStyle(f);\n markAsClean(f);\n });\n\n // now we dispatch events for all restyled fitties\n fittiesToRedraw.forEach(dispatchFitEvent);\n };\n\n var markAsClean = function markAsClean(f) {\n return f.dirty = DrawState.IDLE;\n };\n\n var calculateStyles = function calculateStyles(f) {\n\n // get available width from parent node\n f.availableWidth = f.element.parentNode.clientWidth;\n\n // the space our target element uses\n f.currentWidth = f.element.scrollWidth;\n\n // remember current font size\n f.previousFontSize = f.currentFontSize;\n\n // let's calculate the new font size\n f.currentFontSize = Math.min(Math.max(f.minSize, f.availableWidth / f.currentWidth * f.previousFontSize), f.maxSize);\n\n // if allows wrapping, only wrap when at minimum font size (otherwise would break container)\n f.whiteSpace = f.multiLine && f.currentFontSize === f.minSize ? 'normal' : 'nowrap';\n };\n\n // should always redraw if is not dirty layout, if is dirty layout, only redraw if size has changed\n var shouldRedraw = function shouldRedraw(f) {\n return f.dirty !== DrawState.DIRTY_LAYOUT || f.dirty === DrawState.DIRTY_LAYOUT && f.element.parentNode.clientWidth !== f.availableWidth;\n };\n\n // every fitty element is tested for invalid styles\n var computeStyle = function computeStyle(f) {\n\n // get style properties\n var style = w.getComputedStyle(f.element, null);\n\n // get current font size in pixels (if we already calculated it, use the calculated version)\n f.currentFontSize = parseFloat(style.getPropertyValue('font-size'));\n\n // get display type and wrap mode\n f.display = style.getPropertyValue('display');\n f.whiteSpace = style.getPropertyValue('white-space');\n };\n\n // determines if this fitty requires initial styling, can be prevented by applying correct styles through CSS\n var shouldPreStyle = function shouldPreStyle(f) {\n\n var preStyle = false;\n\n // if we already tested for prestyling we don't have to do it again\n if (f.preStyleTestCompleted) return false;\n\n // should have an inline style, if not, apply\n if (!/inline-/.test(f.display)) {\n preStyle = true;\n f.display = 'inline-block';\n }\n\n // to correctly calculate dimensions the element should have whiteSpace set to nowrap\n if (f.whiteSpace !== 'nowrap') {\n preStyle = true;\n f.whiteSpace = 'nowrap';\n }\n\n // we don't have to do this twice\n f.preStyleTestCompleted = true;\n\n return preStyle;\n };\n\n // apply styles to single fitty\n var applyStyle = function applyStyle(f) {\n f.element.style.whiteSpace = f.whiteSpace;\n f.element.style.display = f.display;\n f.element.style.fontSize = f.currentFontSize + 'px';\n };\n\n // dispatch a fit event on a fitty\n var dispatchFitEvent = function dispatchFitEvent(f) {\n f.element.dispatchEvent(new CustomEvent('fit', {\n detail: {\n oldValue: f.previousFontSize,\n newValue: f.currentFontSize,\n scaleFactor: f.currentFontSize / f.previousFontSize\n }\n }));\n };\n\n // fit method, marks the fitty as dirty and requests a redraw (this will also redraw any other fitty marked as dirty)\n var fit = function fit(f, type) {\n return function () {\n f.dirty = type;\n if (!f.active) return;\n requestRedraw();\n };\n };\n\n var init = function init(f) {\n\n // save some of the original CSS properties before we change them\n f.originalStyle = {\n whiteSpace: f.element.style.whiteSpace,\n display: f.element.style.display,\n fontSize: f.element.style.fontSize\n };\n\n // should we observe DOM mutations\n observeMutations(f);\n\n // this is a new fitty so we need to validate if it's styles are in order\n f.newbie = true;\n\n // because it's a new fitty it should also be dirty, we want it to redraw on the first loop\n f.dirty = true;\n\n // we want to be able to update this fitty\n fitties.push(f);\n };\n\n var destroy = function destroy(f) {\n return function () {\n\n // remove from fitties array\n fitties = fitties.filter(function (_) {\n return _.element !== f.element;\n });\n\n // stop observing DOM\n if (f.observeMutations) f.observer.disconnect();\n\n // reset the CSS properties we changes\n f.element.style.whiteSpace = f.originalStyle.whiteSpace;\n f.element.style.display = f.originalStyle.display;\n f.element.style.fontSize = f.originalStyle.fontSize;\n };\n };\n\n // add a new fitty, does not redraw said fitty\n var subscribe = function subscribe(f) {\n return function () {\n if (f.active) return;\n f.active = true;\n requestRedraw();\n };\n };\n\n // remove an existing fitty\n var unsubscribe = function unsubscribe(f) {\n return function () {\n return f.active = false;\n };\n };\n\n var observeMutations = function observeMutations(f) {\n\n // no observing?\n if (!f.observeMutations) return;\n\n // start observing mutations\n f.observer = new MutationObserver(fit(f, DrawState.DIRTY_CONTENT));\n\n // start observing\n f.observer.observe(f.element, f.observeMutations);\n };\n\n // default mutation observer settings\n var mutationObserverDefaultSetting = {\n subtree: true,\n childList: true,\n characterData: true\n };\n\n // default fitty options\n var defaultOptions = {\n minSize: 16,\n maxSize: 512,\n multiLine: true,\n observeMutations: 'MutationObserver' in w ? mutationObserverDefaultSetting : false\n };\n\n // array of elements in, fitty instances out\n function fittyCreate(elements, options) {\n\n // set options object\n var fittyOptions = _extends({}, defaultOptions, options);\n\n // create fitties\n var publicFitties = elements.map(function (element) {\n\n // create fitty instance\n var f = _extends({}, fittyOptions, {\n\n // internal options for this fitty\n element: element,\n active: true\n });\n\n // initialise this fitty\n init(f);\n\n // expose API\n return {\n element: element,\n fit: fit(f, DrawState.DIRTY),\n unfreeze: subscribe(f),\n freeze: unsubscribe(f),\n unsubscribe: destroy(f)\n };\n });\n\n // call redraw on newly initiated fitties\n requestRedraw();\n\n // expose fitties\n return publicFitties;\n }\n\n // fitty creation function\n function fitty(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n\n // if target is a string\n return typeof target === 'string' ?\n\n // treat it as a querySelector\n fittyCreate(toArray(document.querySelectorAll(target)), options) :\n\n // create single fitty\n fittyCreate([target], options)[0];\n }\n\n // handles viewport changes, redraws all fitties, but only does so after a timeout\n var resizeDebounce = null;\n var onWindowResized = function onWindowResized() {\n w.clearTimeout(resizeDebounce);\n resizeDebounce = w.setTimeout(redrawAll(DrawState.DIRTY_LAYOUT), fitty.observeWindowDelay);\n };\n\n // define observe window property, so when we set it to true or false events are automatically added and removed\n var events = ['resize', 'orientationchange'];\n Object.defineProperty(fitty, 'observeWindow', {\n set: function set(enabled) {\n var method = (enabled ? 'add' : 'remove') + 'EventListener';\n events.forEach(function (e) {\n w[method](e, onWindowResized);\n });\n }\n });\n\n // fitty global properties (by setting observeWindow to true the events above get added)\n fitty.observeWindow = true;\n fitty.observeWindowDelay = 100;\n\n // public fit all method, will force redraw no matter what\n fitty.fitAll = redrawAll(DrawState.DIRTY);\n\n // export our fitty function, we don't want to keep it to our selves\n return fitty;\n}(typeof window === 'undefined' ? null : window);","import { extend, queryAll, closest, getMimeTypeFromFile } from '../utils/util.js'\nimport { isMobile } from '../utils/device.js'\n\nimport fitty from 'fitty';\n\n/**\n * Handles loading, unloading and playback of slide\n * content such as images, videos and iframes.\n */\nexport default class SlideContent {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.startEmbeddedIframe = this.startEmbeddedIframe.bind( this );\n\n\t}\n\n\t/**\n\t * Should the given element be preloaded?\n\t * Decides based on local element attributes and global config.\n\t *\n\t * @param {HTMLElement} element\n\t */\n\tshouldPreload( element ) {\n\n\t\t// Prefer an explicit global preload setting\n\t\tlet preload = this.Reveal.getConfig().preloadIframes;\n\n\t\t// If no global setting is available, fall back on the element's\n\t\t// own preload setting\n\t\tif( typeof preload !== 'boolean' ) {\n\t\t\tpreload = element.hasAttribute( 'data-preload' );\n\t\t}\n\n\t\treturn preload;\n\t}\n\n\t/**\n\t * Called when the given slide is within the configured view\n\t * distance. Shows the slide element and loads any content\n\t * that is set to load lazily (data-src).\n\t *\n\t * @param {HTMLElement} slide Slide to show\n\t */\n\tload( slide, options = {} ) {\n\n\t\t// Show the slide element\n\t\tslide.style.display = this.Reveal.getConfig().display;\n\n\t\t// Media elements with data-src attributes\n\t\tqueryAll( slide, 'img[data-src], video[data-src], audio[data-src], iframe[data-src]' ).forEach( element => {\n\t\t\tif( element.tagName !== 'IFRAME' || this.shouldPreload( element ) ) {\n\t\t\t\telement.setAttribute( 'src', element.getAttribute( 'data-src' ) );\n\t\t\t\telement.setAttribute( 'data-lazy-loaded', '' );\n\t\t\t\telement.removeAttribute( 'data-src' );\n\t\t\t}\n\t\t} );\n\n\t\t// Media elements with children\n\t\tqueryAll( slide, 'video, audio' ).forEach( media => {\n\t\t\tlet sources = 0;\n\n\t\t\tqueryAll( media, 'source[data-src]' ).forEach( source => {\n\t\t\t\tsource.setAttribute( 'src', source.getAttribute( 'data-src' ) );\n\t\t\t\tsource.removeAttribute( 'data-src' );\n\t\t\t\tsource.setAttribute( 'data-lazy-loaded', '' );\n\t\t\t\tsources += 1;\n\t\t\t} );\n\n\t\t\t// Enable inline video playback in mobile Safari\n\t\t\tif( isMobile && media.tagName === 'VIDEO' ) {\n\t\t\t\tmedia.setAttribute( 'playsinline', '' );\n\t\t\t}\n\n\t\t\t// If we rewrote sources for this video/audio element, we need\n\t\t\t// to manually tell it to load from its new origin\n\t\t\tif( sources > 0 ) {\n\t\t\t\tmedia.load();\n\t\t\t}\n\t\t} );\n\n\n\t\t// Show the corresponding background element\n\t\tlet background = slide.slideBackgroundElement;\n\t\tif( background ) {\n\t\t\tbackground.style.display = 'block';\n\n\t\t\tlet backgroundContent = slide.slideBackgroundContentElement;\n\t\t\tlet backgroundIframe = slide.getAttribute( 'data-background-iframe' );\n\n\t\t\t// If the background contains media, load it\n\t\t\tif( background.hasAttribute( 'data-loaded' ) === false ) {\n\t\t\t\tbackground.setAttribute( 'data-loaded', 'true' );\n\n\t\t\t\tlet backgroundImage = slide.getAttribute( 'data-background-image' ),\n\t\t\t\t\tbackgroundVideo = slide.getAttribute( 'data-background-video' ),\n\t\t\t\t\tbackgroundVideoLoop = slide.hasAttribute( 'data-background-video-loop' ),\n\t\t\t\t\tbackgroundVideoMuted = slide.hasAttribute( 'data-background-video-muted' );\n\n\t\t\t\t// Images\n\t\t\t\tif( backgroundImage ) {\n\t\t\t\t\t// base64\n\t\t\t\t\tif( /^data:/.test( backgroundImage.trim() ) ) {\n\t\t\t\t\t\tbackgroundContent.style.backgroundImage = `url(${backgroundImage.trim()})`;\n\t\t\t\t\t}\n\t\t\t\t\t// URL(s)\n\t\t\t\t\telse {\n\t\t\t\t\t\tbackgroundContent.style.backgroundImage = backgroundImage.split( ',' ).map( background => {\n\t\t\t\t\t\t\treturn `url(${encodeURI(background.trim())})`;\n\t\t\t\t\t\t}).join( ',' );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Videos\n\t\t\t\telse if ( backgroundVideo && !this.Reveal.isSpeakerNotes() ) {\n\t\t\t\t\tlet video = document.createElement( 'video' );\n\n\t\t\t\t\tif( backgroundVideoLoop ) {\n\t\t\t\t\t\tvideo.setAttribute( 'loop', '' );\n\t\t\t\t\t}\n\n\t\t\t\t\tif( backgroundVideoMuted ) {\n\t\t\t\t\t\tvideo.muted = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Enable inline playback in mobile Safari\n\t\t\t\t\t//\n\t\t\t\t\t// Mute is required for video to play when using\n\t\t\t\t\t// swipe gestures to navigate since they don't\n\t\t\t\t\t// count as direct user actions :'(\n\t\t\t\t\tif( isMobile ) {\n\t\t\t\t\t\tvideo.muted = true;\n\t\t\t\t\t\tvideo.setAttribute( 'playsinline', '' );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support comma separated lists of video sources\n\t\t\t\t\tbackgroundVideo.split( ',' ).forEach( source => {\n\t\t\t\t\t\tlet type = getMimeTypeFromFile( source );\n\t\t\t\t\t\tif( type ) {\n\t\t\t\t\t\t\tvideo.innerHTML += ``;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tvideo.innerHTML += ``;\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t\tbackgroundContent.appendChild( video );\n\t\t\t\t}\n\t\t\t\t// Iframes\n\t\t\t\telse if( backgroundIframe && options.excludeIframes !== true ) {\n\t\t\t\t\tlet iframe = document.createElement( 'iframe' );\n\t\t\t\t\tiframe.setAttribute( 'allowfullscreen', '' );\n\t\t\t\t\tiframe.setAttribute( 'mozallowfullscreen', '' );\n\t\t\t\t\tiframe.setAttribute( 'webkitallowfullscreen', '' );\n\t\t\t\t\tiframe.setAttribute( 'allow', 'autoplay' );\n\n\t\t\t\t\tiframe.setAttribute( 'data-src', backgroundIframe );\n\n\t\t\t\t\tiframe.style.width = '100%';\n\t\t\t\t\tiframe.style.height = '100%';\n\t\t\t\t\tiframe.style.maxHeight = '100%';\n\t\t\t\t\tiframe.style.maxWidth = '100%';\n\n\t\t\t\t\tbackgroundContent.appendChild( iframe );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start loading preloadable iframes\n\t\t\tlet backgroundIframeElement = backgroundContent.querySelector( 'iframe[data-src]' );\n\t\t\tif( backgroundIframeElement ) {\n\n\t\t\t\t// Check if this iframe is eligible to be preloaded\n\t\t\t\tif( this.shouldPreload( background ) && !/autoplay=(1|true|yes)/gi.test( backgroundIframe ) ) {\n\t\t\t\t\tif( backgroundIframeElement.getAttribute( 'src' ) !== backgroundIframe ) {\n\t\t\t\t\t\tbackgroundIframeElement.setAttribute( 'src', backgroundIframe );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.layout( slide );\n\n\t}\n\n\t/**\n\t * Applies JS-dependent layout helpers for the given slide,\n\t * if there are any.\n\t */\n\tlayout( slide ) {\n\n\t\t// Autosize text with the r-fit-text class based on the\n\t\t// size of its container. This needs to happen after the\n\t\t// slide is visible in order to measure the text.\n\t\tArray.from( slide.querySelectorAll( '.r-fit-text' ) ).forEach( element => {\n\t\t\tfitty( element, {\n\t\t\t\tminSize: 24,\n\t\t\t\tmaxSize: this.Reveal.getConfig().height * 0.8,\n\t\t\t\tobserveMutations: false,\n\t\t\t\tobserveWindow: false\n\t\t\t} );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Unloads and hides the given slide. This is called when the\n\t * slide is moved outside of the configured view distance.\n\t *\n\t * @param {HTMLElement} slide\n\t */\n\tunload( slide ) {\n\n\t\t// Hide the slide element\n\t\tslide.style.display = 'none';\n\n\t\t// Hide the corresponding background element\n\t\tlet background = this.Reveal.getSlideBackground( slide );\n\t\tif( background ) {\n\t\t\tbackground.style.display = 'none';\n\n\t\t\t// Unload any background iframes\n\t\t\tqueryAll( background, 'iframe[src]' ).forEach( element => {\n\t\t\t\telement.removeAttribute( 'src' );\n\t\t\t} );\n\t\t}\n\n\t\t// Reset lazy-loaded media elements with src attributes\n\t\tqueryAll( slide, 'video[data-lazy-loaded][src], audio[data-lazy-loaded][src], iframe[data-lazy-loaded][src]' ).forEach( element => {\n\t\t\telement.setAttribute( 'data-src', element.getAttribute( 'src' ) );\n\t\t\telement.removeAttribute( 'src' );\n\t\t} );\n\n\t\t// Reset lazy-loaded media elements with children\n\t\tqueryAll( slide, 'video[data-lazy-loaded] source[src], audio source[src]' ).forEach( source => {\n\t\t\tsource.setAttribute( 'data-src', source.getAttribute( 'src' ) );\n\t\t\tsource.removeAttribute( 'src' );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Enforces origin-specific format rules for embedded media.\n\t */\n\tformatEmbeddedContent() {\n\n\t\tlet _appendParamToIframeSource = ( sourceAttribute, sourceURL, param ) => {\n\t\t\tqueryAll( this.Reveal.getSlidesElement(), 'iframe['+ sourceAttribute +'*=\"'+ sourceURL +'\"]' ).forEach( el => {\n\t\t\t\tlet src = el.getAttribute( sourceAttribute );\n\t\t\t\tif( src && src.indexOf( param ) === -1 ) {\n\t\t\t\t\tel.setAttribute( sourceAttribute, src + ( !/\\?/.test( src ) ? '?' : '&' ) + param );\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\n\t\t// YouTube frames must include \"?enablejsapi=1\"\n\t\t_appendParamToIframeSource( 'src', 'youtube.com/embed/', 'enablejsapi=1' );\n\t\t_appendParamToIframeSource( 'data-src', 'youtube.com/embed/', 'enablejsapi=1' );\n\n\t\t// Vimeo frames must include \"?api=1\"\n\t\t_appendParamToIframeSource( 'src', 'player.vimeo.com/', 'api=1' );\n\t\t_appendParamToIframeSource( 'data-src', 'player.vimeo.com/', 'api=1' );\n\n\t}\n\n\t/**\n\t * Start playback of any embedded content inside of\n\t * the given element.\n\t *\n\t * @param {HTMLElement} element\n\t */\n\tstartEmbeddedContent( element ) {\n\n\t\tif( element && !this.Reveal.isSpeakerNotes() ) {\n\n\t\t\t// Restart GIFs\n\t\t\tqueryAll( element, 'img[src$=\".gif\"]' ).forEach( el => {\n\t\t\t\t// Setting the same unchanged source like this was confirmed\n\t\t\t\t// to work in Chrome, FF & Safari\n\t\t\t\tel.setAttribute( 'src', el.getAttribute( 'src' ) );\n\t\t\t} );\n\n\t\t\t// HTML5 media elements\n\t\t\tqueryAll( element, 'video, audio' ).forEach( el => {\n\t\t\t\tif( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Prefer an explicit global autoplay setting\n\t\t\t\tlet autoplay = this.Reveal.getConfig().autoPlayMedia;\n\n\t\t\t\t// If no global setting is available, fall back on the element's\n\t\t\t\t// own autoplay setting\n\t\t\t\tif( typeof autoplay !== 'boolean' ) {\n\t\t\t\t\tautoplay = el.hasAttribute( 'data-autoplay' ) || !!closest( el, '.slide-background' );\n\t\t\t\t}\n\n\t\t\t\tif( autoplay && typeof el.play === 'function' ) {\n\n\t\t\t\t\t// If the media is ready, start playback\n\t\t\t\t\tif( el.readyState > 1 ) {\n\t\t\t\t\t\tthis.startEmbeddedMedia( { target: el } );\n\t\t\t\t\t}\n\t\t\t\t\t// Mobile devices never fire a loaded event so instead\n\t\t\t\t\t// of waiting, we initiate playback\n\t\t\t\t\telse if( isMobile ) {\n\t\t\t\t\t\tlet promise = el.play();\n\n\t\t\t\t\t\t// If autoplay does not work, ensure that the controls are visible so\n\t\t\t\t\t\t// that the viewer can start the media on their own\n\t\t\t\t\t\tif( promise && typeof promise.catch === 'function' && el.controls === false ) {\n\t\t\t\t\t\t\tpromise.catch( () => {\n\t\t\t\t\t\t\t\tel.controls = true;\n\n\t\t\t\t\t\t\t\t// Once the video does start playing, hide the controls again\n\t\t\t\t\t\t\t\tel.addEventListener( 'play', () => {\n\t\t\t\t\t\t\t\t\tel.controls = false;\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// If the media isn't loaded, wait before playing\n\t\t\t\t\telse {\n\t\t\t\t\t\tel.removeEventListener( 'loadeddata', this.startEmbeddedMedia ); // remove first to avoid dupes\n\t\t\t\t\t\tel.addEventListener( 'loadeddata', this.startEmbeddedMedia );\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t// Normal iframes\n\t\t\tqueryAll( element, 'iframe[src]' ).forEach( el => {\n\t\t\t\tif( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.startEmbeddedIframe( { target: el } );\n\t\t\t} );\n\n\t\t\t// Lazy loading iframes\n\t\t\tqueryAll( element, 'iframe[data-src]' ).forEach( el => {\n\t\t\t\tif( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif( el.getAttribute( 'src' ) !== el.getAttribute( 'data-src' ) ) {\n\t\t\t\t\tel.removeEventListener( 'load', this.startEmbeddedIframe ); // remove first to avoid dupes\n\t\t\t\t\tel.addEventListener( 'load', this.startEmbeddedIframe );\n\t\t\t\t\tel.setAttribute( 'src', el.getAttribute( 'data-src' ) );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Starts playing an embedded video/audio element after\n\t * it has finished loading.\n\t *\n\t * @param {object} event\n\t */\n\tstartEmbeddedMedia( event ) {\n\n\t\tlet isAttachedToDOM = !!closest( event.target, 'html' ),\n\t\t\tisVisible \t\t= !!closest( event.target, '.present' );\n\n\t\tif( isAttachedToDOM && isVisible ) {\n\t\t\tevent.target.currentTime = 0;\n\t\t\tevent.target.play();\n\t\t}\n\n\t\tevent.target.removeEventListener( 'loadeddata', this.startEmbeddedMedia );\n\n\t}\n\n\t/**\n\t * \"Starts\" the content of an embedded iframe using the\n\t * postMessage API.\n\t *\n\t * @param {object} event\n\t */\n\tstartEmbeddedIframe( event ) {\n\n\t\tlet iframe = event.target;\n\n\t\tif( iframe && iframe.contentWindow ) {\n\n\t\t\tlet isAttachedToDOM = !!closest( event.target, 'html' ),\n\t\t\t\tisVisible \t\t= !!closest( event.target, '.present' );\n\n\t\t\tif( isAttachedToDOM && isVisible ) {\n\n\t\t\t\t// Prefer an explicit global autoplay setting\n\t\t\t\tlet autoplay = this.Reveal.getConfig().autoPlayMedia;\n\n\t\t\t\t// If no global setting is available, fall back on the element's\n\t\t\t\t// own autoplay setting\n\t\t\t\tif( typeof autoplay !== 'boolean' ) {\n\t\t\t\t\tautoplay = iframe.hasAttribute( 'data-autoplay' ) || !!closest( iframe, '.slide-background' );\n\t\t\t\t}\n\n\t\t\t\t// YouTube postMessage API\n\t\t\t\tif( /youtube\\.com\\/embed\\//.test( iframe.getAttribute( 'src' ) ) && autoplay ) {\n\t\t\t\t\tiframe.contentWindow.postMessage( '{\"event\":\"command\",\"func\":\"playVideo\",\"args\":\"\"}', '*' );\n\t\t\t\t}\n\t\t\t\t// Vimeo postMessage API\n\t\t\t\telse if( /player\\.vimeo\\.com\\//.test( iframe.getAttribute( 'src' ) ) && autoplay ) {\n\t\t\t\t\tiframe.contentWindow.postMessage( '{\"method\":\"play\"}', '*' );\n\t\t\t\t}\n\t\t\t\t// Generic postMessage API\n\t\t\t\telse {\n\t\t\t\t\tiframe.contentWindow.postMessage( 'slide:start', '*' );\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Stop playback of any embedded content inside of\n\t * the targeted slide.\n\t *\n\t * @param {HTMLElement} element\n\t */\n\tstopEmbeddedContent( element, options = {} ) {\n\n\t\toptions = extend( {\n\t\t\t// Defaults\n\t\t\tunloadIframes: true\n\t\t}, options );\n\n\t\tif( element && element.parentNode ) {\n\t\t\t// HTML5 media elements\n\t\t\tqueryAll( element, 'video, audio' ).forEach( el => {\n\t\t\t\tif( !el.hasAttribute( 'data-ignore' ) && typeof el.pause === 'function' ) {\n\t\t\t\t\tel.setAttribute('data-paused-by-reveal', '');\n\t\t\t\t\tel.pause();\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t// Generic postMessage API for non-lazy loaded iframes\n\t\t\tqueryAll( element, 'iframe' ).forEach( el => {\n\t\t\t\tif( el.contentWindow ) el.contentWindow.postMessage( 'slide:stop', '*' );\n\t\t\t\tel.removeEventListener( 'load', this.startEmbeddedIframe );\n\t\t\t});\n\n\t\t\t// YouTube postMessage API\n\t\t\tqueryAll( element, 'iframe[src*=\"youtube.com/embed/\"]' ).forEach( el => {\n\t\t\t\tif( !el.hasAttribute( 'data-ignore' ) && el.contentWindow && typeof el.contentWindow.postMessage === 'function' ) {\n\t\t\t\t\tel.contentWindow.postMessage( '{\"event\":\"command\",\"func\":\"pauseVideo\",\"args\":\"\"}', '*' );\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Vimeo postMessage API\n\t\t\tqueryAll( element, 'iframe[src*=\"player.vimeo.com/\"]' ).forEach( el => {\n\t\t\t\tif( !el.hasAttribute( 'data-ignore' ) && el.contentWindow && typeof el.contentWindow.postMessage === 'function' ) {\n\t\t\t\t\tel.contentWindow.postMessage( '{\"method\":\"pause\"}', '*' );\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif( options.unloadIframes === true ) {\n\t\t\t\t// Unload lazy-loaded iframes\n\t\t\t\tqueryAll( element, 'iframe[data-src]' ).forEach( el => {\n\t\t\t\t\t// Only removing the src doesn't actually unload the frame\n\t\t\t\t\t// in all browsers (Firefox) so we set it to blank first\n\t\t\t\t\tel.setAttribute( 'src', 'about:blank' );\n\t\t\t\t\tel.removeAttribute( 'src' );\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\n\t}\n\n}\n","/**\n * Handles the display of reveal.js' optional slide number.\n */\nexport default class SlideNumber {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t}\n\n\trender() {\n\n\t\tthis.element = document.createElement( 'div' );\n\t\tthis.element.className = 'slide-number';\n\t\tthis.Reveal.getRevealElement().appendChild( this.element );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tlet slideNumberDisplay = 'none';\n\t\tif( config.slideNumber && !this.Reveal.isPrintingPDF() ) {\n\t\t\tif( config.showSlideNumber === 'all' ) {\n\t\t\t\tslideNumberDisplay = 'block';\n\t\t\t}\n\t\t\telse if( config.showSlideNumber === 'speaker' && this.Reveal.isSpeakerNotes() ) {\n\t\t\t\tslideNumberDisplay = 'block';\n\t\t\t}\n\t\t}\n\n\t\tthis.element.style.display = slideNumberDisplay;\n\n\t}\n\n\t/**\n\t * Updates the slide number to match the current slide.\n\t */\n\tupdate() {\n\n\t\t// Update slide number if enabled\n\t\tif( this.Reveal.getConfig().slideNumber && this.element ) {\n\t\t\tthis.element.innerHTML = this.getSlideNumber();\n\t\t}\n\n\t}\n\n\t/**\n\t * Returns the HTML string corresponding to the current slide\n\t * number, including formatting.\n\t */\n\tgetSlideNumber( slide = this.Reveal.getCurrentSlide() ) {\n\n\t\tlet config = this.Reveal.getConfig();\n\t\tlet value;\n\t\tlet format = 'h.v';\n\n\t\tif ( typeof config.slideNumber === 'function' ) {\n\t\t\tvalue = config.slideNumber( slide );\n\t\t} else {\n\t\t\t// Check if a custom number format is available\n\t\t\tif( typeof config.slideNumber === 'string' ) {\n\t\t\t\tformat = config.slideNumber;\n\t\t\t}\n\n\t\t\t// If there are ONLY vertical slides in this deck, always use\n\t\t\t// a flattened slide number\n\t\t\tif( !/c/.test( format ) && this.Reveal.getHorizontalSlides().length === 1 ) {\n\t\t\t\tformat = 'c';\n\t\t\t}\n\n\t\t\t// Offset the current slide number by 1 to make it 1-indexed\n\t\t\tlet horizontalOffset = slide && slide.dataset.visibility === 'uncounted' ? 0 : 1;\n\n\t\t\tvalue = [];\n\t\t\tswitch( format ) {\n\t\t\t\tcase 'c':\n\t\t\t\t\tvalue.push( this.Reveal.getSlidePastCount( slide ) + horizontalOffset );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'c/t':\n\t\t\t\t\tvalue.push( this.Reveal.getSlidePastCount( slide ) + horizontalOffset, '/', this.Reveal.getTotalSlides() );\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tlet indices = this.Reveal.getIndices( slide );\n\t\t\t\t\tvalue.push( indices.h + horizontalOffset );\n\t\t\t\t\tlet sep = format === 'h/v' ? '/' : '.';\n\t\t\t\t\tif( this.Reveal.isVerticalSlide( slide ) ) value.push( sep, indices.v + 1 );\n\t\t\t}\n\t\t}\n\n\t\tlet url = '#' + this.Reveal.location.getHash( slide );\n\t\treturn this.formatNumber( value[0], value[1], value[2], url );\n\n\t}\n\n\t/**\n\t * Applies HTML formatting to a slide number before it's\n\t * written to the DOM.\n\t *\n\t * @param {number} a Current slide\n\t * @param {string} delimiter Character to separate slide numbers\n\t * @param {(number|*)} b Total slides\n\t * @param {HTMLElement} [url='#'+locationHash()] The url to link to\n\t * @return {string} HTML string fragment\n\t */\n\tformatNumber( a, delimiter, b, url = '#' + this.Reveal.location.getHash() ) {\n\n\t\tif( typeof b === 'number' && !isNaN( b ) ) {\n\t\t\treturn `\n\t\t\t\t\t${a} \n\t\t\t\t\t${delimiter} \n\t\t\t\t\t${b} \n\t\t\t\t\t `;\n\t\t}\n\t\telse {\n\t\t\treturn `\n\t\t\t\t\t${a} \n\t\t\t\t\t `;\n\t\t}\n\n\t}\n\n\tdestroy() {\n\n\t\tthis.element.remove();\n\n\t}\n\n}","/**\n * Converts various color input formats to an {r:0,g:0,b:0} object.\n *\n * @param {string} color The string representation of a color\n * @example\n * colorToRgb('#000');\n * @example\n * colorToRgb('#000000');\n * @example\n * colorToRgb('rgb(0,0,0)');\n * @example\n * colorToRgb('rgba(0,0,0)');\n *\n * @return {{r: number, g: number, b: number, [a]: number}|null}\n */\nexport const colorToRgb = ( color ) => {\n\n\tlet hex3 = color.match( /^#([0-9a-f]{3})$/i );\n\tif( hex3 && hex3[1] ) {\n\t\thex3 = hex3[1];\n\t\treturn {\n\t\t\tr: parseInt( hex3.charAt( 0 ), 16 ) * 0x11,\n\t\t\tg: parseInt( hex3.charAt( 1 ), 16 ) * 0x11,\n\t\t\tb: parseInt( hex3.charAt( 2 ), 16 ) * 0x11\n\t\t};\n\t}\n\n\tlet hex6 = color.match( /^#([0-9a-f]{6})$/i );\n\tif( hex6 && hex6[1] ) {\n\t\thex6 = hex6[1];\n\t\treturn {\n\t\t\tr: parseInt( hex6.slice( 0, 2 ), 16 ),\n\t\t\tg: parseInt( hex6.slice( 2, 4 ), 16 ),\n\t\t\tb: parseInt( hex6.slice( 4, 6 ), 16 )\n\t\t};\n\t}\n\n\tlet rgb = color.match( /^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i );\n\tif( rgb ) {\n\t\treturn {\n\t\t\tr: parseInt( rgb[1], 10 ),\n\t\t\tg: parseInt( rgb[2], 10 ),\n\t\t\tb: parseInt( rgb[3], 10 )\n\t\t};\n\t}\n\n\tlet rgba = color.match( /^rgba\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\,\\s*([\\d]+|[\\d]*.[\\d]+)\\s*\\)$/i );\n\tif( rgba ) {\n\t\treturn {\n\t\t\tr: parseInt( rgba[1], 10 ),\n\t\t\tg: parseInt( rgba[2], 10 ),\n\t\t\tb: parseInt( rgba[3], 10 ),\n\t\t\ta: parseFloat( rgba[4] )\n\t\t};\n\t}\n\n\treturn null;\n\n}\n\n/**\n * Calculates brightness on a scale of 0-255.\n *\n * @param {string} color See colorToRgb for supported formats.\n * @see {@link colorToRgb}\n */\nexport const colorBrightness = ( color ) => {\n\n\tif( typeof color === 'string' ) color = colorToRgb( color );\n\n\tif( color ) {\n\t\treturn ( color.r * 299 + color.g * 587 + color.b * 114 ) / 1000;\n\t}\n\n\treturn null;\n\n}","import { queryAll } from '../utils/util.js'\nimport { colorToRgb, colorBrightness } from '../utils/color.js'\n\n/**\n * Creates and updates slide backgrounds.\n */\nexport default class Backgrounds {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t}\n\n\trender() {\n\n\t\tthis.element = document.createElement( 'div' );\n\t\tthis.element.className = 'backgrounds';\n\t\tthis.Reveal.getRevealElement().appendChild( this.element );\n\n\t}\n\n\t/**\n\t * Creates the slide background elements and appends them\n\t * to the background container. One element is created per\n\t * slide no matter if the given slide has visible background.\n\t */\n\tcreate() {\n\n\t\t// Clear prior backgrounds\n\t\tthis.element.innerHTML = '';\n\t\tthis.element.classList.add( 'no-transition' );\n\n\t\t// Iterate over all horizontal slides\n\t\tthis.Reveal.getHorizontalSlides().forEach( slideh => {\n\n\t\t\tlet backgroundStack = this.createBackground( slideh, this.element );\n\n\t\t\t// Iterate over all vertical slides\n\t\t\tqueryAll( slideh, 'section' ).forEach( slidev => {\n\n\t\t\t\tthis.createBackground( slidev, backgroundStack );\n\n\t\t\t\tbackgroundStack.classList.add( 'stack' );\n\n\t\t\t} );\n\n\t\t} );\n\n\t\t// Add parallax background if specified\n\t\tif( this.Reveal.getConfig().parallaxBackgroundImage ) {\n\n\t\t\tthis.element.style.backgroundImage = 'url(\"' + this.Reveal.getConfig().parallaxBackgroundImage + '\")';\n\t\t\tthis.element.style.backgroundSize = this.Reveal.getConfig().parallaxBackgroundSize;\n\t\t\tthis.element.style.backgroundRepeat = this.Reveal.getConfig().parallaxBackgroundRepeat;\n\t\t\tthis.element.style.backgroundPosition = this.Reveal.getConfig().parallaxBackgroundPosition;\n\n\t\t\t// Make sure the below properties are set on the element - these properties are\n\t\t\t// needed for proper transitions to be set on the element via CSS. To remove\n\t\t\t// annoying background slide-in effect when the presentation starts, apply\n\t\t\t// these properties after short time delay\n\t\t\tsetTimeout( () => {\n\t\t\t\tthis.Reveal.getRevealElement().classList.add( 'has-parallax-background' );\n\t\t\t}, 1 );\n\n\t\t}\n\t\telse {\n\n\t\t\tthis.element.style.backgroundImage = '';\n\t\t\tthis.Reveal.getRevealElement().classList.remove( 'has-parallax-background' );\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Creates a background for the given slide.\n\t *\n\t * @param {HTMLElement} slide\n\t * @param {HTMLElement} container The element that the background\n\t * should be appended to\n\t * @return {HTMLElement} New background div\n\t */\n\tcreateBackground( slide, container ) {\n\n\t\t// Main slide background element\n\t\tlet element = document.createElement( 'div' );\n\t\telement.className = 'slide-background ' + slide.className.replace( /present|past|future/, '' );\n\n\t\t// Inner background element that wraps images/videos/iframes\n\t\tlet contentElement = document.createElement( 'div' );\n\t\tcontentElement.className = 'slide-background-content';\n\n\t\telement.appendChild( contentElement );\n\t\tcontainer.appendChild( element );\n\n\t\tslide.slideBackgroundElement = element;\n\t\tslide.slideBackgroundContentElement = contentElement;\n\n\t\t// Syncs the background to reflect all current background settings\n\t\tthis.sync( slide );\n\n\t\treturn element;\n\n\t}\n\n\t/**\n\t * Renders all of the visual properties of a slide background\n\t * based on the various background attributes.\n\t *\n\t * @param {HTMLElement} slide\n\t */\n\tsync( slide ) {\n\n\t\tconst element = slide.slideBackgroundElement,\n\t\t\tcontentElement = slide.slideBackgroundContentElement;\n\n\t\tconst data = {\n\t\t\tbackground: slide.getAttribute( 'data-background' ),\n\t\t\tbackgroundSize: slide.getAttribute( 'data-background-size' ),\n\t\t\tbackgroundImage: slide.getAttribute( 'data-background-image' ),\n\t\t\tbackgroundVideo: slide.getAttribute( 'data-background-video' ),\n\t\t\tbackgroundIframe: slide.getAttribute( 'data-background-iframe' ),\n\t\t\tbackgroundColor: slide.getAttribute( 'data-background-color' ),\n\t\t\tbackgroundRepeat: slide.getAttribute( 'data-background-repeat' ),\n\t\t\tbackgroundPosition: slide.getAttribute( 'data-background-position' ),\n\t\t\tbackgroundTransition: slide.getAttribute( 'data-background-transition' ),\n\t\t\tbackgroundOpacity: slide.getAttribute( 'data-background-opacity' ),\n\t\t};\n\n\t\tconst dataPreload = slide.hasAttribute( 'data-preload' );\n\n\t\t// Reset the prior background state in case this is not the\n\t\t// initial sync\n\t\tslide.classList.remove( 'has-dark-background' );\n\t\tslide.classList.remove( 'has-light-background' );\n\n\t\telement.removeAttribute( 'data-loaded' );\n\t\telement.removeAttribute( 'data-background-hash' );\n\t\telement.removeAttribute( 'data-background-size' );\n\t\telement.removeAttribute( 'data-background-transition' );\n\t\telement.style.backgroundColor = '';\n\n\t\tcontentElement.style.backgroundSize = '';\n\t\tcontentElement.style.backgroundRepeat = '';\n\t\tcontentElement.style.backgroundPosition = '';\n\t\tcontentElement.style.backgroundImage = '';\n\t\tcontentElement.style.opacity = '';\n\t\tcontentElement.innerHTML = '';\n\n\t\tif( data.background ) {\n\t\t\t// Auto-wrap image urls in url(...)\n\t\t\tif( /^(http|file|\\/\\/)/gi.test( data.background ) || /\\.(svg|png|jpg|jpeg|gif|bmp)([?#\\s]|$)/gi.test( data.background ) ) {\n\t\t\t\tslide.setAttribute( 'data-background-image', data.background );\n\t\t\t}\n\t\t\telse {\n\t\t\t\telement.style.background = data.background;\n\t\t\t}\n\t\t}\n\n\t\t// Create a hash for this combination of background settings.\n\t\t// This is used to determine when two slide backgrounds are\n\t\t// the same.\n\t\tif( data.background || data.backgroundColor || data.backgroundImage || data.backgroundVideo || data.backgroundIframe ) {\n\t\t\telement.setAttribute( 'data-background-hash', data.background +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundSize +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundImage +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundVideo +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundIframe +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundColor +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundRepeat +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundPosition +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundTransition +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundOpacity );\n\t\t}\n\n\t\t// Additional and optional background properties\n\t\tif( data.backgroundSize ) element.setAttribute( 'data-background-size', data.backgroundSize );\n\t\tif( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor;\n\t\tif( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition );\n\n\t\tif( dataPreload ) element.setAttribute( 'data-preload', '' );\n\n\t\t// Background image options are set on the content wrapper\n\t\tif( data.backgroundSize ) contentElement.style.backgroundSize = data.backgroundSize;\n\t\tif( data.backgroundRepeat ) contentElement.style.backgroundRepeat = data.backgroundRepeat;\n\t\tif( data.backgroundPosition ) contentElement.style.backgroundPosition = data.backgroundPosition;\n\t\tif( data.backgroundOpacity ) contentElement.style.opacity = data.backgroundOpacity;\n\n\t\t// If this slide has a background color, we add a class that\n\t\t// signals if it is light or dark. If the slide has no background\n\t\t// color, no class will be added\n\t\tlet contrastColor = data.backgroundColor;\n\n\t\t// If no bg color was found, or it cannot be converted by colorToRgb, check the computed background\n\t\tif( !contrastColor || !colorToRgb( contrastColor ) ) {\n\t\t\tlet computedBackgroundStyle = window.getComputedStyle( element );\n\t\t\tif( computedBackgroundStyle && computedBackgroundStyle.backgroundColor ) {\n\t\t\t\tcontrastColor = computedBackgroundStyle.backgroundColor;\n\t\t\t}\n\t\t}\n\n\t\tif( contrastColor ) {\n\t\t\tconst rgb = colorToRgb( contrastColor );\n\n\t\t\t// Ignore fully transparent backgrounds. Some browsers return\n\t\t\t// rgba(0,0,0,0) when reading the computed background color of\n\t\t\t// an element with no background\n\t\t\tif( rgb && rgb.a !== 0 ) {\n\t\t\t\tif( colorBrightness( contrastColor ) < 128 ) {\n\t\t\t\t\tslide.classList.add( 'has-dark-background' );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tslide.classList.add( 'has-light-background' );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Updates the background elements to reflect the current\n\t * slide.\n\t *\n\t * @param {boolean} includeAll If true, the backgrounds of\n\t * all vertical slides (not just the present) will be updated.\n\t */\n\tupdate( includeAll = false ) {\n\n\t\tlet currentSlide = this.Reveal.getCurrentSlide();\n\t\tlet indices = this.Reveal.getIndices();\n\n\t\tlet currentBackground = null;\n\n\t\t// Reverse past/future classes when in RTL mode\n\t\tlet horizontalPast = this.Reveal.getConfig().rtl ? 'future' : 'past',\n\t\t\thorizontalFuture = this.Reveal.getConfig().rtl ? 'past' : 'future';\n\n\t\t// Update the classes of all backgrounds to match the\n\t\t// states of their slides (past/present/future)\n\t\tArray.from( this.element.childNodes ).forEach( ( backgroundh, h ) => {\n\n\t\t\tbackgroundh.classList.remove( 'past', 'present', 'future' );\n\n\t\t\tif( h < indices.h ) {\n\t\t\t\tbackgroundh.classList.add( horizontalPast );\n\t\t\t}\n\t\t\telse if ( h > indices.h ) {\n\t\t\t\tbackgroundh.classList.add( horizontalFuture );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbackgroundh.classList.add( 'present' );\n\n\t\t\t\t// Store a reference to the current background element\n\t\t\t\tcurrentBackground = backgroundh;\n\t\t\t}\n\n\t\t\tif( includeAll || h === indices.h ) {\n\t\t\t\tqueryAll( backgroundh, '.slide-background' ).forEach( ( backgroundv, v ) => {\n\n\t\t\t\t\tbackgroundv.classList.remove( 'past', 'present', 'future' );\n\n\t\t\t\t\tif( v < indices.v ) {\n\t\t\t\t\t\tbackgroundv.classList.add( 'past' );\n\t\t\t\t\t}\n\t\t\t\t\telse if ( v > indices.v ) {\n\t\t\t\t\t\tbackgroundv.classList.add( 'future' );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tbackgroundv.classList.add( 'present' );\n\n\t\t\t\t\t\t// Only if this is the present horizontal and vertical slide\n\t\t\t\t\t\tif( h === indices.h ) currentBackground = backgroundv;\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\t\t\t}\n\n\t\t} );\n\n\t\t// Stop content inside of previous backgrounds\n\t\tif( this.previousBackground ) {\n\n\t\t\tthis.Reveal.slideContent.stopEmbeddedContent( this.previousBackground, { unloadIframes: !this.Reveal.slideContent.shouldPreload( this.previousBackground ) } );\n\n\t\t}\n\n\t\t// Start content in the current background\n\t\tif( currentBackground ) {\n\n\t\t\tthis.Reveal.slideContent.startEmbeddedContent( currentBackground );\n\n\t\t\tlet currentBackgroundContent = currentBackground.querySelector( '.slide-background-content' );\n\t\t\tif( currentBackgroundContent ) {\n\n\t\t\t\tlet backgroundImageURL = currentBackgroundContent.style.backgroundImage || '';\n\n\t\t\t\t// Restart GIFs (doesn't work in Firefox)\n\t\t\t\tif( /\\.gif/i.test( backgroundImageURL ) ) {\n\t\t\t\t\tcurrentBackgroundContent.style.backgroundImage = '';\n\t\t\t\t\twindow.getComputedStyle( currentBackgroundContent ).opacity;\n\t\t\t\t\tcurrentBackgroundContent.style.backgroundImage = backgroundImageURL;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Don't transition between identical backgrounds. This\n\t\t\t// prevents unwanted flicker.\n\t\t\tlet previousBackgroundHash = this.previousBackground ? this.previousBackground.getAttribute( 'data-background-hash' ) : null;\n\t\t\tlet currentBackgroundHash = currentBackground.getAttribute( 'data-background-hash' );\n\t\t\tif( currentBackgroundHash && currentBackgroundHash === previousBackgroundHash && currentBackground !== this.previousBackground ) {\n\t\t\t\tthis.element.classList.add( 'no-transition' );\n\t\t\t}\n\n\t\t\tthis.previousBackground = currentBackground;\n\n\t\t}\n\n\t\t// If there's a background brightness flag for this slide,\n\t\t// bubble it to the .reveal container\n\t\tif( currentSlide ) {\n\t\t\t[ 'has-light-background', 'has-dark-background' ].forEach( classToBubble => {\n\t\t\t\tif( currentSlide.classList.contains( classToBubble ) ) {\n\t\t\t\t\tthis.Reveal.getRevealElement().classList.add( classToBubble );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.getRevealElement().classList.remove( classToBubble );\n\t\t\t\t}\n\t\t\t}, this );\n\t\t}\n\n\t\t// Allow the first background to apply without transition\n\t\tsetTimeout( () => {\n\t\t\tthis.element.classList.remove( 'no-transition' );\n\t\t}, 1 );\n\n\t}\n\n\t/**\n\t * Updates the position of the parallax background based\n\t * on the current slide index.\n\t */\n\tupdateParallax() {\n\n\t\tlet indices = this.Reveal.getIndices();\n\n\t\tif( this.Reveal.getConfig().parallaxBackgroundImage ) {\n\n\t\t\tlet horizontalSlides = this.Reveal.getHorizontalSlides(),\n\t\t\t\tverticalSlides = this.Reveal.getVerticalSlides();\n\n\t\t\tlet backgroundSize = this.element.style.backgroundSize.split( ' ' ),\n\t\t\t\tbackgroundWidth, backgroundHeight;\n\n\t\t\tif( backgroundSize.length === 1 ) {\n\t\t\t\tbackgroundWidth = backgroundHeight = parseInt( backgroundSize[0], 10 );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbackgroundWidth = parseInt( backgroundSize[0], 10 );\n\t\t\t\tbackgroundHeight = parseInt( backgroundSize[1], 10 );\n\t\t\t}\n\n\t\t\tlet slideWidth = this.element.offsetWidth,\n\t\t\t\thorizontalSlideCount = horizontalSlides.length,\n\t\t\t\thorizontalOffsetMultiplier,\n\t\t\t\thorizontalOffset;\n\n\t\t\tif( typeof this.Reveal.getConfig().parallaxBackgroundHorizontal === 'number' ) {\n\t\t\t\thorizontalOffsetMultiplier = this.Reveal.getConfig().parallaxBackgroundHorizontal;\n\t\t\t}\n\t\t\telse {\n\t\t\t\thorizontalOffsetMultiplier = horizontalSlideCount > 1 ? ( backgroundWidth - slideWidth ) / ( horizontalSlideCount-1 ) : 0;\n\t\t\t}\n\n\t\t\thorizontalOffset = horizontalOffsetMultiplier * indices.h * -1;\n\n\t\t\tlet slideHeight = this.element.offsetHeight,\n\t\t\t\tverticalSlideCount = verticalSlides.length,\n\t\t\t\tverticalOffsetMultiplier,\n\t\t\t\tverticalOffset;\n\n\t\t\tif( typeof this.Reveal.getConfig().parallaxBackgroundVertical === 'number' ) {\n\t\t\t\tverticalOffsetMultiplier = this.Reveal.getConfig().parallaxBackgroundVertical;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tverticalOffsetMultiplier = ( backgroundHeight - slideHeight ) / ( verticalSlideCount-1 );\n\t\t\t}\n\n\t\t\tverticalOffset = verticalSlideCount > 0 ? verticalOffsetMultiplier * indices.v : 0;\n\n\t\t\tthis.element.style.backgroundPosition = horizontalOffset + 'px ' + -verticalOffset + 'px';\n\n\t\t}\n\n\t}\n\n\tdestroy() {\n\n\t\tthis.element.remove();\n\n\t}\n\n}\n","\nexport const SLIDES_SELECTOR = '.slides section';\nexport const HORIZONTAL_SLIDES_SELECTOR = '.slides>section';\nexport const VERTICAL_SLIDES_SELECTOR = '.slides>section.present>section';\n\n// Methods that may not be invoked via the postMessage API\nexport const POST_MESSAGE_METHOD_BLACKLIST = /registerPlugin|registerKeyboardShortcut|addKeyBinding|addEventListener/;\n\n// Regex for retrieving the fragment style from a class attribute\nexport const FRAGMENT_STYLE_REGEX = /fade-(down|up|right|left|out|in-then-out|in-then-semi-out)|semi-fade-out|current-visible|shrink|grow/;","import { queryAll, extend, createStyleSheet, matches, closest } from '../utils/util.js'\nimport { FRAGMENT_STYLE_REGEX } from '../utils/constants.js'\n\n// Counter used to generate unique IDs for auto-animated elements\nlet autoAnimateCounter = 0;\n\n/**\n * Automatically animates matching elements across\n * slides with the [data-auto-animate] attribute.\n */\nexport default class AutoAnimate {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t}\n\n\t/**\n\t * Runs an auto-animation between the given slides.\n\t *\n\t * @param {HTMLElement} fromSlide\n\t * @param {HTMLElement} toSlide\n\t */\n\trun( fromSlide, toSlide ) {\n\n\t\t// Clean up after prior animations\n\t\tthis.reset();\n\n\t\tlet allSlides = this.Reveal.getSlides();\n\t\tlet toSlideIndex = allSlides.indexOf( toSlide );\n\t\tlet fromSlideIndex = allSlides.indexOf( fromSlide );\n\n\t\t// Ensure that both slides are auto-animate targets with the same data-auto-animate-id value\n\t\t// (including null if absent on both) and that data-auto-animate-restart isn't set on the\n\t\t// physically latter slide (independent of slide direction)\n\t\tif( fromSlide.hasAttribute( 'data-auto-animate' ) && toSlide.hasAttribute( 'data-auto-animate' )\n\t\t\t\t&& fromSlide.getAttribute( 'data-auto-animate-id' ) === toSlide.getAttribute( 'data-auto-animate-id' ) \n\t\t\t\t&& !( toSlideIndex > fromSlideIndex ? toSlide : fromSlide ).hasAttribute( 'data-auto-animate-restart' ) ) {\n\n\t\t\t// Create a new auto-animate sheet\n\t\t\tthis.autoAnimateStyleSheet = this.autoAnimateStyleSheet || createStyleSheet();\n\n\t\t\tlet animationOptions = this.getAutoAnimateOptions( toSlide );\n\n\t\t\t// Set our starting state\n\t\t\tfromSlide.dataset.autoAnimate = 'pending';\n\t\t\ttoSlide.dataset.autoAnimate = 'pending';\n\n\t\t\t// Flag the navigation direction, needed for fragment buildup\n\t\t\tanimationOptions.slideDirection = toSlideIndex > fromSlideIndex ? 'forward' : 'backward';\n\n\t\t\t// Inject our auto-animate styles for this transition\n\t\t\tlet css = this.getAutoAnimatableElements( fromSlide, toSlide ).map( elements => {\n\t\t\t\treturn this.autoAnimateElements( elements.from, elements.to, elements.options || {}, animationOptions, autoAnimateCounter++ );\n\t\t\t} );\n\n\t\t\t// Animate unmatched elements, if enabled\n\t\t\tif( toSlide.dataset.autoAnimateUnmatched !== 'false' && this.Reveal.getConfig().autoAnimateUnmatched === true ) {\n\n\t\t\t\t// Our default timings for unmatched elements\n\t\t\t\tlet defaultUnmatchedDuration = animationOptions.duration * 0.8,\n\t\t\t\t\tdefaultUnmatchedDelay = animationOptions.duration * 0.2;\n\n\t\t\t\tthis.getUnmatchedAutoAnimateElements( toSlide ).forEach( unmatchedElement => {\n\n\t\t\t\t\tlet unmatchedOptions = this.getAutoAnimateOptions( unmatchedElement, animationOptions );\n\t\t\t\t\tlet id = 'unmatched';\n\n\t\t\t\t\t// If there is a duration or delay set specifically for this\n\t\t\t\t\t// element our unmatched elements should adhere to those\n\t\t\t\t\tif( unmatchedOptions.duration !== animationOptions.duration || unmatchedOptions.delay !== animationOptions.delay ) {\n\t\t\t\t\t\tid = 'unmatched-' + autoAnimateCounter++;\n\t\t\t\t\t\tcss.push( `[data-auto-animate=\"running\"] [data-auto-animate-target=\"${id}\"] { transition: opacity ${unmatchedOptions.duration}s ease ${unmatchedOptions.delay}s; }` );\n\t\t\t\t\t}\n\n\t\t\t\t\tunmatchedElement.dataset.autoAnimateTarget = id;\n\n\t\t\t\t}, this );\n\n\t\t\t\t// Our default transition for unmatched elements\n\t\t\t\tcss.push( `[data-auto-animate=\"running\"] [data-auto-animate-target=\"unmatched\"] { transition: opacity ${defaultUnmatchedDuration}s ease ${defaultUnmatchedDelay}s; }` );\n\n\t\t\t}\n\n\t\t\t// Setting the whole chunk of CSS at once is the most\n\t\t\t// efficient way to do this. Using sheet.insertRule\n\t\t\t// is multiple factors slower.\n\t\t\tthis.autoAnimateStyleSheet.innerHTML = css.join( '' );\n\n\t\t\t// Start the animation next cycle\n\t\t\trequestAnimationFrame( () => {\n\t\t\t\tif( this.autoAnimateStyleSheet ) {\n\t\t\t\t\t// This forces our newly injected styles to be applied in Firefox\n\t\t\t\t\tgetComputedStyle( this.autoAnimateStyleSheet ).fontWeight;\n\n\t\t\t\t\ttoSlide.dataset.autoAnimate = 'running';\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\ttype: 'autoanimate',\n\t\t\t\tdata: {\n\t\t\t\t\tfromSlide,\n\t\t\t\t\ttoSlide,\n\t\t\t\t\tsheet: this.autoAnimateStyleSheet\n\t\t\t\t}\n\t\t\t});\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Rolls back all changes that we've made to the DOM so\n\t * that as part of animating.\n\t */\n\treset() {\n\n\t\t// Reset slides\n\t\tqueryAll( this.Reveal.getRevealElement(), '[data-auto-animate]:not([data-auto-animate=\"\"])' ).forEach( element => {\n\t\t\telement.dataset.autoAnimate = '';\n\t\t} );\n\n\t\t// Reset elements\n\t\tqueryAll( this.Reveal.getRevealElement(), '[data-auto-animate-target]' ).forEach( element => {\n\t\t\tdelete element.dataset.autoAnimateTarget;\n\t\t} );\n\n\t\t// Remove the animation sheet\n\t\tif( this.autoAnimateStyleSheet && this.autoAnimateStyleSheet.parentNode ) {\n\t\t\tthis.autoAnimateStyleSheet.parentNode.removeChild( this.autoAnimateStyleSheet );\n\t\t\tthis.autoAnimateStyleSheet = null;\n\t\t}\n\n\t}\n\n\t/**\n\t * Creates a FLIP animation where the `to` element starts out\n\t * in the `from` element position and animates to its original\n\t * state.\n\t *\n\t * @param {HTMLElement} from\n\t * @param {HTMLElement} to\n\t * @param {Object} elementOptions Options for this element pair\n\t * @param {Object} animationOptions Options set at the slide level\n\t * @param {String} id Unique ID that we can use to identify this\n\t * auto-animate element in the DOM\n\t */\n\tautoAnimateElements( from, to, elementOptions, animationOptions, id ) {\n\n\t\t// 'from' elements are given a data-auto-animate-target with no value,\n\t\t// 'to' elements are are given a data-auto-animate-target with an ID\n\t\tfrom.dataset.autoAnimateTarget = '';\n\t\tto.dataset.autoAnimateTarget = id;\n\n\t\t// Each element may override any of the auto-animate options\n\t\t// like transition easing, duration and delay via data-attributes\n\t\tlet options = this.getAutoAnimateOptions( to, animationOptions );\n\n\t\t// If we're using a custom element matcher the element options\n\t\t// may contain additional transition overrides\n\t\tif( typeof elementOptions.delay !== 'undefined' ) options.delay = elementOptions.delay;\n\t\tif( typeof elementOptions.duration !== 'undefined' ) options.duration = elementOptions.duration;\n\t\tif( typeof elementOptions.easing !== 'undefined' ) options.easing = elementOptions.easing;\n\n\t\tlet fromProps = this.getAutoAnimatableProperties( 'from', from, elementOptions ),\n\t\t\ttoProps = this.getAutoAnimatableProperties( 'to', to, elementOptions );\n\n\t\t// Maintain fragment visibility for matching elements when\n\t\t// we're navigating forwards, this way the viewer won't need\n\t\t// to step through the same fragments twice\n\t\tif( to.classList.contains( 'fragment' ) ) {\n\n\t\t\t// Don't auto-animate the opacity of fragments to avoid\n\t\t\t// conflicts with fragment animations\n\t\t\tdelete toProps.styles['opacity'];\n\n\t\t\tif( from.classList.contains( 'fragment' ) ) {\n\n\t\t\t\tlet fromFragmentStyle = ( from.className.match( FRAGMENT_STYLE_REGEX ) || [''] )[0];\n\t\t\t\tlet toFragmentStyle = ( to.className.match( FRAGMENT_STYLE_REGEX ) || [''] )[0];\n\n\t\t\t\t// Only skip the fragment if the fragment animation style\n\t\t\t\t// remains unchanged\n\t\t\t\tif( fromFragmentStyle === toFragmentStyle && animationOptions.slideDirection === 'forward' ) {\n\t\t\t\t\tto.classList.add( 'visible', 'disabled' );\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// If translation and/or scaling are enabled, css transform\n\t\t// the 'to' element so that it matches the position and size\n\t\t// of the 'from' element\n\t\tif( elementOptions.translate !== false || elementOptions.scale !== false ) {\n\n\t\t\tlet presentationScale = this.Reveal.getScale();\n\n\t\t\tlet delta = {\n\t\t\t\tx: ( fromProps.x - toProps.x ) / presentationScale,\n\t\t\t\ty: ( fromProps.y - toProps.y ) / presentationScale,\n\t\t\t\tscaleX: fromProps.width / toProps.width,\n\t\t\t\tscaleY: fromProps.height / toProps.height\n\t\t\t};\n\n\t\t\t// Limit decimal points to avoid 0.0001px blur and stutter\n\t\t\tdelta.x = Math.round( delta.x * 1000 ) / 1000;\n\t\t\tdelta.y = Math.round( delta.y * 1000 ) / 1000;\n\t\t\tdelta.scaleX = Math.round( delta.scaleX * 1000 ) / 1000;\n\t\t\tdelta.scaleX = Math.round( delta.scaleX * 1000 ) / 1000;\n\n\t\t\tlet translate = elementOptions.translate !== false && ( delta.x !== 0 || delta.y !== 0 ),\n\t\t\t\tscale = elementOptions.scale !== false && ( delta.scaleX !== 0 || delta.scaleY !== 0 );\n\n\t\t\t// No need to transform if nothing's changed\n\t\t\tif( translate || scale ) {\n\n\t\t\t\tlet transform = [];\n\n\t\t\t\tif( translate ) transform.push( `translate(${delta.x}px, ${delta.y}px)` );\n\t\t\t\tif( scale ) transform.push( `scale(${delta.scaleX}, ${delta.scaleY})` );\n\n\t\t\t\tfromProps.styles['transform'] = transform.join( ' ' );\n\t\t\t\tfromProps.styles['transform-origin'] = 'top left';\n\n\t\t\t\ttoProps.styles['transform'] = 'none';\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Delete all unchanged 'to' styles\n\t\tfor( let propertyName in toProps.styles ) {\n\t\t\tconst toValue = toProps.styles[propertyName];\n\t\t\tconst fromValue = fromProps.styles[propertyName];\n\n\t\t\tif( toValue === fromValue ) {\n\t\t\t\tdelete toProps.styles[propertyName];\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// If these property values were set via a custom matcher providing\n\t\t\t\t// an explicit 'from' and/or 'to' value, we always inject those values.\n\t\t\t\tif( toValue.explicitValue === true ) {\n\t\t\t\t\ttoProps.styles[propertyName] = toValue.value;\n\t\t\t\t}\n\n\t\t\t\tif( fromValue.explicitValue === true ) {\n\t\t\t\t\tfromProps.styles[propertyName] = fromValue.value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet css = '';\n\n\t\tlet toStyleProperties = Object.keys( toProps.styles );\n\n\t\t// Only create animate this element IF at least one style\n\t\t// property has changed\n\t\tif( toStyleProperties.length > 0 ) {\n\n\t\t\t// Instantly move to the 'from' state\n\t\t\tfromProps.styles['transition'] = 'none';\n\n\t\t\t// Animate towards the 'to' state\n\t\t\ttoProps.styles['transition'] = `all ${options.duration}s ${options.easing} ${options.delay}s`;\n\t\t\ttoProps.styles['transition-property'] = toStyleProperties.join( ', ' );\n\t\t\ttoProps.styles['will-change'] = toStyleProperties.join( ', ' );\n\n\t\t\t// Build up our custom CSS. We need to override inline styles\n\t\t\t// so we need to make our styles vErY IMPORTANT!1!!\n\t\t\tlet fromCSS = Object.keys( fromProps.styles ).map( propertyName => {\n\t\t\t\treturn propertyName + ': ' + fromProps.styles[propertyName] + ' !important;';\n\t\t\t} ).join( '' );\n\n\t\t\tlet toCSS = Object.keys( toProps.styles ).map( propertyName => {\n\t\t\t\treturn propertyName + ': ' + toProps.styles[propertyName] + ' !important;';\n\t\t\t} ).join( '' );\n\n\t\t\tcss = \t'[data-auto-animate-target=\"'+ id +'\"] {'+ fromCSS +'}' +\n\t\t\t\t\t'[data-auto-animate=\"running\"] [data-auto-animate-target=\"'+ id +'\"] {'+ toCSS +'}';\n\n\t\t}\n\n\t\treturn css;\n\n\t}\n\n\t/**\n\t * Returns the auto-animate options for the given element.\n\t *\n\t * @param {HTMLElement} element Element to pick up options\n\t * from, either a slide or an animation target\n\t * @param {Object} [inheritedOptions] Optional set of existing\n\t * options\n\t */\n\tgetAutoAnimateOptions( element, inheritedOptions ) {\n\n\t\tlet options = {\n\t\t\teasing: this.Reveal.getConfig().autoAnimateEasing,\n\t\t\tduration: this.Reveal.getConfig().autoAnimateDuration,\n\t\t\tdelay: 0\n\t\t};\n\n\t\toptions = extend( options, inheritedOptions );\n\n\t\t// Inherit options from parent elements\n\t\tif( element.parentNode ) {\n\t\t\tlet autoAnimatedParent = closest( element.parentNode, '[data-auto-animate-target]' );\n\t\t\tif( autoAnimatedParent ) {\n\t\t\t\toptions = this.getAutoAnimateOptions( autoAnimatedParent, options );\n\t\t\t}\n\t\t}\n\n\t\tif( element.dataset.autoAnimateEasing ) {\n\t\t\toptions.easing = element.dataset.autoAnimateEasing;\n\t\t}\n\n\t\tif( element.dataset.autoAnimateDuration ) {\n\t\t\toptions.duration = parseFloat( element.dataset.autoAnimateDuration );\n\t\t}\n\n\t\tif( element.dataset.autoAnimateDelay ) {\n\t\t\toptions.delay = parseFloat( element.dataset.autoAnimateDelay );\n\t\t}\n\n\t\treturn options;\n\n\t}\n\n\t/**\n\t * Returns an object containing all of the properties\n\t * that can be auto-animated for the given element and\n\t * their current computed values.\n\t *\n\t * @param {String} direction 'from' or 'to'\n\t */\n\tgetAutoAnimatableProperties( direction, element, elementOptions ) {\n\n\t\tlet config = this.Reveal.getConfig();\n\n\t\tlet properties = { styles: [] };\n\n\t\t// Position and size\n\t\tif( elementOptions.translate !== false || elementOptions.scale !== false ) {\n\t\t\tlet bounds;\n\n\t\t\t// Custom auto-animate may optionally return a custom tailored\n\t\t\t// measurement function\n\t\t\tif( typeof elementOptions.measure === 'function' ) {\n\t\t\t\tbounds = elementOptions.measure( element );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif( config.center ) {\n\t\t\t\t\t// More precise, but breaks when used in combination\n\t\t\t\t\t// with zoom for scaling the deck ¯\\_(ツ)_/¯\n\t\t\t\t\tbounds = element.getBoundingClientRect();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tlet scale = this.Reveal.getScale();\n\t\t\t\t\tbounds = {\n\t\t\t\t\t\tx: element.offsetLeft * scale,\n\t\t\t\t\t\ty: element.offsetTop * scale,\n\t\t\t\t\t\twidth: element.offsetWidth * scale,\n\t\t\t\t\t\theight: element.offsetHeight * scale\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tproperties.x = bounds.x;\n\t\t\tproperties.y = bounds.y;\n\t\t\tproperties.width = bounds.width;\n\t\t\tproperties.height = bounds.height;\n\t\t}\n\n\t\tconst computedStyles = getComputedStyle( element );\n\n\t\t// CSS styles\n\t\t( elementOptions.styles || config.autoAnimateStyles ).forEach( style => {\n\t\t\tlet value;\n\n\t\t\t// `style` is either the property name directly, or an object\n\t\t\t// definition of a style property\n\t\t\tif( typeof style === 'string' ) style = { property: style };\n\n\t\t\tif( typeof style.from !== 'undefined' && direction === 'from' ) {\n\t\t\t\tvalue = { value: style.from, explicitValue: true };\n\t\t\t}\n\t\t\telse if( typeof style.to !== 'undefined' && direction === 'to' ) {\n\t\t\t\tvalue = { value: style.to, explicitValue: true };\n\t\t\t}\n\t\t\telse {\n\t\t\t\tvalue = computedStyles[style.property];\n\t\t\t}\n\n\t\t\tif( value !== '' ) {\n\t\t\t\tproperties.styles[style.property] = value;\n\t\t\t}\n\t\t} );\n\n\t\treturn properties;\n\n\t}\n\n\t/**\n\t * Get a list of all element pairs that we can animate\n\t * between the given slides.\n\t *\n\t * @param {HTMLElement} fromSlide\n\t * @param {HTMLElement} toSlide\n\t *\n\t * @return {Array} Each value is an array where [0] is\n\t * the element we're animating from and [1] is the\n\t * element we're animating to\n\t */\n\tgetAutoAnimatableElements( fromSlide, toSlide ) {\n\n\t\tlet matcher = typeof this.Reveal.getConfig().autoAnimateMatcher === 'function' ? this.Reveal.getConfig().autoAnimateMatcher : this.getAutoAnimatePairs;\n\n\t\tlet pairs = matcher.call( this, fromSlide, toSlide );\n\n\t\tlet reserved = [];\n\n\t\t// Remove duplicate pairs\n\t\treturn pairs.filter( ( pair, index ) => {\n\t\t\tif( reserved.indexOf( pair.to ) === -1 ) {\n\t\t\t\treserved.push( pair.to );\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} );\n\n\t}\n\n\t/**\n\t * Identifies matching elements between slides.\n\t *\n\t * You can specify a custom matcher function by using\n\t * the `autoAnimateMatcher` config option.\n\t */\n\tgetAutoAnimatePairs( fromSlide, toSlide ) {\n\n\t\tlet pairs = [];\n\n\t\tconst codeNodes = 'pre';\n\t\tconst textNodes = 'h1, h2, h3, h4, h5, h6, p, li';\n\t\tconst mediaNodes = 'img, video, iframe';\n\n\t\t// Eplicit matches via data-id\n\t\tthis.findAutoAnimateMatches( pairs, fromSlide, toSlide, '[data-id]', node => {\n\t\t\treturn node.nodeName + ':::' + node.getAttribute( 'data-id' );\n\t\t} );\n\n\t\t// Text\n\t\tthis.findAutoAnimateMatches( pairs, fromSlide, toSlide, textNodes, node => {\n\t\t\treturn node.nodeName + ':::' + node.innerText;\n\t\t} );\n\n\t\t// Media\n\t\tthis.findAutoAnimateMatches( pairs, fromSlide, toSlide, mediaNodes, node => {\n\t\t\treturn node.nodeName + ':::' + ( node.getAttribute( 'src' ) || node.getAttribute( 'data-src' ) );\n\t\t} );\n\n\t\t// Code\n\t\tthis.findAutoAnimateMatches( pairs, fromSlide, toSlide, codeNodes, node => {\n\t\t\treturn node.nodeName + ':::' + node.innerText;\n\t\t} );\n\n\t\tpairs.forEach( pair => {\n\n\t\t\t// Disable scale transformations on text nodes, we transition\n\t\t\t// each individual text property instead\n\t\t\tif( matches( pair.from, textNodes ) ) {\n\t\t\t\tpair.options = { scale: false };\n\t\t\t}\n\t\t\t// Animate individual lines of code\n\t\t\telse if( matches( pair.from, codeNodes ) ) {\n\n\t\t\t\t// Transition the code block's width and height instead of scaling\n\t\t\t\t// to prevent its content from being squished\n\t\t\t\tpair.options = { scale: false, styles: [ 'width', 'height' ] };\n\n\t\t\t\t// Lines of code\n\t\t\t\tthis.findAutoAnimateMatches( pairs, pair.from, pair.to, '.hljs .hljs-ln-code', node => {\n\t\t\t\t\treturn node.textContent;\n\t\t\t\t}, {\n\t\t\t\t\tscale: false,\n\t\t\t\t\tstyles: [],\n\t\t\t\t\tmeasure: this.getLocalBoundingBox.bind( this )\n\t\t\t\t} );\n\n\t\t\t\t// Line numbers\n\t\t\t\tthis.findAutoAnimateMatches( pairs, pair.from, pair.to, '.hljs .hljs-ln-line[data-line-number]', node => {\n\t\t\t\t\treturn node.getAttribute( 'data-line-number' );\n\t\t\t\t}, {\n\t\t\t\t\tscale: false,\n\t\t\t\t\tstyles: [ 'width' ],\n\t\t\t\t\tmeasure: this.getLocalBoundingBox.bind( this )\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t}, this );\n\n\t\treturn pairs;\n\n\t}\n\n\t/**\n\t * Helper method which returns a bounding box based on\n\t * the given elements offset coordinates.\n\t *\n\t * @param {HTMLElement} element\n\t * @return {Object} x, y, width, height\n\t */\n\tgetLocalBoundingBox( element ) {\n\n\t\tconst presentationScale = this.Reveal.getScale();\n\n\t\treturn {\n\t\t\tx: Math.round( ( element.offsetLeft * presentationScale ) * 100 ) / 100,\n\t\t\ty: Math.round( ( element.offsetTop * presentationScale ) * 100 ) / 100,\n\t\t\twidth: Math.round( ( element.offsetWidth * presentationScale ) * 100 ) / 100,\n\t\t\theight: Math.round( ( element.offsetHeight * presentationScale ) * 100 ) / 100\n\t\t};\n\n\t}\n\n\t/**\n\t * Finds matching elements between two slides.\n\t *\n\t * @param {Array} pairs \tList of pairs to push matches to\n\t * @param {HTMLElement} fromScope Scope within the from element exists\n\t * @param {HTMLElement} toScope Scope within the to element exists\n\t * @param {String} selector CSS selector of the element to match\n\t * @param {Function} serializer A function that accepts an element and returns\n\t * a stringified ID based on its contents\n\t * @param {Object} animationOptions Optional config options for this pair\n\t */\n\tfindAutoAnimateMatches( pairs, fromScope, toScope, selector, serializer, animationOptions ) {\n\n\t\tlet fromMatches = {};\n\t\tlet toMatches = {};\n\n\t\t[].slice.call( fromScope.querySelectorAll( selector ) ).forEach( ( element, i ) => {\n\t\t\tconst key = serializer( element );\n\t\t\tif( typeof key === 'string' && key.length ) {\n\t\t\t\tfromMatches[key] = fromMatches[key] || [];\n\t\t\t\tfromMatches[key].push( element );\n\t\t\t}\n\t\t} );\n\n\t\t[].slice.call( toScope.querySelectorAll( selector ) ).forEach( ( element, i ) => {\n\t\t\tconst key = serializer( element );\n\t\t\ttoMatches[key] = toMatches[key] || [];\n\t\t\ttoMatches[key].push( element );\n\n\t\t\tlet fromElement;\n\n\t\t\t// Retrieve the 'from' element\n\t\t\tif( fromMatches[key] ) {\n\t\t\t\tconst pimaryIndex = toMatches[key].length - 1;\n\t\t\t\tconst secondaryIndex = fromMatches[key].length - 1;\n\n\t\t\t\t// If there are multiple identical from elements, retrieve\n\t\t\t\t// the one at the same index as our to-element.\n\t\t\t\tif( fromMatches[key][ pimaryIndex ] ) {\n\t\t\t\t\tfromElement = fromMatches[key][ pimaryIndex ];\n\t\t\t\t\tfromMatches[key][ pimaryIndex ] = null;\n\t\t\t\t}\n\t\t\t\t// If there are no matching from-elements at the same index,\n\t\t\t\t// use the last one.\n\t\t\t\telse if( fromMatches[key][ secondaryIndex ] ) {\n\t\t\t\t\tfromElement = fromMatches[key][ secondaryIndex ];\n\t\t\t\t\tfromMatches[key][ secondaryIndex ] = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we've got a matching pair, push it to the list of pairs\n\t\t\tif( fromElement ) {\n\t\t\t\tpairs.push({\n\t\t\t\t\tfrom: fromElement,\n\t\t\t\t\tto: element,\n\t\t\t\t\toptions: animationOptions\n\t\t\t\t});\n\t\t\t}\n\t\t} );\n\n\t}\n\n\t/**\n\t * Returns a all elements within the given scope that should\n\t * be considered unmatched in an auto-animate transition. If\n\t * fading of unmatched elements is turned on, these elements\n\t * will fade when going between auto-animate slides.\n\t *\n\t * Note that parents of auto-animate targets are NOT considerd\n\t * unmatched since fading them would break the auto-animation.\n\t *\n\t * @param {HTMLElement} rootElement\n\t * @return {Array}\n\t */\n\tgetUnmatchedAutoAnimateElements( rootElement ) {\n\n\t\treturn [].slice.call( rootElement.children ).reduce( ( result, element ) => {\n\n\t\t\tconst containsAnimatedElements = element.querySelector( '[data-auto-animate-target]' );\n\n\t\t\t// The element is unmatched if\n\t\t\t// - It is not an auto-animate target\n\t\t\t// - It does not contain any auto-animate targets\n\t\t\tif( !element.hasAttribute( 'data-auto-animate-target' ) && !containsAnimatedElements ) {\n\t\t\t\tresult.push( element );\n\t\t\t}\n\n\t\t\tif( element.querySelector( '[data-auto-animate-target]' ) ) {\n\t\t\t\tresult = result.concat( this.getUnmatchedAutoAnimateElements( element ) );\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}, [] );\n\n\t}\n\n}\n","import { extend, queryAll } from '../utils/util.js'\n\n/**\n * Handles sorting and navigation of slide fragments.\n * Fragments are elements within a slide that are\n * revealed/animated incrementally.\n */\nexport default class Fragments {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tif( config.fragments === false ) {\n\t\t\tthis.disable();\n\t\t}\n\t\telse if( oldConfig.fragments === false ) {\n\t\t\tthis.enable();\n\t\t}\n\n\t}\n\n\t/**\n\t * If fragments are disabled in the deck, they should all be\n\t * visible rather than stepped through.\n\t */\n\tdisable() {\n\n\t\tqueryAll( this.Reveal.getSlidesElement(), '.fragment' ).forEach( element => {\n\t\t\telement.classList.add( 'visible' );\n\t\t\telement.classList.remove( 'current-fragment' );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Reverse of #disable(). Only called if fragments have\n\t * previously been disabled.\n\t */\n\tenable() {\n\n\t\tqueryAll( this.Reveal.getSlidesElement(), '.fragment' ).forEach( element => {\n\t\t\telement.classList.remove( 'visible' );\n\t\t\telement.classList.remove( 'current-fragment' );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Returns an object describing the available fragment\n\t * directions.\n\t *\n\t * @return {{prev: boolean, next: boolean}}\n\t */\n\tavailableRoutes() {\n\n\t\tlet currentSlide = this.Reveal.getCurrentSlide();\n\t\tif( currentSlide && this.Reveal.getConfig().fragments ) {\n\t\t\tlet fragments = currentSlide.querySelectorAll( '.fragment:not(.disabled)' );\n\t\t\tlet hiddenFragments = currentSlide.querySelectorAll( '.fragment:not(.disabled):not(.visible)' );\n\n\t\t\treturn {\n\t\t\t\tprev: fragments.length - hiddenFragments.length > 0,\n\t\t\t\tnext: !!hiddenFragments.length\n\t\t\t};\n\t\t}\n\t\telse {\n\t\t\treturn { prev: false, next: false };\n\t\t}\n\n\t}\n\n\t/**\n\t * Return a sorted fragments list, ordered by an increasing\n\t * \"data-fragment-index\" attribute.\n\t *\n\t * Fragments will be revealed in the order that they are returned by\n\t * this function, so you can use the index attributes to control the\n\t * order of fragment appearance.\n\t *\n\t * To maintain a sensible default fragment order, fragments are presumed\n\t * to be passed in document order. This function adds a \"fragment-index\"\n\t * attribute to each node if such an attribute is not already present,\n\t * and sets that attribute to an integer value which is the position of\n\t * the fragment within the fragments list.\n\t *\n\t * @param {object[]|*} fragments\n\t * @param {boolean} grouped If true the returned array will contain\n\t * nested arrays for all fragments with the same index\n\t * @return {object[]} sorted Sorted array of fragments\n\t */\n\tsort( fragments, grouped = false ) {\n\n\t\tfragments = Array.from( fragments );\n\n\t\tlet ordered = [],\n\t\t\tunordered = [],\n\t\t\tsorted = [];\n\n\t\t// Group ordered and unordered elements\n\t\tfragments.forEach( fragment => {\n\t\t\tif( fragment.hasAttribute( 'data-fragment-index' ) ) {\n\t\t\t\tlet index = parseInt( fragment.getAttribute( 'data-fragment-index' ), 10 );\n\n\t\t\t\tif( !ordered[index] ) {\n\t\t\t\t\tordered[index] = [];\n\t\t\t\t}\n\n\t\t\t\tordered[index].push( fragment );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tunordered.push( [ fragment ] );\n\t\t\t}\n\t\t} );\n\n\t\t// Append fragments without explicit indices in their\n\t\t// DOM order\n\t\tordered = ordered.concat( unordered );\n\n\t\t// Manually count the index up per group to ensure there\n\t\t// are no gaps\n\t\tlet index = 0;\n\n\t\t// Push all fragments in their sorted order to an array,\n\t\t// this flattens the groups\n\t\tordered.forEach( group => {\n\t\t\tgroup.forEach( fragment => {\n\t\t\t\tsorted.push( fragment );\n\t\t\t\tfragment.setAttribute( 'data-fragment-index', index );\n\t\t\t} );\n\n\t\t\tindex ++;\n\t\t} );\n\n\t\treturn grouped === true ? ordered : sorted;\n\n\t}\n\n\t/**\n\t * Sorts and formats all of fragments in the\n\t * presentation.\n\t */\n\tsortAll() {\n\n\t\tthis.Reveal.getHorizontalSlides().forEach( horizontalSlide => {\n\n\t\t\tlet verticalSlides = queryAll( horizontalSlide, 'section' );\n\t\t\tverticalSlides.forEach( ( verticalSlide, y ) => {\n\n\t\t\t\tthis.sort( verticalSlide.querySelectorAll( '.fragment' ) );\n\n\t\t\t}, this );\n\n\t\t\tif( verticalSlides.length === 0 ) this.sort( horizontalSlide.querySelectorAll( '.fragment' ) );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Refreshes the fragments on the current slide so that they\n\t * have the appropriate classes (.visible + .current-fragment).\n\t *\n\t * @param {number} [index] The index of the current fragment\n\t * @param {array} [fragments] Array containing all fragments\n\t * in the current slide\n\t *\n\t * @return {{shown: array, hidden: array}}\n\t */\n\tupdate( index, fragments ) {\n\n\t\tlet changedFragments = {\n\t\t\tshown: [],\n\t\t\thidden: []\n\t\t};\n\n\t\tlet currentSlide = this.Reveal.getCurrentSlide();\n\t\tif( currentSlide && this.Reveal.getConfig().fragments ) {\n\n\t\t\tfragments = fragments || this.sort( currentSlide.querySelectorAll( '.fragment' ) );\n\n\t\t\tif( fragments.length ) {\n\n\t\t\t\tlet maxIndex = 0;\n\n\t\t\t\tif( typeof index !== 'number' ) {\n\t\t\t\t\tlet currentFragment = this.sort( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop();\n\t\t\t\t\tif( currentFragment ) {\n\t\t\t\t\t\tindex = parseInt( currentFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tArray.from( fragments ).forEach( ( el, i ) => {\n\n\t\t\t\t\tif( el.hasAttribute( 'data-fragment-index' ) ) {\n\t\t\t\t\t\ti = parseInt( el.getAttribute( 'data-fragment-index' ), 10 );\n\t\t\t\t\t}\n\n\t\t\t\t\tmaxIndex = Math.max( maxIndex, i );\n\n\t\t\t\t\t// Visible fragments\n\t\t\t\t\tif( i <= index ) {\n\t\t\t\t\t\tlet wasVisible = el.classList.contains( 'visible' )\n\t\t\t\t\t\tel.classList.add( 'visible' );\n\t\t\t\t\t\tel.classList.remove( 'current-fragment' );\n\n\t\t\t\t\t\tif( i === index ) {\n\t\t\t\t\t\t\t// Announce the fragments one by one to the Screen Reader\n\t\t\t\t\t\t\tthis.Reveal.announceStatus( this.Reveal.getStatusText( el ) );\n\n\t\t\t\t\t\t\tel.classList.add( 'current-fragment' );\n\t\t\t\t\t\t\tthis.Reveal.slideContent.startEmbeddedContent( el );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif( !wasVisible ) {\n\t\t\t\t\t\t\tchangedFragments.shown.push( el )\n\t\t\t\t\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\t\t\t\t\ttarget: el,\n\t\t\t\t\t\t\t\ttype: 'visible',\n\t\t\t\t\t\t\t\tbubbles: false\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// Hidden fragments\n\t\t\t\t\telse {\n\t\t\t\t\t\tlet wasVisible = el.classList.contains( 'visible' )\n\t\t\t\t\t\tel.classList.remove( 'visible' );\n\t\t\t\t\t\tel.classList.remove( 'current-fragment' );\n\n\t\t\t\t\t\tif( wasVisible ) {\n\t\t\t\t\t\t\tthis.Reveal.slideContent.stopEmbeddedContent( el );\n\t\t\t\t\t\t\tchangedFragments.hidden.push( el );\n\t\t\t\t\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\t\t\t\t\ttarget: el,\n\t\t\t\t\t\t\t\ttype: 'hidden',\n\t\t\t\t\t\t\t\tbubbles: false\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\t// Write the current fragment index to the slide .\n\t\t\t\t// This can be used by end users to apply styles based on\n\t\t\t\t// the current fragment index.\n\t\t\t\tindex = typeof index === 'number' ? index : -1;\n\t\t\t\tindex = Math.max( Math.min( index, maxIndex ), -1 );\n\t\t\t\tcurrentSlide.setAttribute( 'data-fragment', index );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn changedFragments;\n\n\t}\n\n\t/**\n\t * Formats the fragments on the given slide so that they have\n\t * valid indices. Call this if fragments are changed in the DOM\n\t * after reveal.js has already initialized.\n\t *\n\t * @param {HTMLElement} slide\n\t * @return {Array} a list of the HTML fragments that were synced\n\t */\n\tsync( slide = this.Reveal.getCurrentSlide() ) {\n\n\t\treturn this.sort( slide.querySelectorAll( '.fragment' ) );\n\n\t}\n\n\t/**\n\t * Navigate to the specified slide fragment.\n\t *\n\t * @param {?number} index The index of the fragment that\n\t * should be shown, -1 means all are invisible\n\t * @param {number} offset Integer offset to apply to the\n\t * fragment index\n\t *\n\t * @return {boolean} true if a change was made in any\n\t * fragments visibility as part of this call\n\t */\n\tgoto( index, offset = 0 ) {\n\n\t\tlet currentSlide = this.Reveal.getCurrentSlide();\n\t\tif( currentSlide && this.Reveal.getConfig().fragments ) {\n\n\t\t\tlet fragments = this.sort( currentSlide.querySelectorAll( '.fragment:not(.disabled)' ) );\n\t\t\tif( fragments.length ) {\n\n\t\t\t\t// If no index is specified, find the current\n\t\t\t\tif( typeof index !== 'number' ) {\n\t\t\t\t\tlet lastVisibleFragment = this.sort( currentSlide.querySelectorAll( '.fragment:not(.disabled).visible' ) ).pop();\n\n\t\t\t\t\tif( lastVisibleFragment ) {\n\t\t\t\t\t\tindex = parseInt( lastVisibleFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tindex = -1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply the offset if there is one\n\t\t\t\tindex += offset;\n\n\t\t\t\tlet changedFragments = this.update( index, fragments );\n\n\t\t\t\tif( changedFragments.hidden.length ) {\n\t\t\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\t\t\ttype: 'fragmenthidden',\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tfragment: changedFragments.hidden[0],\n\t\t\t\t\t\t\tfragments: changedFragments.hidden\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif( changedFragments.shown.length ) {\n\t\t\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\t\t\ttype: 'fragmentshown',\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tfragment: changedFragments.shown[0],\n\t\t\t\t\t\t\tfragments: changedFragments.shown\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tthis.Reveal.controls.update();\n\t\t\t\tthis.Reveal.progress.update();\n\n\t\t\t\tif( this.Reveal.getConfig().fragmentInURL ) {\n\t\t\t\t\tthis.Reveal.location.writeURL();\n\t\t\t\t}\n\n\t\t\t\treturn !!( changedFragments.shown.length || changedFragments.hidden.length );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\t/**\n\t * Navigate to the next slide fragment.\n\t *\n\t * @return {boolean} true if there was a next fragment,\n\t * false otherwise\n\t */\n\tnext() {\n\n\t\treturn this.goto( null, 1 );\n\n\t}\n\n\t/**\n\t * Navigate to the previous slide fragment.\n\t *\n\t * @return {boolean} true if there was a previous fragment,\n\t * false otherwise\n\t */\n\tprev() {\n\n\t\treturn this.goto( null, -1 );\n\n\t}\n\n}","import { SLIDES_SELECTOR } from '../utils/constants.js'\nimport { extend, queryAll, transformElement } from '../utils/util.js'\n\n/**\n * Handles all logic related to the overview mode\n * (birds-eye view of all slides).\n */\nexport default class Overview {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.active = false;\n\n\t\tthis.onSlideClicked = this.onSlideClicked.bind( this );\n\n\t}\n\n\t/**\n\t * Displays the overview of slides (quick nav) by scaling\n\t * down and arranging all slide elements.\n\t */\n\tactivate() {\n\n\t\t// Only proceed if enabled in config\n\t\tif( this.Reveal.getConfig().overview && !this.isActive() ) {\n\n\t\t\tthis.active = true;\n\n\t\t\tthis.Reveal.getRevealElement().classList.add( 'overview' );\n\n\t\t\t// Don't auto-slide while in overview mode\n\t\t\tthis.Reveal.cancelAutoSlide();\n\n\t\t\t// Move the backgrounds element into the slide container to\n\t\t\t// that the same scaling is applied\n\t\t\tthis.Reveal.getSlidesElement().appendChild( this.Reveal.getBackgroundsElement() );\n\n\t\t\t// Clicking on an overview slide navigates to it\n\t\t\tqueryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR ).forEach( slide => {\n\t\t\t\tif( !slide.classList.contains( 'stack' ) ) {\n\t\t\t\t\tslide.addEventListener( 'click', this.onSlideClicked, true );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t// Calculate slide sizes\n\t\t\tconst margin = 70;\n\t\t\tconst slideSize = this.Reveal.getComputedSlideSize();\n\t\t\tthis.overviewSlideWidth = slideSize.width + margin;\n\t\t\tthis.overviewSlideHeight = slideSize.height + margin;\n\n\t\t\t// Reverse in RTL mode\n\t\t\tif( this.Reveal.getConfig().rtl ) {\n\t\t\t\tthis.overviewSlideWidth = -this.overviewSlideWidth;\n\t\t\t}\n\n\t\t\tthis.Reveal.updateSlidesVisibility();\n\n\t\t\tthis.layout();\n\t\t\tthis.update();\n\n\t\t\tthis.Reveal.layout();\n\n\t\t\tconst indices = this.Reveal.getIndices();\n\n\t\t\t// Notify observers of the overview showing\n\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\ttype: 'overviewshown',\n\t\t\t\tdata: {\n\t\t\t\t\t'indexh': indices.h,\n\t\t\t\t\t'indexv': indices.v,\n\t\t\t\t\t'currentSlide': this.Reveal.getCurrentSlide()\n\t\t\t\t}\n\t\t\t});\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Uses CSS transforms to position all slides in a grid for\n\t * display inside of the overview mode.\n\t */\n\tlayout() {\n\n\t\t// Layout slides\n\t\tthis.Reveal.getHorizontalSlides().forEach( ( hslide, h ) => {\n\t\t\thslide.setAttribute( 'data-index-h', h );\n\t\t\ttransformElement( hslide, 'translate3d(' + ( h * this.overviewSlideWidth ) + 'px, 0, 0)' );\n\n\t\t\tif( hslide.classList.contains( 'stack' ) ) {\n\n\t\t\t\tqueryAll( hslide, 'section' ).forEach( ( vslide, v ) => {\n\t\t\t\t\tvslide.setAttribute( 'data-index-h', h );\n\t\t\t\t\tvslide.setAttribute( 'data-index-v', v );\n\n\t\t\t\t\ttransformElement( vslide, 'translate3d(0, ' + ( v * this.overviewSlideHeight ) + 'px, 0)' );\n\t\t\t\t} );\n\n\t\t\t}\n\t\t} );\n\n\t\t// Layout slide backgrounds\n\t\tArray.from( this.Reveal.getBackgroundsElement().childNodes ).forEach( ( hbackground, h ) => {\n\t\t\ttransformElement( hbackground, 'translate3d(' + ( h * this.overviewSlideWidth ) + 'px, 0, 0)' );\n\n\t\t\tqueryAll( hbackground, '.slide-background' ).forEach( ( vbackground, v ) => {\n\t\t\t\ttransformElement( vbackground, 'translate3d(0, ' + ( v * this.overviewSlideHeight ) + 'px, 0)' );\n\t\t\t} );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Moves the overview viewport to the current slides.\n\t * Called each time the current slide changes.\n\t */\n\tupdate() {\n\n\t\tconst vmin = Math.min( window.innerWidth, window.innerHeight );\n\t\tconst scale = Math.max( vmin / 5, 150 ) / vmin;\n\t\tconst indices = this.Reveal.getIndices();\n\n\t\tthis.Reveal.transformSlides( {\n\t\t\toverview: [\n\t\t\t\t'scale('+ scale +')',\n\t\t\t\t'translateX('+ ( -indices.h * this.overviewSlideWidth ) +'px)',\n\t\t\t\t'translateY('+ ( -indices.v * this.overviewSlideHeight ) +'px)'\n\t\t\t].join( ' ' )\n\t\t} );\n\n\t}\n\n\t/**\n\t * Exits the slide overview and enters the currently\n\t * active slide.\n\t */\n\tdeactivate() {\n\n\t\t// Only proceed if enabled in config\n\t\tif( this.Reveal.getConfig().overview ) {\n\n\t\t\tthis.active = false;\n\n\t\t\tthis.Reveal.getRevealElement().classList.remove( 'overview' );\n\n\t\t\t// Temporarily add a class so that transitions can do different things\n\t\t\t// depending on whether they are exiting/entering overview, or just\n\t\t\t// moving from slide to slide\n\t\t\tthis.Reveal.getRevealElement().classList.add( 'overview-deactivating' );\n\n\t\t\tsetTimeout( () => {\n\t\t\t\tthis.Reveal.getRevealElement().classList.remove( 'overview-deactivating' );\n\t\t\t}, 1 );\n\n\t\t\t// Move the background element back out\n\t\t\tthis.Reveal.getRevealElement().appendChild( this.Reveal.getBackgroundsElement() );\n\n\t\t\t// Clean up changes made to slides\n\t\t\tqueryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR ).forEach( slide => {\n\t\t\t\ttransformElement( slide, '' );\n\n\t\t\t\tslide.removeEventListener( 'click', this.onSlideClicked, true );\n\t\t\t} );\n\n\t\t\t// Clean up changes made to backgrounds\n\t\t\tqueryAll( this.Reveal.getBackgroundsElement(), '.slide-background' ).forEach( background => {\n\t\t\t\ttransformElement( background, '' );\n\t\t\t} );\n\n\t\t\tthis.Reveal.transformSlides( { overview: '' } );\n\n\t\t\tconst indices = this.Reveal.getIndices();\n\n\t\t\tthis.Reveal.slide( indices.h, indices.v );\n\t\t\tthis.Reveal.layout();\n\t\t\tthis.Reveal.cueAutoSlide();\n\n\t\t\t// Notify observers of the overview hiding\n\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\ttype: 'overviewhidden',\n\t\t\t\tdata: {\n\t\t\t\t\t'indexh': indices.h,\n\t\t\t\t\t'indexv': indices.v,\n\t\t\t\t\t'currentSlide': this.Reveal.getCurrentSlide()\n\t\t\t\t}\n\t\t\t});\n\n\t\t}\n\t}\n\n\t/**\n\t * Toggles the slide overview mode on and off.\n\t *\n\t * @param {Boolean} [override] Flag which overrides the\n\t * toggle logic and forcibly sets the desired state. True means\n\t * overview is open, false means it's closed.\n\t */\n\ttoggle( override ) {\n\n\t\tif( typeof override === 'boolean' ) {\n\t\t\toverride ? this.activate() : this.deactivate();\n\t\t}\n\t\telse {\n\t\t\tthis.isActive() ? this.deactivate() : this.activate();\n\t\t}\n\n\t}\n\n\t/**\n\t * Checks if the overview is currently active.\n\t *\n\t * @return {Boolean} true if the overview is active,\n\t * false otherwise\n\t */\n\tisActive() {\n\n\t\treturn this.active;\n\n\t}\n\n\t/**\n\t * Invoked when a slide is and we're in the overview.\n\t *\n\t * @param {object} event\n\t */\n\tonSlideClicked( event ) {\n\n\t\tif( this.isActive() ) {\n\t\t\tevent.preventDefault();\n\n\t\t\tlet element = event.target;\n\n\t\t\twhile( element && !element.nodeName.match( /section/gi ) ) {\n\t\t\t\telement = element.parentNode;\n\t\t\t}\n\n\t\t\tif( element && !element.classList.contains( 'disabled' ) ) {\n\n\t\t\t\tthis.deactivate();\n\n\t\t\t\tif( element.nodeName.match( /section/gi ) ) {\n\t\t\t\t\tlet h = parseInt( element.getAttribute( 'data-index-h' ), 10 ),\n\t\t\t\t\t\tv = parseInt( element.getAttribute( 'data-index-v' ), 10 );\n\n\t\t\t\t\tthis.Reveal.slide( h, v );\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\n\t}\n\n}","import { enterFullscreen } from '../utils/util.js'\n\n/**\n * Handles all reveal.js keyboard interactions.\n */\nexport default class Keyboard {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\t// A key:value map of keyboard keys and descriptions of\n\t\t// the actions they trigger\n\t\tthis.shortcuts = {};\n\n\t\t// Holds custom key code mappings\n\t\tthis.bindings = {};\n\n\t\tthis.onDocumentKeyDown = this.onDocumentKeyDown.bind( this );\n\t\tthis.onDocumentKeyPress = this.onDocumentKeyPress.bind( this );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tif( config.navigationMode === 'linear' ) {\n\t\t\tthis.shortcuts['→ , ↓ , SPACE , N , L , J'] = 'Next slide';\n\t\t\tthis.shortcuts['← , ↑ , P , H , K'] = 'Previous slide';\n\t\t}\n\t\telse {\n\t\t\tthis.shortcuts['N , SPACE'] = 'Next slide';\n\t\t\tthis.shortcuts['P , Shift SPACE'] = 'Previous slide';\n\t\t\tthis.shortcuts['← , H'] = 'Navigate left';\n\t\t\tthis.shortcuts['→ , L'] = 'Navigate right';\n\t\t\tthis.shortcuts['↑ , K'] = 'Navigate up';\n\t\t\tthis.shortcuts['↓ , J'] = 'Navigate down';\n\t\t}\n\n\t\tthis.shortcuts['Alt + ←/↑/→/↓'] = 'Navigate without fragments';\n\t\tthis.shortcuts['Shift + ←/↑/→/↓'] = 'Jump to first/last slide';\n\t\tthis.shortcuts['B , .'] = 'Pause';\n\t\tthis.shortcuts['F'] = 'Fullscreen';\n\t\tthis.shortcuts['ESC, O'] = 'Slide overview';\n\n\t}\n\n\t/**\n\t * Starts listening for keyboard events.\n\t */\n\tbind() {\n\n\t\tdocument.addEventListener( 'keydown', this.onDocumentKeyDown, false );\n\t\tdocument.addEventListener( 'keypress', this.onDocumentKeyPress, false );\n\n\t}\n\n\t/**\n\t * Stops listening for keyboard events.\n\t */\n\tunbind() {\n\n\t\tdocument.removeEventListener( 'keydown', this.onDocumentKeyDown, false );\n\t\tdocument.removeEventListener( 'keypress', this.onDocumentKeyPress, false );\n\n\t}\n\n\t/**\n\t * Add a custom key binding with optional description to\n\t * be added to the help screen.\n\t */\n\taddKeyBinding( binding, callback ) {\n\n\t\tif( typeof binding === 'object' && binding.keyCode ) {\n\t\t\tthis.bindings[binding.keyCode] = {\n\t\t\t\tcallback: callback,\n\t\t\t\tkey: binding.key,\n\t\t\t\tdescription: binding.description\n\t\t\t};\n\t\t}\n\t\telse {\n\t\t\tthis.bindings[binding] = {\n\t\t\t\tcallback: callback,\n\t\t\t\tkey: null,\n\t\t\t\tdescription: null\n\t\t\t};\n\t\t}\n\n\t}\n\n\t/**\n\t * Removes the specified custom key binding.\n\t */\n\tremoveKeyBinding( keyCode ) {\n\n\t\tdelete this.bindings[keyCode];\n\n\t}\n\n\t/**\n\t * Programmatically triggers a keyboard event\n\t *\n\t * @param {int} keyCode\n\t */\n\ttriggerKey( keyCode ) {\n\n\t\tthis.onDocumentKeyDown( { keyCode } );\n\n\t}\n\n\t/**\n\t * Registers a new shortcut to include in the help overlay\n\t *\n\t * @param {String} key\n\t * @param {String} value\n\t */\n\tregisterKeyboardShortcut( key, value ) {\n\n\t\tthis.shortcuts[key] = value;\n\n\t}\n\n\tgetShortcuts() {\n\n\t\treturn this.shortcuts;\n\n\t}\n\n\tgetBindings() {\n\n\t\treturn this.bindings;\n\n\t}\n\n\t/**\n\t * Handler for the document level 'keypress' event.\n\t *\n\t * @param {object} event\n\t */\n\tonDocumentKeyPress( event ) {\n\n\t\t// Check if the pressed key is question mark\n\t\tif( event.shiftKey && event.charCode === 63 ) {\n\t\t\tthis.Reveal.toggleHelp();\n\t\t}\n\n\t}\n\n\t/**\n\t * Handler for the document level 'keydown' event.\n\t *\n\t * @param {object} event\n\t */\n\tonDocumentKeyDown( event ) {\n\n\t\tlet config = this.Reveal.getConfig();\n\n\t\t// If there's a condition specified and it returns false,\n\t\t// ignore this event\n\t\tif( typeof config.keyboardCondition === 'function' && config.keyboardCondition(event) === false ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// If keyboardCondition is set, only capture keyboard events\n\t\t// for embedded decks when they are focused\n\t\tif( config.keyboardCondition === 'focused' && !this.Reveal.isFocused() ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Shorthand\n\t\tlet keyCode = event.keyCode;\n\n\t\t// Remember if auto-sliding was paused so we can toggle it\n\t\tlet autoSlideWasPaused = !this.Reveal.isAutoSliding();\n\n\t\tthis.Reveal.onUserInput( event );\n\n\t\t// Is there a focused element that could be using the keyboard?\n\t\tlet activeElementIsCE = document.activeElement && document.activeElement.isContentEditable === true;\n\t\tlet activeElementIsInput = document.activeElement && document.activeElement.tagName && /input|textarea/i.test( document.activeElement.tagName );\n\t\tlet activeElementIsNotes = document.activeElement && document.activeElement.className && /speaker-notes/i.test( document.activeElement.className);\n\n\t\t// Whitelist certain modifiers for slide navigation shortcuts\n\t\tlet isNavigationKey = [32, 37, 38, 39, 40, 78, 80].indexOf( event.keyCode ) !== -1;\n\n\t\t// Prevent all other events when a modifier is pressed\n\t\tlet unusedModifier = \t!( isNavigationKey && event.shiftKey || event.altKey ) &&\n\t\t\t\t\t\t\t\t( event.shiftKey || event.altKey || event.ctrlKey || event.metaKey );\n\n\t\t// Disregard the event if there's a focused element or a\n\t\t// keyboard modifier key is present\n\t\tif( activeElementIsCE || activeElementIsInput || activeElementIsNotes || unusedModifier ) return;\n\n\t\t// While paused only allow resume keyboard events; 'b', 'v', '.'\n\t\tlet resumeKeyCodes = [66,86,190,191];\n\t\tlet key;\n\n\t\t// Custom key bindings for togglePause should be able to resume\n\t\tif( typeof config.keyboard === 'object' ) {\n\t\t\tfor( key in config.keyboard ) {\n\t\t\t\tif( config.keyboard[key] === 'togglePause' ) {\n\t\t\t\t\tresumeKeyCodes.push( parseInt( key, 10 ) );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif( this.Reveal.isPaused() && resumeKeyCodes.indexOf( keyCode ) === -1 ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Use linear navigation if we're configured to OR if\n\t\t// the presentation is one-dimensional\n\t\tlet useLinearMode = config.navigationMode === 'linear' || !this.Reveal.hasHorizontalSlides() || !this.Reveal.hasVerticalSlides();\n\n\t\tlet triggered = false;\n\n\t\t// 1. User defined key bindings\n\t\tif( typeof config.keyboard === 'object' ) {\n\n\t\t\tfor( key in config.keyboard ) {\n\n\t\t\t\t// Check if this binding matches the pressed key\n\t\t\t\tif( parseInt( key, 10 ) === keyCode ) {\n\n\t\t\t\t\tlet value = config.keyboard[ key ];\n\n\t\t\t\t\t// Callback function\n\t\t\t\t\tif( typeof value === 'function' ) {\n\t\t\t\t\t\tvalue.apply( null, [ event ] );\n\t\t\t\t\t}\n\t\t\t\t\t// String shortcuts to reveal.js API\n\t\t\t\t\telse if( typeof value === 'string' && typeof this.Reveal[ value ] === 'function' ) {\n\t\t\t\t\t\tthis.Reveal[ value ].call();\n\t\t\t\t\t}\n\n\t\t\t\t\ttriggered = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// 2. Registered custom key bindings\n\t\tif( triggered === false ) {\n\n\t\t\tfor( key in this.bindings ) {\n\n\t\t\t\t// Check if this binding matches the pressed key\n\t\t\t\tif( parseInt( key, 10 ) === keyCode ) {\n\n\t\t\t\t\tlet action = this.bindings[ key ].callback;\n\n\t\t\t\t\t// Callback function\n\t\t\t\t\tif( typeof action === 'function' ) {\n\t\t\t\t\t\taction.apply( null, [ event ] );\n\t\t\t\t\t}\n\t\t\t\t\t// String shortcuts to reveal.js API\n\t\t\t\t\telse if( typeof action === 'string' && typeof this.Reveal[ action ] === 'function' ) {\n\t\t\t\t\t\tthis.Reveal[ action ].call();\n\t\t\t\t\t}\n\n\t\t\t\t\ttriggered = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// 3. System defined key bindings\n\t\tif( triggered === false ) {\n\n\t\t\t// Assume true and try to prove false\n\t\t\ttriggered = true;\n\n\t\t\t// P, PAGE UP\n\t\t\tif( keyCode === 80 || keyCode === 33 ) {\n\t\t\t\tthis.Reveal.prev({skipFragments: event.altKey});\n\t\t\t}\n\t\t\t// N, PAGE DOWN\n\t\t\telse if( keyCode === 78 || keyCode === 34 ) {\n\t\t\t\tthis.Reveal.next({skipFragments: event.altKey});\n\t\t\t}\n\t\t\t// H, LEFT\n\t\t\telse if( keyCode === 72 || keyCode === 37 ) {\n\t\t\t\tif( event.shiftKey ) {\n\t\t\t\t\tthis.Reveal.slide( 0 );\n\t\t\t\t}\n\t\t\t\telse if( !this.Reveal.overview.isActive() && useLinearMode ) {\n\t\t\t\t\tthis.Reveal.prev({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.left({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t}\n\t\t\t// L, RIGHT\n\t\t\telse if( keyCode === 76 || keyCode === 39 ) {\n\t\t\t\tif( event.shiftKey ) {\n\t\t\t\t\tthis.Reveal.slide( this.Reveal.getHorizontalSlides().length - 1 );\n\t\t\t\t}\n\t\t\t\telse if( !this.Reveal.overview.isActive() && useLinearMode ) {\n\t\t\t\t\tthis.Reveal.next({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.right({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t}\n\t\t\t// K, UP\n\t\t\telse if( keyCode === 75 || keyCode === 38 ) {\n\t\t\t\tif( event.shiftKey ) {\n\t\t\t\t\tthis.Reveal.slide( undefined, 0 );\n\t\t\t\t}\n\t\t\t\telse if( !this.Reveal.overview.isActive() && useLinearMode ) {\n\t\t\t\t\tthis.Reveal.prev({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.up({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t}\n\t\t\t// J, DOWN\n\t\t\telse if( keyCode === 74 || keyCode === 40 ) {\n\t\t\t\tif( event.shiftKey ) {\n\t\t\t\t\tthis.Reveal.slide( undefined, Number.MAX_VALUE );\n\t\t\t\t}\n\t\t\t\telse if( !this.Reveal.overview.isActive() && useLinearMode ) {\n\t\t\t\t\tthis.Reveal.next({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.down({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t}\n\t\t\t// HOME\n\t\t\telse if( keyCode === 36 ) {\n\t\t\t\tthis.Reveal.slide( 0 );\n\t\t\t}\n\t\t\t// END\n\t\t\telse if( keyCode === 35 ) {\n\t\t\t\tthis.Reveal.slide( this.Reveal.getHorizontalSlides().length - 1 );\n\t\t\t}\n\t\t\t// SPACE\n\t\t\telse if( keyCode === 32 ) {\n\t\t\t\tif( this.Reveal.overview.isActive() ) {\n\t\t\t\t\tthis.Reveal.overview.deactivate();\n\t\t\t\t}\n\t\t\t\tif( event.shiftKey ) {\n\t\t\t\t\tthis.Reveal.prev({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.next({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t}\n\t\t\t// TWO-SPOT, SEMICOLON, B, V, PERIOD, LOGITECH PRESENTER TOOLS \"BLACK SCREEN\" BUTTON\n\t\t\telse if( keyCode === 58 || keyCode === 59 || keyCode === 66 || keyCode === 86 || keyCode === 190 || keyCode === 191 ) {\n\t\t\t\tthis.Reveal.togglePause();\n\t\t\t}\n\t\t\t// F\n\t\t\telse if( keyCode === 70 ) {\n\t\t\t\tenterFullscreen( config.embedded ? this.Reveal.getViewportElement() : document.documentElement );\n\t\t\t}\n\t\t\t// A\n\t\t\telse if( keyCode === 65 ) {\n\t\t\t\tif ( config.autoSlideStoppable ) {\n\t\t\t\t\tthis.Reveal.toggleAutoSlide( autoSlideWasPaused );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttriggered = false;\n\t\t\t}\n\n\t\t}\n\n\t\t// If the input resulted in a triggered action we should prevent\n\t\t// the browsers default behavior\n\t\tif( triggered ) {\n\t\t\tevent.preventDefault && event.preventDefault();\n\t\t}\n\t\t// ESC or O key\n\t\telse if( keyCode === 27 || keyCode === 79 ) {\n\t\t\tif( this.Reveal.closeOverlay() === false ) {\n\t\t\t\tthis.Reveal.overview.toggle();\n\t\t\t}\n\n\t\t\tevent.preventDefault && event.preventDefault();\n\t\t}\n\n\t\t// If auto-sliding is enabled we need to cue up\n\t\t// another timeout\n\t\tthis.Reveal.cueAutoSlide();\n\n\t}\n\n}","/**\n * Reads and writes the URL based on reveal.js' current state.\n */\nexport default class Location {\n\n\t// The minimum number of milliseconds that must pass between\n\t// calls to history.replaceState\n\tMAX_REPLACE_STATE_FREQUENCY = 1000\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\t// Delays updates to the URL due to a Chrome thumbnailer bug\n\t\tthis.writeURLTimeout = 0;\n\n\t\tthis.replaceStateTimestamp = 0;\n\n\t\tthis.onWindowHashChange = this.onWindowHashChange.bind( this );\n\n\t}\n\n\tbind() {\n\n\t\twindow.addEventListener( 'hashchange', this.onWindowHashChange, false );\n\n\t}\n\n\tunbind() {\n\n\t\twindow.removeEventListener( 'hashchange', this.onWindowHashChange, false );\n\n\t}\n\n\t/**\n\t * Returns the slide indices for the given hash link.\n\t *\n\t * @param {string} [hash] the hash string that we want to\n\t * find the indices for\n\t *\n\t * @returns slide indices or null\n\t */\n\tgetIndicesFromHash( hash=window.location.hash ) {\n\n\t\t// Attempt to parse the hash as either an index or name\n\t\tlet name = hash.replace( /^#\\/?/, '' );\n\t\tlet bits = name.split( '/' );\n\n\t\t// If the first bit is not fully numeric and there is a name we\n\t\t// can assume that this is a named link\n\t\tif( !/^[0-9]*$/.test( bits[0] ) && name.length ) {\n\t\t\tlet element;\n\n\t\t\tlet f;\n\n\t\t\t// Parse named links with fragments (#/named-link/2)\n\t\t\tif( /\\/[-\\d]+$/g.test( name ) ) {\n\t\t\t\tf = parseInt( name.split( '/' ).pop(), 10 );\n\t\t\t\tf = isNaN(f) ? undefined : f;\n\t\t\t\tname = name.split( '/' ).shift();\n\t\t\t}\n\n\t\t\t// Ensure the named link is a valid HTML ID attribute\n\t\t\ttry {\n\t\t\t\telement = document.getElementById( decodeURIComponent( name ) );\n\t\t\t}\n\t\t\tcatch ( error ) { }\n\n\t\t\tif( element ) {\n\t\t\t\treturn { ...this.Reveal.getIndices( element ), f };\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tconst config = this.Reveal.getConfig();\n\t\t\tlet hashIndexBase = config.hashOneBasedIndex ? 1 : 0;\n\n\t\t\t// Read the index components of the hash\n\t\t\tlet h = ( parseInt( bits[0], 10 ) - hashIndexBase ) || 0,\n\t\t\t\tv = ( parseInt( bits[1], 10 ) - hashIndexBase ) || 0,\n\t\t\t\tf;\n\n\t\t\tif( config.fragmentInURL ) {\n\t\t\t\tf = parseInt( bits[2], 10 );\n\t\t\t\tif( isNaN( f ) ) {\n\t\t\t\t\tf = undefined;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { h, v, f };\n\t\t}\n\n\t\t// The hash couldn't be parsed or no matching named link was found\n\t\treturn null\n\n\t}\n\n\t/**\n\t * Reads the current URL (hash) and navigates accordingly.\n\t */\n\treadURL() {\n\n\t\tconst currentIndices = this.Reveal.getIndices();\n\t\tconst newIndices = this.getIndicesFromHash();\n\n\t\tif( newIndices ) {\n\t\t\tif( ( newIndices.h !== currentIndices.h || newIndices.v !== currentIndices.v || newIndices.f !== undefined ) ) {\n\t\t\t\t\tthis.Reveal.slide( newIndices.h, newIndices.v, newIndices.f );\n\t\t\t}\n\t\t}\n\t\t// If no new indices are available, we're trying to navigate to\n\t\t// a slide hash that does not exist\n\t\telse {\n\t\t\tthis.Reveal.slide( currentIndices.h || 0, currentIndices.v || 0 );\n\t\t}\n\n\t}\n\n\t/**\n\t * Updates the page URL (hash) to reflect the current\n\t * state.\n\t *\n\t * @param {number} delay The time in ms to wait before\n\t * writing the hash\n\t */\n\twriteURL( delay ) {\n\n\t\tlet config = this.Reveal.getConfig();\n\t\tlet currentSlide = this.Reveal.getCurrentSlide();\n\n\t\t// Make sure there's never more than one timeout running\n\t\tclearTimeout( this.writeURLTimeout );\n\n\t\t// If a delay is specified, timeout this call\n\t\tif( typeof delay === 'number' ) {\n\t\t\tthis.writeURLTimeout = setTimeout( this.writeURL, delay );\n\t\t}\n\t\telse if( currentSlide ) {\n\n\t\t\tlet hash = this.getHash();\n\n\t\t\t// If we're configured to push to history OR the history\n\t\t\t// API is not avaialble.\n\t\t\tif( config.history ) {\n\t\t\t\twindow.location.hash = hash;\n\t\t\t}\n\t\t\t// If we're configured to reflect the current slide in the\n\t\t\t// URL without pushing to history.\n\t\t\telse if( config.hash ) {\n\t\t\t\t// If the hash is empty, don't add it to the URL\n\t\t\t\tif( hash === '/' ) {\n\t\t\t\t\tthis.debouncedReplaceState( window.location.pathname + window.location.search );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.debouncedReplaceState( '#' + hash );\n\t\t\t\t}\n\t\t\t}\n\t\t\t// UPDATE: The below nuking of all hash changes breaks\n\t\t\t// anchors on pages where reveal.js is running. Removed\n\t\t\t// in 4.0. Why was it here in the first place? ¯\\_(ツ)_/¯\n\t\t\t//\n\t\t\t// If history and hash are both disabled, a hash may still\n\t\t\t// be added to the URL by clicking on a href with a hash\n\t\t\t// target. Counter this by always removing the hash.\n\t\t\t// else {\n\t\t\t// \twindow.history.replaceState( null, null, window.location.pathname + window.location.search );\n\t\t\t// }\n\n\t\t}\n\n\t}\n\n\treplaceState( url ) {\n\n\t\twindow.history.replaceState( null, null, url );\n\t\tthis.replaceStateTimestamp = Date.now();\n\n\t}\n\n\tdebouncedReplaceState( url ) {\n\n\t\tclearTimeout( this.replaceStateTimeout );\n\n\t\tif( Date.now() - this.replaceStateTimestamp > this.MAX_REPLACE_STATE_FREQUENCY ) {\n\t\t\tthis.replaceState( url );\n\t\t}\n\t\telse {\n\t\t\tthis.replaceStateTimeout = setTimeout( () => this.replaceState( url ), this.MAX_REPLACE_STATE_FREQUENCY );\n\t\t}\n\n\t}\n\n\t/**\n\t * Return a hash URL that will resolve to the given slide location.\n\t *\n\t * @param {HTMLElement} [slide=currentSlide] The slide to link to\n\t */\n\tgetHash( slide ) {\n\n\t\tlet url = '/';\n\n\t\t// Attempt to create a named link based on the slide's ID\n\t\tlet s = slide || this.Reveal.getCurrentSlide();\n\t\tlet id = s ? s.getAttribute( 'id' ) : null;\n\t\tif( id ) {\n\t\t\tid = encodeURIComponent( id );\n\t\t}\n\n\t\tlet index = this.Reveal.getIndices( slide );\n\t\tif( !this.Reveal.getConfig().fragmentInURL ) {\n\t\t\tindex.f = undefined;\n\t\t}\n\n\t\t// If the current slide has an ID, use that as a named link,\n\t\t// but we don't support named links with a fragment index\n\t\tif( typeof id === 'string' && id.length ) {\n\t\t\turl = '/' + id;\n\n\t\t\t// If there is also a fragment, append that at the end\n\t\t\t// of the named link, like: #/named-link/2\n\t\t\tif( index.f >= 0 ) url += '/' + index.f;\n\t\t}\n\t\t// Otherwise use the /h/v index\n\t\telse {\n\t\t\tlet hashIndexBase = this.Reveal.getConfig().hashOneBasedIndex ? 1 : 0;\n\t\t\tif( index.h > 0 || index.v > 0 || index.f >= 0 ) url += index.h + hashIndexBase;\n\t\t\tif( index.v > 0 || index.f >= 0 ) url += '/' + (index.v + hashIndexBase );\n\t\t\tif( index.f >= 0 ) url += '/' + index.f;\n\t\t}\n\n\t\treturn url;\n\n\t}\n\n\t/**\n\t * Handler for the window level 'hashchange' event.\n\t *\n\t * @param {object} [event]\n\t */\n\tonWindowHashChange( event ) {\n\n\t\tthis.readURL();\n\n\t}\n\n}","import { queryAll } from '../utils/util.js'\nimport { isAndroid } from '../utils/device.js'\n\n/**\n * Manages our presentation controls. This includes both\n * the built-in control arrows as well as event monitoring\n * of any elements within the presentation with either of the\n * following helper classes:\n * - .navigate-up\n * - .navigate-right\n * - .navigate-down\n * - .navigate-left\n * - .navigate-next\n * - .navigate-prev\n */\nexport default class Controls {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.onNavigateLeftClicked = this.onNavigateLeftClicked.bind( this );\n\t\tthis.onNavigateRightClicked = this.onNavigateRightClicked.bind( this );\n\t\tthis.onNavigateUpClicked = this.onNavigateUpClicked.bind( this );\n\t\tthis.onNavigateDownClicked = this.onNavigateDownClicked.bind( this );\n\t\tthis.onNavigatePrevClicked = this.onNavigatePrevClicked.bind( this );\n\t\tthis.onNavigateNextClicked = this.onNavigateNextClicked.bind( this );\n\n\t}\n\n\trender() {\n\n\t\tconst rtl = this.Reveal.getConfig().rtl;\n\t\tconst revealElement = this.Reveal.getRevealElement();\n\n\t\tthis.element = document.createElement( 'aside' );\n\t\tthis.element.className = 'controls';\n\t\tthis.element.innerHTML =\n\t\t\t`
\n\t\t\t
\n\t\t\t
\n\t\t\t
`;\n\n\t\tthis.Reveal.getRevealElement().appendChild( this.element );\n\n\t\t// There can be multiple instances of controls throughout the page\n\t\tthis.controlsLeft = queryAll( revealElement, '.navigate-left' );\n\t\tthis.controlsRight = queryAll( revealElement, '.navigate-right' );\n\t\tthis.controlsUp = queryAll( revealElement, '.navigate-up' );\n\t\tthis.controlsDown = queryAll( revealElement, '.navigate-down' );\n\t\tthis.controlsPrev = queryAll( revealElement, '.navigate-prev' );\n\t\tthis.controlsNext = queryAll( revealElement, '.navigate-next' );\n\n\t\t// The left, right and down arrows in the standard reveal.js controls\n\t\tthis.controlsRightArrow = this.element.querySelector( '.navigate-right' );\n\t\tthis.controlsLeftArrow = this.element.querySelector( '.navigate-left' );\n\t\tthis.controlsDownArrow = this.element.querySelector( '.navigate-down' );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tthis.element.style.display = config.controls ? 'block' : 'none';\n\n\t\tthis.element.setAttribute( 'data-controls-layout', config.controlsLayout );\n\t\tthis.element.setAttribute( 'data-controls-back-arrows', config.controlsBackArrows );\n\n\t}\n\n\tbind() {\n\n\t\t// Listen to both touch and click events, in case the device\n\t\t// supports both\n\t\tlet pointerEvents = [ 'touchstart', 'click' ];\n\n\t\t// Only support touch for Android, fixes double navigations in\n\t\t// stock browser\n\t\tif( isAndroid ) {\n\t\t\tpointerEvents = [ 'touchstart' ];\n\t\t}\n\n\t\tpointerEvents.forEach( eventName => {\n\t\t\tthis.controlsLeft.forEach( el => el.addEventListener( eventName, this.onNavigateLeftClicked, false ) );\n\t\t\tthis.controlsRight.forEach( el => el.addEventListener( eventName, this.onNavigateRightClicked, false ) );\n\t\t\tthis.controlsUp.forEach( el => el.addEventListener( eventName, this.onNavigateUpClicked, false ) );\n\t\t\tthis.controlsDown.forEach( el => el.addEventListener( eventName, this.onNavigateDownClicked, false ) );\n\t\t\tthis.controlsPrev.forEach( el => el.addEventListener( eventName, this.onNavigatePrevClicked, false ) );\n\t\t\tthis.controlsNext.forEach( el => el.addEventListener( eventName, this.onNavigateNextClicked, false ) );\n\t\t} );\n\n\t}\n\n\tunbind() {\n\n\t\t[ 'touchstart', 'click' ].forEach( eventName => {\n\t\t\tthis.controlsLeft.forEach( el => el.removeEventListener( eventName, this.onNavigateLeftClicked, false ) );\n\t\t\tthis.controlsRight.forEach( el => el.removeEventListener( eventName, this.onNavigateRightClicked, false ) );\n\t\t\tthis.controlsUp.forEach( el => el.removeEventListener( eventName, this.onNavigateUpClicked, false ) );\n\t\t\tthis.controlsDown.forEach( el => el.removeEventListener( eventName, this.onNavigateDownClicked, false ) );\n\t\t\tthis.controlsPrev.forEach( el => el.removeEventListener( eventName, this.onNavigatePrevClicked, false ) );\n\t\t\tthis.controlsNext.forEach( el => el.removeEventListener( eventName, this.onNavigateNextClicked, false ) );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Updates the state of all control/navigation arrows.\n\t */\n\tupdate() {\n\n\t\tlet routes = this.Reveal.availableRoutes();\n\n\t\t// Remove the 'enabled' class from all directions\n\t\t[...this.controlsLeft, ...this.controlsRight, ...this.controlsUp, ...this.controlsDown, ...this.controlsPrev, ...this.controlsNext].forEach( node => {\n\t\t\tnode.classList.remove( 'enabled', 'fragmented' );\n\n\t\t\t// Set 'disabled' attribute on all directions\n\t\t\tnode.setAttribute( 'disabled', 'disabled' );\n\t\t} );\n\n\t\t// Add the 'enabled' class to the available routes; remove 'disabled' attribute to enable buttons\n\t\tif( routes.left ) this.controlsLeft.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\tif( routes.right ) this.controlsRight.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\tif( routes.up ) this.controlsUp.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\tif( routes.down ) this.controlsDown.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\n\t\t// Prev/next buttons\n\t\tif( routes.left || routes.up ) this.controlsPrev.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\tif( routes.right || routes.down ) this.controlsNext.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\n\t\t// Highlight fragment directions\n\t\tlet currentSlide = this.Reveal.getCurrentSlide();\n\t\tif( currentSlide ) {\n\n\t\t\tlet fragmentsRoutes = this.Reveal.fragments.availableRoutes();\n\n\t\t\t// Always apply fragment decorator to prev/next buttons\n\t\t\tif( fragmentsRoutes.prev ) this.controlsPrev.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\t\tif( fragmentsRoutes.next ) this.controlsNext.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\n\t\t\t// Apply fragment decorators to directional buttons based on\n\t\t\t// what slide axis they are in\n\t\t\tif( this.Reveal.isVerticalSlide( currentSlide ) ) {\n\t\t\t\tif( fragmentsRoutes.prev ) this.controlsUp.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\t\t\tif( fragmentsRoutes.next ) this.controlsDown.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif( fragmentsRoutes.prev ) this.controlsLeft.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\t\t\tif( fragmentsRoutes.next ) this.controlsRight.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\t\t}\n\n\t\t}\n\n\t\tif( this.Reveal.getConfig().controlsTutorial ) {\n\n\t\t\tlet indices = this.Reveal.getIndices();\n\n\t\t\t// Highlight control arrows with an animation to ensure\n\t\t\t// that the viewer knows how to navigate\n\t\t\tif( !this.Reveal.hasNavigatedVertically() && routes.down ) {\n\t\t\t\tthis.controlsDownArrow.classList.add( 'highlight' );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.controlsDownArrow.classList.remove( 'highlight' );\n\n\t\t\t\tif( this.Reveal.getConfig().rtl ) {\n\n\t\t\t\t\tif( !this.Reveal.hasNavigatedHorizontally() && routes.left && indices.v === 0 ) {\n\t\t\t\t\t\tthis.controlsLeftArrow.classList.add( 'highlight' );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.controlsLeftArrow.classList.remove( 'highlight' );\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif( !this.Reveal.hasNavigatedHorizontally() && routes.right && indices.v === 0 ) {\n\t\t\t\t\t\tthis.controlsRightArrow.classList.add( 'highlight' );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.controlsRightArrow.classList.remove( 'highlight' );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tdestroy() {\n\n\t\tthis.unbind();\n\t\tthis.element.remove();\n\n\t}\n\n\t/**\n\t * Event handlers for navigation control buttons.\n\t */\n\tonNavigateLeftClicked( event ) {\n\n\t\tevent.preventDefault();\n\t\tthis.Reveal.onUserInput();\n\n\t\tif( this.Reveal.getConfig().navigationMode === 'linear' ) {\n\t\t\tthis.Reveal.prev();\n\t\t}\n\t\telse {\n\t\t\tthis.Reveal.left();\n\t\t}\n\n\t}\n\n\tonNavigateRightClicked( event ) {\n\n\t\tevent.preventDefault();\n\t\tthis.Reveal.onUserInput();\n\n\t\tif( this.Reveal.getConfig().navigationMode === 'linear' ) {\n\t\t\tthis.Reveal.next();\n\t\t}\n\t\telse {\n\t\t\tthis.Reveal.right();\n\t\t}\n\n\t}\n\n\tonNavigateUpClicked( event ) {\n\n\t\tevent.preventDefault();\n\t\tthis.Reveal.onUserInput();\n\n\t\tthis.Reveal.up();\n\n\t}\n\n\tonNavigateDownClicked( event ) {\n\n\t\tevent.preventDefault();\n\t\tthis.Reveal.onUserInput();\n\n\t\tthis.Reveal.down();\n\n\t}\n\n\tonNavigatePrevClicked( event ) {\n\n\t\tevent.preventDefault();\n\t\tthis.Reveal.onUserInput();\n\n\t\tthis.Reveal.prev();\n\n\t}\n\n\tonNavigateNextClicked( event ) {\n\n\t\tevent.preventDefault();\n\t\tthis.Reveal.onUserInput();\n\n\t\tthis.Reveal.next();\n\n\t}\n\n\n}","/**\n * Creates a visual progress bar for the presentation.\n */\nexport default class Progress {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.onProgressClicked = this.onProgressClicked.bind( this );\n\n\t}\n\n\trender() {\n\n\t\tthis.element = document.createElement( 'div' );\n\t\tthis.element.className = 'progress';\n\t\tthis.Reveal.getRevealElement().appendChild( this.element );\n\n\t\tthis.bar = document.createElement( 'span' );\n\t\tthis.element.appendChild( this.bar );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tthis.element.style.display = config.progress ? 'block' : 'none';\n\n\t}\n\n\tbind() {\n\n\t\tif( this.Reveal.getConfig().progress && this.element ) {\n\t\t\tthis.element.addEventListener( 'click', this.onProgressClicked, false );\n\t\t}\n\n\t}\n\n\tunbind() {\n\n\t\tif ( this.Reveal.getConfig().progress && this.element ) {\n\t\t\tthis.element.removeEventListener( 'click', this.onProgressClicked, false );\n\t\t}\n\n\t}\n\n\t/**\n\t * Updates the progress bar to reflect the current slide.\n\t */\n\tupdate() {\n\n\t\t// Update progress if enabled\n\t\tif( this.Reveal.getConfig().progress && this.bar ) {\n\n\t\t\tlet scale = this.Reveal.getProgress();\n\n\t\t\t// Don't fill the progress bar if there's only one slide\n\t\t\tif( this.Reveal.getTotalSlides() < 2 ) {\n\t\t\t\tscale = 0;\n\t\t\t}\n\n\t\t\tthis.bar.style.transform = 'scaleX('+ scale +')';\n\n\t\t}\n\n\t}\n\n\tgetMaxWidth() {\n\n\t\treturn this.Reveal.getRevealElement().offsetWidth;\n\n\t}\n\n\t/**\n\t * Clicking on the progress bar results in a navigation to the\n\t * closest approximate horizontal slide using this equation:\n\t *\n\t * ( clickX / presentationWidth ) * numberOfSlides\n\t *\n\t * @param {object} event\n\t */\n\tonProgressClicked( event ) {\n\n\t\tthis.Reveal.onUserInput( event );\n\n\t\tevent.preventDefault();\n\n\t\tlet slides = this.Reveal.getSlides();\n\t\tlet slidesTotal = slides.length;\n\t\tlet slideIndex = Math.floor( ( event.clientX / this.getMaxWidth() ) * slidesTotal );\n\n\t\tif( this.Reveal.getConfig().rtl ) {\n\t\t\tslideIndex = slidesTotal - slideIndex;\n\t\t}\n\n\t\tlet targetIndices = this.Reveal.getIndices(slides[slideIndex]);\n\t\tthis.Reveal.slide( targetIndices.h, targetIndices.v );\n\n\t}\n\n\tdestroy() {\n\n\t\tthis.element.remove();\n\n\t}\n\n}","/**\n * Handles hiding of the pointer/cursor when inactive.\n */\nexport default class Pointer {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\t// Throttles mouse wheel navigation\n\t\tthis.lastMouseWheelStep = 0;\n\n\t\t// Is the mouse pointer currently hidden from view\n\t\tthis.cursorHidden = false;\n\n\t\t// Timeout used to determine when the cursor is inactive\n\t\tthis.cursorInactiveTimeout = 0;\n\n\t\tthis.onDocumentCursorActive = this.onDocumentCursorActive.bind( this );\n\t\tthis.onDocumentMouseScroll = this.onDocumentMouseScroll.bind( this );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tif( config.mouseWheel ) {\n\t\t\tdocument.addEventListener( 'DOMMouseScroll', this.onDocumentMouseScroll, false ); // FF\n\t\t\tdocument.addEventListener( 'mousewheel', this.onDocumentMouseScroll, false );\n\t\t}\n\t\telse {\n\t\t\tdocument.removeEventListener( 'DOMMouseScroll', this.onDocumentMouseScroll, false ); // FF\n\t\t\tdocument.removeEventListener( 'mousewheel', this.onDocumentMouseScroll, false );\n\t\t}\n\n\t\t// Auto-hide the mouse pointer when its inactive\n\t\tif( config.hideInactiveCursor ) {\n\t\t\tdocument.addEventListener( 'mousemove', this.onDocumentCursorActive, false );\n\t\t\tdocument.addEventListener( 'mousedown', this.onDocumentCursorActive, false );\n\t\t}\n\t\telse {\n\t\t\tthis.showCursor();\n\n\t\t\tdocument.removeEventListener( 'mousemove', this.onDocumentCursorActive, false );\n\t\t\tdocument.removeEventListener( 'mousedown', this.onDocumentCursorActive, false );\n\t\t}\n\n\t}\n\n\t/**\n\t * Shows the mouse pointer after it has been hidden with\n\t * #hideCursor.\n\t */\n\tshowCursor() {\n\n\t\tif( this.cursorHidden ) {\n\t\t\tthis.cursorHidden = false;\n\t\t\tthis.Reveal.getRevealElement().style.cursor = '';\n\t\t}\n\n\t}\n\n\t/**\n\t * Hides the mouse pointer when it's on top of the .reveal\n\t * container.\n\t */\n\thideCursor() {\n\n\t\tif( this.cursorHidden === false ) {\n\t\t\tthis.cursorHidden = true;\n\t\t\tthis.Reveal.getRevealElement().style.cursor = 'none';\n\t\t}\n\n\t}\n\n\tdestroy() {\n\n\t\tthis.showCursor();\n\n\t\tdocument.removeEventListener( 'DOMMouseScroll', this.onDocumentMouseScroll, false );\n\t\tdocument.removeEventListener( 'mousewheel', this.onDocumentMouseScroll, false );\n\t\tdocument.removeEventListener( 'mousemove', this.onDocumentCursorActive, false );\n\t\tdocument.removeEventListener( 'mousedown', this.onDocumentCursorActive, false );\n\n\t}\n\n\t/**\n\t * Called whenever there is mouse input at the document level\n\t * to determine if the cursor is active or not.\n\t *\n\t * @param {object} event\n\t */\n\tonDocumentCursorActive( event ) {\n\n\t\tthis.showCursor();\n\n\t\tclearTimeout( this.cursorInactiveTimeout );\n\n\t\tthis.cursorInactiveTimeout = setTimeout( this.hideCursor.bind( this ), this.Reveal.getConfig().hideCursorTime );\n\n\t}\n\n\t/**\n\t * Handles mouse wheel scrolling, throttled to avoid skipping\n\t * multiple slides.\n\t *\n\t * @param {object} event\n\t */\n\tonDocumentMouseScroll( event ) {\n\n\t\tif( Date.now() - this.lastMouseWheelStep > 1000 ) {\n\n\t\t\tthis.lastMouseWheelStep = Date.now();\n\n\t\t\tlet delta = event.detail || -event.wheelDelta;\n\t\t\tif( delta > 0 ) {\n\t\t\t\tthis.Reveal.next();\n\t\t\t}\n\t\t\telse if( delta < 0 ) {\n\t\t\t\tthis.Reveal.prev();\n\t\t\t}\n\n\t\t}\n\n\t}\n\n}","/**\n * Loads a JavaScript file from the given URL and executes it.\n *\n * @param {string} url Address of the .js file to load\n * @param {function} callback Method to invoke when the script\n * has loaded and executed\n */\nexport const loadScript = ( url, callback ) => {\n\n\tconst script = document.createElement( 'script' );\n\tscript.type = 'text/javascript';\n\tscript.async = false;\n\tscript.defer = false;\n\tscript.src = url;\n\n\tif( typeof callback === 'function' ) {\n\n\t\t// Success callback\n\t\tscript.onload = script.onreadystatechange = event => {\n\t\t\tif( event.type === 'load' || /loaded|complete/.test( script.readyState ) ) {\n\n\t\t\t\t// Kill event listeners\n\t\t\t\tscript.onload = script.onreadystatechange = script.onerror = null;\n\n\t\t\t\tcallback();\n\n\t\t\t}\n\t\t};\n\n\t\t// Error callback\n\t\tscript.onerror = err => {\n\n\t\t\t// Kill event listeners\n\t\t\tscript.onload = script.onreadystatechange = script.onerror = null;\n\n\t\t\tcallback( new Error( 'Failed loading script: ' + script.src + '\\n' + err ) );\n\n\t\t};\n\n\t}\n\n\t// Append the script at the end of \n\tconst head = document.querySelector( 'head' );\n\thead.insertBefore( script, head.lastChild );\n\n}","import { loadScript } from '../utils/loader.js'\n\n/**\n * Manages loading and registering of reveal.js plugins.\n */\nexport default class Plugins {\n\n\tconstructor( reveal ) {\n\n\t\tthis.Reveal = reveal;\n\n\t\t// Flags our current state (idle -> loading -> loaded)\n\t\tthis.state = 'idle';\n\n\t\t// An id:instance map of currently registed plugins\n\t\tthis.registeredPlugins = {};\n\n\t\tthis.asyncDependencies = [];\n\n\t}\n\n\t/**\n\t * Loads reveal.js dependencies, registers and\n\t * initializes plugins.\n\t *\n\t * Plugins are direct references to a reveal.js plugin\n\t * object that we register and initialize after any\n\t * synchronous dependencies have loaded.\n\t *\n\t * Dependencies are defined via the 'dependencies' config\n\t * option and will be loaded prior to starting reveal.js.\n\t * Some dependencies may have an 'async' flag, if so they\n\t * will load after reveal.js has been started up.\n\t */\n\tload( plugins, dependencies ) {\n\n\t\tthis.state = 'loading';\n\n\t\tplugins.forEach( this.registerPlugin.bind( this ) );\n\n\t\treturn new Promise( resolve => {\n\n\t\t\tlet scripts = [],\n\t\t\t\tscriptsToLoad = 0;\n\n\t\t\tdependencies.forEach( s => {\n\t\t\t\t// Load if there's no condition or the condition is truthy\n\t\t\t\tif( !s.condition || s.condition() ) {\n\t\t\t\t\tif( s.async ) {\n\t\t\t\t\t\tthis.asyncDependencies.push( s );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tscripts.push( s );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tif( scripts.length ) {\n\t\t\t\tscriptsToLoad = scripts.length;\n\n\t\t\t\tconst scriptLoadedCallback = (s) => {\n\t\t\t\t\tif( s && typeof s.callback === 'function' ) s.callback();\n\n\t\t\t\t\tif( --scriptsToLoad === 0 ) {\n\t\t\t\t\t\tthis.initPlugins().then( resolve );\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Load synchronous scripts\n\t\t\t\tscripts.forEach( s => {\n\t\t\t\t\tif( typeof s.id === 'string' ) {\n\t\t\t\t\t\tthis.registerPlugin( s );\n\t\t\t\t\t\tscriptLoadedCallback( s );\n\t\t\t\t\t}\n\t\t\t\t\telse if( typeof s.src === 'string' ) {\n\t\t\t\t\t\tloadScript( s.src, () => scriptLoadedCallback(s) );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tconsole.warn( 'Unrecognized plugin format', s );\n\t\t\t\t\t\tscriptLoadedCallback();\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.initPlugins().then( resolve );\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Initializes our plugins and waits for them to be ready\n\t * before proceeding.\n\t */\n\tinitPlugins() {\n\n\t\treturn new Promise( resolve => {\n\n\t\t\tlet pluginValues = Object.values( this.registeredPlugins );\n\t\t\tlet pluginsToInitialize = pluginValues.length;\n\n\t\t\t// If there are no plugins, skip this step\n\t\t\tif( pluginsToInitialize === 0 ) {\n\t\t\t\tthis.loadAsync().then( resolve );\n\t\t\t}\n\t\t\t// ... otherwise initialize plugins\n\t\t\telse {\n\n\t\t\t\tlet initNextPlugin;\n\n\t\t\t\tlet afterPlugInitialized = () => {\n\t\t\t\t\tif( --pluginsToInitialize === 0 ) {\n\t\t\t\t\t\tthis.loadAsync().then( resolve );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tinitNextPlugin();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tlet i = 0;\n\n\t\t\t\t// Initialize plugins serially\n\t\t\t\tinitNextPlugin = () => {\n\n\t\t\t\t\tlet plugin = pluginValues[i++];\n\n\t\t\t\t\t// If the plugin has an 'init' method, invoke it\n\t\t\t\t\tif( typeof plugin.init === 'function' ) {\n\t\t\t\t\t\tlet promise = plugin.init( this.Reveal );\n\n\t\t\t\t\t\t// If the plugin returned a Promise, wait for it\n\t\t\t\t\t\tif( promise && typeof promise.then === 'function' ) {\n\t\t\t\t\t\t\tpromise.then( afterPlugInitialized );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tafterPlugInitialized();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tafterPlugInitialized();\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tinitNextPlugin();\n\n\t\t\t}\n\n\t\t} )\n\n\t}\n\n\t/**\n\t * Loads all async reveal.js dependencies.\n\t */\n\tloadAsync() {\n\n\t\tthis.state = 'loaded';\n\n\t\tif( this.asyncDependencies.length ) {\n\t\t\tthis.asyncDependencies.forEach( s => {\n\t\t\t\tloadScript( s.src, s.callback );\n\t\t\t} );\n\t\t}\n\n\t\treturn Promise.resolve();\n\n\t}\n\n\t/**\n\t * Registers a new plugin with this reveal.js instance.\n\t *\n\t * reveal.js waits for all regisered plugins to initialize\n\t * before considering itself ready, as long as the plugin\n\t * is registered before calling `Reveal.initialize()`.\n\t */\n\tregisterPlugin( plugin ) {\n\n\t\t// Backwards compatibility to make reveal.js ~3.9.0\n\t\t// plugins work with reveal.js 4.0.0\n\t\tif( arguments.length === 2 && typeof arguments[0] === 'string' ) {\n\t\t\tplugin = arguments[1];\n\t\t\tplugin.id = arguments[0];\n\t\t}\n\t\t// Plugin can optionally be a function which we call\n\t\t// to create an instance of the plugin\n\t\telse if( typeof plugin === 'function' ) {\n\t\t\tplugin = plugin();\n\t\t}\n\n\t\tlet id = plugin.id;\n\n\t\tif( typeof id !== 'string' ) {\n\t\t\tconsole.warn( 'Unrecognized plugin format; can\\'t find plugin.id', plugin );\n\t\t}\n\t\telse if( this.registeredPlugins[id] === undefined ) {\n\t\t\tthis.registeredPlugins[id] = plugin;\n\n\t\t\t// If a plugin is registered after reveal.js is loaded,\n\t\t\t// initialize it right away\n\t\t\tif( this.state === 'loaded' && typeof plugin.init === 'function' ) {\n\t\t\t\tplugin.init( this.Reveal );\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tconsole.warn( 'reveal.js: \"'+ id +'\" plugin has already been registered' );\n\t\t}\n\n\t}\n\n\t/**\n\t * Checks if a specific plugin has been registered.\n\t *\n\t * @param {String} id Unique plugin identifier\n\t */\n\thasPlugin( id ) {\n\n\t\treturn !!this.registeredPlugins[id];\n\n\t}\n\n\t/**\n\t * Returns the specific plugin instance, if a plugin\n\t * with the given ID has been registered.\n\t *\n\t * @param {String} id Unique plugin identifier\n\t */\n\tgetPlugin( id ) {\n\n\t\treturn this.registeredPlugins[id];\n\n\t}\n\n\tgetRegisteredPlugins() {\n\n\t\treturn this.registeredPlugins;\n\n\t}\n\n\tdestroy() {\n\n\t\tObject.values( this.registeredPlugins ).forEach( plugin => {\n\t\t\tif( typeof plugin.destroy === 'function' ) {\n\t\t\t\tplugin.destroy();\n\t\t\t}\n\t\t} );\n\n\t\tthis.registeredPlugins = {};\n\t\tthis.asyncDependencies = [];\n\n\t}\n\n}\n","import { SLIDES_SELECTOR } from '../utils/constants.js'\nimport { queryAll, createStyleSheet } from '../utils/util.js'\n\n/**\n * Setups up our presentation for printing/exporting to PDF.\n */\nexport default class Print {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t}\n\n\t/**\n\t * Configures the presentation for printing to a static\n\t * PDF.\n\t */\n\tasync setupPDF() {\n\n\t\tconst config = this.Reveal.getConfig();\n\t\tconst slides = queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR )\n\n\t\t// Compute slide numbers now, before we start duplicating slides\n\t\tconst doingSlideNumbers = config.slideNumber && /all|print/i.test( config.showSlideNumber );\n\n\t\tconst slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );\n\n\t\t// Dimensions of the PDF pages\n\t\tconst pageWidth = Math.floor( slideSize.width * ( 1 + config.margin ) ),\n\t\t\tpageHeight = Math.floor( slideSize.height * ( 1 + config.margin ) );\n\n\t\t// Dimensions of slides within the pages\n\t\tconst slideWidth = slideSize.width,\n\t\t\tslideHeight = slideSize.height;\n\n\t\tawait new Promise( requestAnimationFrame );\n\n\t\t// Let the browser know what page size we want to print\n\t\tcreateStyleSheet( '@page{size:'+ pageWidth +'px '+ pageHeight +'px; margin: 0px;}' );\n\n\t\t// Limit the size of certain elements to the dimensions of the slide\n\t\tcreateStyleSheet( '.reveal section>img, .reveal section>video, .reveal section>iframe{max-width: '+ slideWidth +'px; max-height:'+ slideHeight +'px}' );\n\n\t\tdocument.documentElement.classList.add( 'print-pdf' );\n\t\tdocument.body.style.width = pageWidth + 'px';\n\t\tdocument.body.style.height = pageHeight + 'px';\n\n\t\tconst viewportElement = document.querySelector( '.reveal-viewport' );\n\t\tlet presentationBackground;\n\t\tif( viewportElement ) {\n\t\t\tconst viewportStyles = window.getComputedStyle( viewportElement );\n\t\t\tif( viewportStyles && viewportStyles.background ) {\n\t\t\t\tpresentationBackground = viewportStyles.background;\n\t\t\t}\n\t\t}\n\n\t\t// Make sure stretch elements fit on slide\n\t\tawait new Promise( requestAnimationFrame );\n\t\tthis.Reveal.layoutSlideContents( slideWidth, slideHeight );\n\n\t\t// Batch scrollHeight access to prevent layout thrashing\n\t\tawait new Promise( requestAnimationFrame );\n\n\t\tconst slideScrollHeights = slides.map( slide => slide.scrollHeight );\n\n\t\tconst pages = [];\n\t\tconst pageContainer = slides[0].parentNode;\n\n\t\t// Slide and slide background layout\n\t\tslides.forEach( function( slide, index ) {\n\n\t\t\t// Vertical stacks are not centred since their section\n\t\t\t// children will be\n\t\t\tif( slide.classList.contains( 'stack' ) === false ) {\n\t\t\t\t// Center the slide inside of the page, giving the slide some margin\n\t\t\t\tlet left = ( pageWidth - slideWidth ) / 2;\n\t\t\t\tlet top = ( pageHeight - slideHeight ) / 2;\n\n\t\t\t\tconst contentHeight = slideScrollHeights[ index ];\n\t\t\t\tlet numberOfPages = Math.max( Math.ceil( contentHeight / pageHeight ), 1 );\n\n\t\t\t\t// Adhere to configured pages per slide limit\n\t\t\t\tnumberOfPages = Math.min( numberOfPages, config.pdfMaxPagesPerSlide );\n\n\t\t\t\t// Center slides vertically\n\t\t\t\tif( numberOfPages === 1 && config.center || slide.classList.contains( 'center' ) ) {\n\t\t\t\t\ttop = Math.max( ( pageHeight - contentHeight ) / 2, 0 );\n\t\t\t\t}\n\n\t\t\t\t// Wrap the slide in a page element and hide its overflow\n\t\t\t\t// so that no page ever flows onto another\n\t\t\t\tconst page = document.createElement( 'div' );\n\t\t\t\tpages.push( page );\n\n\t\t\t\tpage.className = 'pdf-page';\n\t\t\t\tpage.style.height = ( ( pageHeight + config.pdfPageHeightOffset ) * numberOfPages ) + 'px';\n\n\t\t\t\t// Copy the presentation-wide background to each individual\n\t\t\t\t// page when printing\n\t\t\t\tif( presentationBackground ) {\n\t\t\t\t\tpage.style.background = presentationBackground;\n\t\t\t\t}\n\n\t\t\t\tpage.appendChild( slide );\n\n\t\t\t\t// Position the slide inside of the page\n\t\t\t\tslide.style.left = left + 'px';\n\t\t\t\tslide.style.top = top + 'px';\n\t\t\t\tslide.style.width = slideWidth + 'px';\n\n\t\t\t\t// Re-run the slide layout so that r-fit-text is applied based on\n\t\t\t\t// the printed slide size\n\t\t\t\tthis.Reveal.slideContent.layout( slide )\n\n\t\t\t\tif( slide.slideBackgroundElement ) {\n\t\t\t\t\tpage.insertBefore( slide.slideBackgroundElement, slide );\n\t\t\t\t}\n\n\t\t\t\t// Inject notes if `showNotes` is enabled\n\t\t\t\tif( config.showNotes ) {\n\n\t\t\t\t\t// Are there notes for this slide?\n\t\t\t\t\tconst notes = this.Reveal.getSlideNotes( slide );\n\t\t\t\t\tif( notes ) {\n\n\t\t\t\t\t\tconst notesSpacing = 8;\n\t\t\t\t\t\tconst notesLayout = typeof config.showNotes === 'string' ? config.showNotes : 'inline';\n\t\t\t\t\t\tconst notesElement = document.createElement( 'div' );\n\t\t\t\t\t\tnotesElement.classList.add( 'speaker-notes' );\n\t\t\t\t\t\tnotesElement.classList.add( 'speaker-notes-pdf' );\n\t\t\t\t\t\tnotesElement.setAttribute( 'data-layout', notesLayout );\n\t\t\t\t\t\tnotesElement.innerHTML = notes;\n\n\t\t\t\t\t\tif( notesLayout === 'separate-page' ) {\n\t\t\t\t\t\t\tpages.push( notesElement );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tnotesElement.style.left = notesSpacing + 'px';\n\t\t\t\t\t\t\tnotesElement.style.bottom = notesSpacing + 'px';\n\t\t\t\t\t\t\tnotesElement.style.width = ( pageWidth - notesSpacing*2 ) + 'px';\n\t\t\t\t\t\t\tpage.appendChild( notesElement );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Inject slide numbers if `slideNumbers` are enabled\n\t\t\t\tif( doingSlideNumbers ) {\n\t\t\t\t\tconst slideNumber = index + 1;\n\t\t\t\t\tconst numberElement = document.createElement( 'div' );\n\t\t\t\t\tnumberElement.classList.add( 'slide-number' );\n\t\t\t\t\tnumberElement.classList.add( 'slide-number-pdf' );\n\t\t\t\t\tnumberElement.innerHTML = slideNumber;\n\t\t\t\t\tpage.appendChild( numberElement );\n\t\t\t\t}\n\n\t\t\t\t// Copy page and show fragments one after another\n\t\t\t\tif( config.pdfSeparateFragments ) {\n\n\t\t\t\t\t// Each fragment 'group' is an array containing one or more\n\t\t\t\t\t// fragments. Multiple fragments that appear at the same time\n\t\t\t\t\t// are part of the same group.\n\t\t\t\t\tconst fragmentGroups = this.Reveal.fragments.sort( page.querySelectorAll( '.fragment' ), true );\n\n\t\t\t\t\tlet previousFragmentStep;\n\n\t\t\t\t\tfragmentGroups.forEach( function( fragments ) {\n\n\t\t\t\t\t\t// Remove 'current-fragment' from the previous group\n\t\t\t\t\t\tif( previousFragmentStep ) {\n\t\t\t\t\t\t\tpreviousFragmentStep.forEach( function( fragment ) {\n\t\t\t\t\t\t\t\tfragment.classList.remove( 'current-fragment' );\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Show the fragments for the current index\n\t\t\t\t\t\tfragments.forEach( function( fragment ) {\n\t\t\t\t\t\t\tfragment.classList.add( 'visible', 'current-fragment' );\n\t\t\t\t\t\t}, this );\n\n\t\t\t\t\t\t// Create a separate page for the current fragment state\n\t\t\t\t\t\tconst clonedPage = page.cloneNode( true );\n\t\t\t\t\t\tpages.push( clonedPage );\n\n\t\t\t\t\t\tpreviousFragmentStep = fragments;\n\n\t\t\t\t\t}, this );\n\n\t\t\t\t\t// Reset the first/original page so that all fragments are hidden\n\t\t\t\t\tfragmentGroups.forEach( function( fragments ) {\n\t\t\t\t\t\tfragments.forEach( function( fragment ) {\n\t\t\t\t\t\t\tfragment.classList.remove( 'visible', 'current-fragment' );\n\t\t\t\t\t\t} );\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\t\t\t\t// Show all fragments\n\t\t\t\telse {\n\t\t\t\t\tqueryAll( page, '.fragment:not(.fade-out)' ).forEach( function( fragment ) {\n\t\t\t\t\t\tfragment.classList.add( 'visible' );\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}, this );\n\n\t\tawait new Promise( requestAnimationFrame );\n\n\t\tpages.forEach( page => pageContainer.appendChild( page ) );\n\n\t\t// Notify subscribers that the PDF layout is good to go\n\t\tthis.Reveal.dispatchEvent({ type: 'pdf-ready' });\n\n\t}\n\n\t/**\n\t * Checks if this instance is being used to print a PDF.\n\t */\n\tisPrintingPDF() {\n\n\t\treturn ( /print-pdf/gi ).test( window.location.search );\n\n\t}\n\n}\n","import { isAndroid } from '../utils/device.js'\nimport { matches } from '../utils/util.js'\n\nconst SWIPE_THRESHOLD = 40;\n\n/**\n * Controls all touch interactions and navigations for\n * a presentation.\n */\nexport default class Touch {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\t// Holds information about the currently ongoing touch interaction\n\t\tthis.touchStartX = 0;\n\t\tthis.touchStartY = 0;\n\t\tthis.touchStartCount = 0;\n\t\tthis.touchCaptured = false;\n\n\t\tthis.onPointerDown = this.onPointerDown.bind( this );\n\t\tthis.onPointerMove = this.onPointerMove.bind( this );\n\t\tthis.onPointerUp = this.onPointerUp.bind( this );\n\t\tthis.onTouchStart = this.onTouchStart.bind( this );\n\t\tthis.onTouchMove = this.onTouchMove.bind( this );\n\t\tthis.onTouchEnd = this.onTouchEnd.bind( this );\n\n\t}\n\n\t/**\n\t *\n\t */\n\tbind() {\n\n\t\tlet revealElement = this.Reveal.getRevealElement();\n\n\t\tif( 'onpointerdown' in window ) {\n\t\t\t// Use W3C pointer events\n\t\t\trevealElement.addEventListener( 'pointerdown', this.onPointerDown, false );\n\t\t\trevealElement.addEventListener( 'pointermove', this.onPointerMove, false );\n\t\t\trevealElement.addEventListener( 'pointerup', this.onPointerUp, false );\n\t\t}\n\t\telse if( window.navigator.msPointerEnabled ) {\n\t\t\t// IE 10 uses prefixed version of pointer events\n\t\t\trevealElement.addEventListener( 'MSPointerDown', this.onPointerDown, false );\n\t\t\trevealElement.addEventListener( 'MSPointerMove', this.onPointerMove, false );\n\t\t\trevealElement.addEventListener( 'MSPointerUp', this.onPointerUp, false );\n\t\t}\n\t\telse {\n\t\t\t// Fall back to touch events\n\t\t\trevealElement.addEventListener( 'touchstart', this.onTouchStart, false );\n\t\t\trevealElement.addEventListener( 'touchmove', this.onTouchMove, false );\n\t\t\trevealElement.addEventListener( 'touchend', this.onTouchEnd, false );\n\t\t}\n\n\t}\n\n\t/**\n\t *\n\t */\n\tunbind() {\n\n\t\tlet revealElement = this.Reveal.getRevealElement();\n\n\t\trevealElement.removeEventListener( 'pointerdown', this.onPointerDown, false );\n\t\trevealElement.removeEventListener( 'pointermove', this.onPointerMove, false );\n\t\trevealElement.removeEventListener( 'pointerup', this.onPointerUp, false );\n\n\t\trevealElement.removeEventListener( 'MSPointerDown', this.onPointerDown, false );\n\t\trevealElement.removeEventListener( 'MSPointerMove', this.onPointerMove, false );\n\t\trevealElement.removeEventListener( 'MSPointerUp', this.onPointerUp, false );\n\n\t\trevealElement.removeEventListener( 'touchstart', this.onTouchStart, false );\n\t\trevealElement.removeEventListener( 'touchmove', this.onTouchMove, false );\n\t\trevealElement.removeEventListener( 'touchend', this.onTouchEnd, false );\n\n\t}\n\n\t/**\n\t * Checks if the target element prevents the triggering of\n\t * swipe navigation.\n\t */\n\tisSwipePrevented( target ) {\n\n\t\t// Prevent accidental swipes when scrubbing timelines\n\t\tif( matches( target, 'video, audio' ) ) return true;\n\n\t\twhile( target && typeof target.hasAttribute === 'function' ) {\n\t\t\tif( target.hasAttribute( 'data-prevent-swipe' ) ) return true;\n\t\t\ttarget = target.parentNode;\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\t/**\n\t * Handler for the 'touchstart' event, enables support for\n\t * swipe and pinch gestures.\n\t *\n\t * @param {object} event\n\t */\n\tonTouchStart( event ) {\n\n\t\tif( this.isSwipePrevented( event.target ) ) return true;\n\n\t\tthis.touchStartX = event.touches[0].clientX;\n\t\tthis.touchStartY = event.touches[0].clientY;\n\t\tthis.touchStartCount = event.touches.length;\n\n\t}\n\n\t/**\n\t * Handler for the 'touchmove' event.\n\t *\n\t * @param {object} event\n\t */\n\tonTouchMove( event ) {\n\n\t\tif( this.isSwipePrevented( event.target ) ) return true;\n\n\t\tlet config = this.Reveal.getConfig();\n\n\t\t// Each touch should only trigger one action\n\t\tif( !this.touchCaptured ) {\n\t\t\tthis.Reveal.onUserInput( event );\n\n\t\t\tlet currentX = event.touches[0].clientX;\n\t\t\tlet currentY = event.touches[0].clientY;\n\n\t\t\t// There was only one touch point, look for a swipe\n\t\t\tif( event.touches.length === 1 && this.touchStartCount !== 2 ) {\n\n\t\t\t\tlet availableRoutes = this.Reveal.availableRoutes({ includeFragments: true });\n\n\t\t\t\tlet deltaX = currentX - this.touchStartX,\n\t\t\t\t\tdeltaY = currentY - this.touchStartY;\n\n\t\t\t\tif( deltaX > SWIPE_THRESHOLD && Math.abs( deltaX ) > Math.abs( deltaY ) ) {\n\t\t\t\t\tthis.touchCaptured = true;\n\t\t\t\t\tif( config.navigationMode === 'linear' ) {\n\t\t\t\t\t\tif( config.rtl ) {\n\t\t\t\t\t\t\tthis.Reveal.next();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tthis.Reveal.prev();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.Reveal.left();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if( deltaX < -SWIPE_THRESHOLD && Math.abs( deltaX ) > Math.abs( deltaY ) ) {\n\t\t\t\t\tthis.touchCaptured = true;\n\t\t\t\t\tif( config.navigationMode === 'linear' ) {\n\t\t\t\t\t\tif( config.rtl ) {\n\t\t\t\t\t\t\tthis.Reveal.prev();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tthis.Reveal.next();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.Reveal.right();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if( deltaY > SWIPE_THRESHOLD && availableRoutes.up ) {\n\t\t\t\t\tthis.touchCaptured = true;\n\t\t\t\t\tif( config.navigationMode === 'linear' ) {\n\t\t\t\t\t\tthis.Reveal.prev();\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.Reveal.up();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if( deltaY < -SWIPE_THRESHOLD && availableRoutes.down ) {\n\t\t\t\t\tthis.touchCaptured = true;\n\t\t\t\t\tif( config.navigationMode === 'linear' ) {\n\t\t\t\t\t\tthis.Reveal.next();\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.Reveal.down();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If we're embedded, only block touch events if they have\n\t\t\t\t// triggered an action\n\t\t\t\tif( config.embedded ) {\n\t\t\t\t\tif( this.touchCaptured || this.Reveal.isVerticalSlide() ) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Not embedded? Block them all to avoid needless tossing\n\t\t\t\t// around of the viewport in iOS\n\t\t\t\telse {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t\t// There's a bug with swiping on some Android devices unless\n\t\t// the default action is always prevented\n\t\telse if( isAndroid ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\n\t}\n\n\t/**\n\t * Handler for the 'touchend' event.\n\t *\n\t * @param {object} event\n\t */\n\tonTouchEnd( event ) {\n\n\t\tthis.touchCaptured = false;\n\n\t}\n\n\t/**\n\t * Convert pointer down to touch start.\n\t *\n\t * @param {object} event\n\t */\n\tonPointerDown( event ) {\n\n\t\tif( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === \"touch\" ) {\n\t\t\tevent.touches = [{ clientX: event.clientX, clientY: event.clientY }];\n\t\t\tthis.onTouchStart( event );\n\t\t}\n\n\t}\n\n\t/**\n\t * Convert pointer move to touch move.\n\t *\n\t * @param {object} event\n\t */\n\tonPointerMove( event ) {\n\n\t\tif( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === \"touch\" ) {\n\t\t\tevent.touches = [{ clientX: event.clientX, clientY: event.clientY }];\n\t\t\tthis.onTouchMove( event );\n\t\t}\n\n\t}\n\n\t/**\n\t * Convert pointer up to touch end.\n\t *\n\t * @param {object} event\n\t */\n\tonPointerUp( event ) {\n\n\t\tif( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === \"touch\" ) {\n\t\t\tevent.touches = [{ clientX: event.clientX, clientY: event.clientY }];\n\t\t\tthis.onTouchEnd( event );\n\t\t}\n\n\t}\n\n}","import { closest } from '../utils/util.js'\n\n/**\n * Manages focus when a presentation is embedded. This\n * helps us only capture keyboard from the presentation\n * a user is currently interacting with in a page where\n * multiple presentations are embedded.\n */\n\nconst STATE_FOCUS = 'focus';\nconst STATE_BLUR = 'blur';\n\nexport default class Focus {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.onRevealPointerDown = this.onRevealPointerDown.bind( this );\n\t\tthis.onDocumentPointerDown = this.onDocumentPointerDown.bind( this );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tif( config.embedded ) {\n\t\t\tthis.blur();\n\t\t}\n\t\telse {\n\t\t\tthis.focus();\n\t\t\tthis.unbind();\n\t\t}\n\n\t}\n\n\tbind() {\n\n\t\tif( this.Reveal.getConfig().embedded ) {\n\t\t\tthis.Reveal.getRevealElement().addEventListener( 'pointerdown', this.onRevealPointerDown, false );\n\t\t}\n\n\t}\n\n\tunbind() {\n\n\t\tthis.Reveal.getRevealElement().removeEventListener( 'pointerdown', this.onRevealPointerDown, false );\n\t\tdocument.removeEventListener( 'pointerdown', this.onDocumentPointerDown, false );\n\n\t}\n\n\tfocus() {\n\n\t\tif( this.state !== STATE_FOCUS ) {\n\t\t\tthis.Reveal.getRevealElement().classList.add( 'focused' );\n\t\t\tdocument.addEventListener( 'pointerdown', this.onDocumentPointerDown, false );\n\t\t}\n\n\t\tthis.state = STATE_FOCUS;\n\n\t}\n\n\tblur() {\n\n\t\tif( this.state !== STATE_BLUR ) {\n\t\t\tthis.Reveal.getRevealElement().classList.remove( 'focused' );\n\t\t\tdocument.removeEventListener( 'pointerdown', this.onDocumentPointerDown, false );\n\t\t}\n\n\t\tthis.state = STATE_BLUR;\n\n\t}\n\n\tisFocused() {\n\n\t\treturn this.state === STATE_FOCUS;\n\n\t}\n\n\tdestroy() {\n\n\t\tthis.Reveal.getRevealElement().classList.remove( 'focused' );\n\n\t}\n\n\tonRevealPointerDown( event ) {\n\n\t\tthis.focus();\n\n\t}\n\n\tonDocumentPointerDown( event ) {\n\n\t\tlet revealElement = closest( event.target, '.reveal' );\n\t\tif( !revealElement || revealElement !== this.Reveal.getRevealElement() ) {\n\t\t\tthis.blur();\n\t\t}\n\n\t}\n\n}","/**\n * Handles the showing and \n */\nexport default class Notes {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t}\n\n\trender() {\n\n\t\tthis.element = document.createElement( 'div' );\n\t\tthis.element.className = 'speaker-notes';\n\t\tthis.element.setAttribute( 'data-prevent-swipe', '' );\n\t\tthis.element.setAttribute( 'tabindex', '0' );\n\t\tthis.Reveal.getRevealElement().appendChild( this.element );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tif( config.showNotes ) {\n\t\t\tthis.element.setAttribute( 'data-layout', typeof config.showNotes === 'string' ? config.showNotes : 'inline' );\n\t\t}\n\n\t}\n\n\t/**\n\t * Pick up notes from the current slide and display them\n\t * to the viewer.\n\t *\n\t * @see {@link config.showNotes}\n\t */\n\tupdate() {\n\n\t\tif( this.Reveal.getConfig().showNotes && this.element && this.Reveal.getCurrentSlide() && !this.Reveal.print.isPrintingPDF() ) {\n\n\t\t\tthis.element.innerHTML = this.getSlideNotes() || 'No notes on this slide. ';\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Updates the visibility of the speaker notes sidebar that\n\t * is used to share annotated slides. The notes sidebar is\n\t * only visible if showNotes is true and there are notes on\n\t * one or more slides in the deck.\n\t */\n\tupdateVisibility() {\n\n\t\tif( this.Reveal.getConfig().showNotes && this.hasNotes() && !this.Reveal.print.isPrintingPDF() ) {\n\t\t\tthis.Reveal.getRevealElement().classList.add( 'show-notes' );\n\t\t}\n\t\telse {\n\t\t\tthis.Reveal.getRevealElement().classList.remove( 'show-notes' );\n\t\t}\n\n\t}\n\n\t/**\n\t * Checks if there are speaker notes for ANY slide in the\n\t * presentation.\n\t */\n\thasNotes() {\n\n\t\treturn this.Reveal.getSlidesElement().querySelectorAll( '[data-notes], aside.notes' ).length > 0;\n\n\t}\n\n\t/**\n\t * Checks if this presentation is running inside of the\n\t * speaker notes window.\n\t *\n\t * @return {boolean}\n\t */\n\tisSpeakerNotesWindow() {\n\n\t\treturn !!window.location.search.match( /receiver/gi );\n\n\t}\n\n\t/**\n\t * Retrieves the speaker notes from a slide. Notes can be\n\t * defined in two ways:\n\t * 1. As a data-notes attribute on the slide \n\t * 2. As an inside of the slide\n\t *\n\t * @param {HTMLElement} [slide=currentSlide]\n\t * @return {(string|null)}\n\t */\n\tgetSlideNotes( slide = this.Reveal.getCurrentSlide() ) {\n\n\t\t// Notes can be specified via the data-notes attribute...\n\t\tif( slide.hasAttribute( 'data-notes' ) ) {\n\t\t\treturn slide.getAttribute( 'data-notes' );\n\t\t}\n\n\t\t// ... or using an