├── .gitignore
├── Materials
├── Data
│ ├── car_data.RData
│ └── okc.RData
├── Extra_Slides.R
├── Extra_Slides.html
├── Extra_Slides.pdf
├── Extra_Slides_files
│ └── figure-html
│ │ ├── bivariate-plot-pca-1.svg
│ │ ├── bivariate-rec-orig-1.svg
│ │ ├── coef-plots-1-show-1.svg
│ │ └── coef-plots-2-show-1.svg
├── Part_1_Getting_Started.R
├── Part_1_Getting_Started.html
├── Part_1_Getting_Started.pdf
├── Part_1_Getting_Started_files
│ └── figure-html
│ │ ├── ggplot - example - disp-1.svg
│ │ └── ggplot-example-disp-1.svg
├── Part_2_Basic_Principals.R
├── Part_2_Basic_Principals.html
├── Part_2_Basic_Principals.pdf
├── Part_2_Basic_Principals_files
│ └── figure-html
│ │ ├── ames-knn-1.svg
│ │ ├── ames-knn-indiv-1.svg
│ │ ├── ames-split-dists-dist-1.svg
│ │ ├── boot-plot-1.svg
│ │ ├── cv-corr-1.svg
│ │ ├── cv-plot-1.svg
│ │ ├── two-class-2panel-1.svg
│ │ └── two-class-overfit-1.svg
├── Part_3_Feature_Engineering.R
├── Part_3_Feature_Engineering.html
├── Part_3_Feature_Engineering.pdf
├── Part_3_Feature_Engineering_files
│ └── figure-html
│ │ ├── ames-hood-1.svg
│ │ ├── bivariate-plot-inverse-1.svg
│ │ ├── bivariate-plot-natural-1.svg
│ │ ├── bivariate-plot-pca-1.svg
│ │ ├── bivariate-rec-orig-1.svg
│ │ ├── coef-plots-1-show-1.svg
│ │ ├── coef-plots-2-show-1.svg
│ │ ├── latitude-1.svg
│ │ ├── lm-obs-pred-show-1.svg
│ │ ├── longitude-1.svg
│ │ ├── scripts_uid8414f540ecdd4c4cbc8f6544838eea13.js
│ │ ├── scripts_uid88417f800ebd4b67adc5397e0356b276.js
│ │ ├── scripts_uid88e8e777f3714197936848c6636be3b1.js
│ │ ├── scripts_uida86b4bcdd21d43799fdb0f0e380e3861.js
│ │ ├── scripts_uidd3aa604fdfff44999bd703dd04674170.js
│ │ ├── scripts_uidd99cbc273a584e809be0ff8ad53817fa.js
│ │ ├── year-built-ac-plot-1.svg
│ │ └── year-built-plot-1.svg
├── Part_4_Regression_Modeling.R
├── Part_4_Regression_Modeling.html
├── Part_4_Regression_Modeling.pdf
├── Part_4_Regression_Modeling_files
│ └── figure-html
│ │ ├── ames-glmn-enhance-1.svg
│ │ ├── ames-glmn-imp-1.svg
│ │ ├── ames-glmn-op-1.svg
│ │ ├── ames-glmn-rmse-plot-1.svg
│ │ ├── ames-mars-imp-1.svg
│ │ ├── ames-mars-op-1.svg
│ │ ├── ames-mars-rmse-plot-1.svg
│ │ ├── bagged-op-1.svg
│ │ ├── bayes-1.png
│ │ ├── bayes-2.png
│ │ ├── bayes-contrast-1.png
│ │ ├── bayes-contrast-plot-1.svg
│ │ ├── car-bag-mars-op-1.svg
│ │ ├── car-glmn-imp-1.svg
│ │ ├── car-glmn-op-1.svg
│ │ ├── car-glmn-rmse-plot-1.svg
│ │ ├── car-mars-imp-1.svg
│ │ ├── car-mars-op-1.svg
│ │ ├── car-mars-rmse-plot-1.svg
│ │ ├── mars-2d-1.svg
│ │ ├── mars-bag-final-1.svg
│ │ ├── mars-cuts-1.svg
│ │ ├── mars-sim-1.png
│ │ ├── mars-sim-1.svg
│ │ ├── mars-sim-final-1.svg
│ │ ├── mars-sim-fit-1.svg
│ │ ├── par-plot-1.svg
│ │ ├── reg-path-1.svg
│ │ ├── test-op-1.svg
│ │ └── tp-post-plot-1.svg
├── Part_5_Classification.R
├── Part_5_Classification.html
├── Part_5_Classification.pdf
├── Part_5_Classification_files
│ └── figure-html
│ │ ├── bag-imp-1.svg
│ │ ├── bag-roc-plot-1.svg
│ │ ├── boost-plot-1.svg
│ │ ├── boot-cart-1-1.png
│ │ ├── boot-cart-1-1.svg
│ │ ├── boot-cart-2-1.png
│ │ ├── boot-cart-2-1.svg
│ │ ├── boot-cart-3-1.png
│ │ ├── boot-cart-3-1.svg
│ │ ├── calib-hist-1.svg
│ │ ├── calib-roc-1.svg
│ │ ├── cart-age-split-1.svg
│ │ ├── cart-imp-1.svg
│ │ ├── cart-orientation-split-1.svg
│ │ ├── cart-plot-1.png
│ │ ├── cart-plot-1.svg
│ │ ├── cart-roc-plot-1.svg
│ │ ├── cart-split-1-1.svg
│ │ ├── cart-split-2-1.svg
│ │ ├── nb-cat-1.svg
│ │ ├── nb-dens-1.svg
│ │ ├── nb-indep-1.svg
│ │ ├── nb-numeric-1.svg
│ │ ├── nb-plot-1.svg
│ │ ├── nb-roc-plot-1.svg
│ │ ├── nb-shrink-1.svg
│ │ ├── roc-plot-1.svg
│ │ ├── rs-contrast-plot-1.svg
│ │ ├── test-probs-1.svg
│ │ ├── test-roc-1.svg
│ │ ├── u-shape-1.svg
│ │ └── xgb-roc-plot-1.svg
├── RData
│ ├── cart_bag.RData
│ ├── cart_mod.RData
│ ├── glmn_mod.RData
│ ├── mars_gcv_bag.RData
│ ├── mars_gcv_mod.RData
│ ├── mars_mod.RData
│ └── nb_mod.RData
├── Template.Rmd
├── Template.html
├── Template_files
│ └── figure-html
│ │ ├── example-plot-1.svg
│ │ └── example-plot-again-1.svg
├── fonts_mtheme_max.css
├── images
│ ├── broom.png
│ ├── dplyr.png
│ ├── ggplot2.png
│ ├── intro-process-1.svg
│ ├── nope.png
│ ├── nopestradomis.jpg
│ ├── purrr.png
│ ├── readr.png
│ ├── recipes.png
│ ├── review-resamp-cache.png
│ ├── rsample.png
│ ├── tidyposterior.png
│ └── yardstick.png
├── libs
│ ├── DiagrammeR-styles-0.2
│ │ └── styles.css
│ ├── Proj4Leaflet-0.7.2
│ │ ├── proj4-compressed.js
│ │ ├── proj4.js
│ │ └── proj4leaflet.js
│ ├── d3-4.3.0
│ │ └── d3.min.js
│ ├── d3-lasso-0.0.5
│ │ ├── d3-lasso.min.js
│ │ └── lasso.js
│ ├── ggiraph-0.2.0
│ │ └── styles.css
│ ├── ggiraph-binding-0.4.1
│ │ └── ggiraph.js
│ ├── grViz-binding-0.9.0
│ │ └── grViz.js
│ ├── grViz-binding-0.9.2
│ │ └── grViz.js
│ ├── htmlwidgets-0.8
│ │ └── htmlwidgets.js
│ ├── htmlwidgets-0.9
│ │ └── htmlwidgets.js
│ ├── htmlwidgets-1.0
│ │ └── htmlwidgets.js
│ ├── jquery-1.12.4
│ │ ├── jquery.js
│ │ └── jquery.min.js
│ ├── leaflet-0.7.7
│ │ ├── images
│ │ │ ├── 1px.png
│ │ │ ├── layers-2x.png
│ │ │ ├── layers.png
│ │ │ ├── marker-icon-2x.png
│ │ │ ├── marker-icon.png
│ │ │ └── marker-shadow.png
│ │ ├── leaflet-src.js
│ │ ├── leaflet.css
│ │ └── leaflet.js
│ ├── leaflet-binding-1.1.0
│ │ └── leaflet.js
│ ├── leaflet-label-0.2.2
│ │ ├── images
│ │ │ └── death.png
│ │ ├── leaflet.label-src.js
│ │ ├── leaflet.label.css
│ │ └── leaflet.label.js
│ ├── leaflet-providers-1.0.27
│ │ ├── CONTRIBUTING.md
│ │ ├── README.md
│ │ ├── bower.json
│ │ ├── css
│ │ │ ├── gh-fork-ribbon.css
│ │ │ └── gh-fork-ribbon.ie.css
│ │ ├── leaflet-providers.js
│ │ ├── license.md
│ │ ├── package.json
│ │ └── providers.json
│ ├── leaflet-providers-plugin-1.1.0
│ │ └── leaflet-providers-plugin.js
│ ├── leafletfix-1.0.0
│ │ └── leafletfix.css
│ ├── remark-css-0.0.1
│ │ └── example.css
│ ├── uid8414f540ecdd4c4cbc8f6544838eea13-0.0.1
│ │ ├── ames-hood-1.svg
│ │ ├── bivariate-plot-inverse-1.svg
│ │ ├── bivariate-plot-natural-1.svg
│ │ ├── bivariate-plot-pca-1.svg
│ │ ├── bivariate-rec-orig-1.svg
│ │ ├── coef-plots-1-show-1.svg
│ │ ├── coef-plots-2-show-1.svg
│ │ ├── latitude-1.svg
│ │ ├── lm-obs-pred-show-1.svg
│ │ ├── longitude-1.svg
│ │ ├── scripts_uid8414f540ecdd4c4cbc8f6544838eea13.js
│ │ ├── scripts_uid88417f800ebd4b67adc5397e0356b276.js
│ │ ├── scripts_uid88e8e777f3714197936848c6636be3b1.js
│ │ ├── scripts_uida86b4bcdd21d43799fdb0f0e380e3861.js
│ │ ├── scripts_uidd3aa604fdfff44999bd703dd04674170.js
│ │ └── scripts_uidd99cbc273a584e809be0ff8ad53817fa.js
│ ├── uid88417f800ebd4b67adc5397e0356b276-0.0.1
│ │ ├── ames-hood-1.svg
│ │ ├── bivariate-plot-inverse-1.svg
│ │ ├── bivariate-plot-natural-1.svg
│ │ ├── bivariate-plot-pca-1.svg
│ │ ├── bivariate-rec-orig-1.svg
│ │ ├── coef-plots-1-show-1.svg
│ │ ├── coef-plots-2-show-1.svg
│ │ ├── latitude-1.svg
│ │ ├── lm-obs-pred-show-1.svg
│ │ ├── longitude-1.svg
│ │ ├── scripts_uid88417f800ebd4b67adc5397e0356b276.js
│ │ └── scripts_uidd3aa604fdfff44999bd703dd04674170.js
│ ├── uid88e8e777f3714197936848c6636be3b1-0.0.1
│ │ ├── ames-hood-1.svg
│ │ ├── bivariate-plot-inverse-1.svg
│ │ ├── bivariate-plot-natural-1.svg
│ │ ├── bivariate-plot-pca-1.svg
│ │ ├── bivariate-rec-orig-1.svg
│ │ ├── coef-plots-1-show-1.svg
│ │ ├── coef-plots-2-show-1.svg
│ │ ├── latitude-1.svg
│ │ ├── lm-obs-pred-show-1.svg
│ │ ├── longitude-1.svg
│ │ ├── scripts_uid88417f800ebd4b67adc5397e0356b276.js
│ │ ├── scripts_uid88e8e777f3714197936848c6636be3b1.js
│ │ └── scripts_uidd3aa604fdfff44999bd703dd04674170.js
│ ├── uida86b4bcdd21d43799fdb0f0e380e3861-0.0.1
│ │ ├── ames-hood-1.svg
│ │ ├── bivariate-plot-inverse-1.svg
│ │ ├── bivariate-plot-natural-1.svg
│ │ ├── bivariate-plot-pca-1.svg
│ │ ├── bivariate-rec-orig-1.svg
│ │ ├── coef-plots-1-show-1.svg
│ │ ├── coef-plots-2-show-1.svg
│ │ ├── latitude-1.svg
│ │ ├── lm-obs-pred-show-1.svg
│ │ ├── longitude-1.svg
│ │ ├── scripts_uid88417f800ebd4b67adc5397e0356b276.js
│ │ ├── scripts_uid88e8e777f3714197936848c6636be3b1.js
│ │ ├── scripts_uida86b4bcdd21d43799fdb0f0e380e3861.js
│ │ └── scripts_uidd3aa604fdfff44999bd703dd04674170.js
│ ├── uidd3aa604fdfff44999bd703dd04674170-0.0.1
│ │ ├── ames-hood-1.svg
│ │ ├── bivariate-plot-inverse-1.svg
│ │ ├── bivariate-plot-natural-1.svg
│ │ ├── bivariate-plot-pca-1.svg
│ │ ├── bivariate-rec-orig-1.svg
│ │ ├── coef-plots-1-show-1.svg
│ │ ├── coef-plots-2-show-1.svg
│ │ ├── latitude-1.svg
│ │ ├── lm-obs-pred-show-1.svg
│ │ ├── longitude-1.svg
│ │ └── scripts_uidd3aa604fdfff44999bd703dd04674170.js
│ ├── uidd99cbc273a584e809be0ff8ad53817fa-0.0.1
│ │ ├── ames-hood-1.svg
│ │ ├── bivariate-plot-inverse-1.svg
│ │ ├── bivariate-plot-natural-1.svg
│ │ ├── bivariate-plot-pca-1.svg
│ │ ├── bivariate-rec-orig-1.svg
│ │ ├── coef-plots-1-show-1.svg
│ │ ├── coef-plots-2-show-1.svg
│ │ ├── latitude-1.svg
│ │ ├── lm-obs-pred-show-1.svg
│ │ ├── longitude-1.svg
│ │ ├── scripts_uid88417f800ebd4b67adc5397e0356b276.js
│ │ ├── scripts_uid88e8e777f3714197936848c6636be3b1.js
│ │ ├── scripts_uida86b4bcdd21d43799fdb0f0e380e3861.js
│ │ ├── scripts_uidd3aa604fdfff44999bd703dd04674170.js
│ │ └── scripts_uidd99cbc273a584e809be0ff8ad53817fa.js
│ └── viz-0.3
│ │ └── viz.js
├── macros.js
└── mtheme_max.css
├── Preparations
└── installs.R
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .DS_Store
3 |
--------------------------------------------------------------------------------
/Materials/Data/car_data.RData:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Data/car_data.RData
--------------------------------------------------------------------------------
/Materials/Data/okc.RData:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Data/okc.RData
--------------------------------------------------------------------------------
/Materials/Extra_Slides.R:
--------------------------------------------------------------------------------
1 | ###################################################################
2 | ## Code for Applied Machine Learning by Max Kuhn @ RStudio::conf
3 | ## https://github.com/topepo/rstudio-conf-2018
4 |
5 | library(ggplot2)
6 |
7 | thm <- theme_bw() +
8 | theme(
9 | panel.background = element_rect(fill = "transparent", colour = NA),
10 | plot.background = element_rect(fill = "transparent", colour = NA),
11 | legend.position = "top",
12 | legend.background = element_rect(fill = "transparent", colour = NA),
13 | legend.key = element_rect(fill = "transparent", colour = NA)
14 | )
15 | theme_set(thm)
16 |
17 |
18 | # Create Data for PCA slides
19 | library(caret)
20 | data(segmentationData)
21 |
22 | segmentationData <- segmentationData[, c("EqSphereAreaCh1", "PerimCh1", "Class", "Case")]
23 | names(segmentationData)[1:2] <- paste0("Predictor", LETTERS[1:2])
24 |
25 | segmentationData$Class <- factor(ifelse(segmentationData$Class == "PS", "One", "Two"))
26 |
27 | bivariate_data_train <- subset(segmentationData, Case == "Train")
28 | bivariate_data_test <- subset(segmentationData, Case == "Test")
29 |
30 | bivariate_data_train$Case <- NULL
31 | bivariate_data_test$Case <- NULL
32 |
33 | # Slide 4
34 |
35 | library(recipes)
36 |
37 | bivariate_rec <- recipe(Class ~ PredictorA + PredictorB,
38 | data = bivariate_data_train) %>%
39 | step_BoxCox(all_predictors())
40 |
41 | bivariate_rec <- prep(bivariate_rec, training = bivariate_data_train, verbose = FALSE)
42 |
43 | inverse_test <- bake(bivariate_rec, newdata = bivariate_data_test, everything())
44 |
45 | # Slide 8
46 |
47 | ggplot(inverse_test,
48 | aes(x = 1/PredictorA,
49 | y = 1/PredictorB,
50 | color = Class)) +
51 | geom_point(alpha = .3, cex = 1.5) +
52 | theme(legend.position = "top") +
53 | xlab("1/A") + ylab("1/B")
54 |
55 | # Slide 9
56 |
57 | bivariate_pca <-
58 | recipe(Class ~ PredictorA + PredictorB, data = bivariate_data_train) %>%
59 | step_BoxCox(all_predictors()) %>%
60 | step_center(all_predictors()) %>%
61 | step_scale(all_predictors()) %>%
62 | step_pca(all_predictors()) %>%
63 | prep(training = bivariate_data_test, verbose = FALSE)
64 |
65 | pca_test <- bake(bivariate_pca, newdata = bivariate_data_test)
66 |
67 | # Put components axes on the same range
68 | pca_rng <- extendrange(c(pca_test$PC1, pca_test$PC2))
69 |
70 | ggplot(pca_test, aes(x = PC1, y = PC2, color = Class)) +
71 | geom_point(alpha = .2, cex = 1.5) +
72 | theme(legend.position = "top") +
73 | xlim(pca_rng) + ylim(pca_rng) +
74 | xlab("Principal Component 1") + ylab("Principal Component 2")
75 |
76 |
77 | # Data for Remaining Slides
78 |
79 | library(AmesHousing)
80 | ames <- make_ames()
81 | nrow(ames)
82 |
83 | library(rsample)
84 |
85 | # Make sure that you get the same random numbers
86 | set.seed(4595)
87 | data_split <- initial_split(ames, strata = "Sale_Price")
88 |
89 | ames_train <- training(data_split)
90 | ames_test <- testing(data_split)
91 |
92 | set.seed(2453)
93 | cv_splits <- vfold_cv(ames_train, v = 10, strata = "Sale_Price")
94 |
95 | lin_coords <- recipe(Sale_Price ~ Bldg_Type + Neighborhood + Year_Built +
96 | Gr_Liv_Area + Full_Bath + Year_Sold + Lot_Area +
97 | Central_Air + Longitude + Latitude,
98 | data = ames_train) %>%
99 | step_log(Sale_Price, base = 10) %>%
100 | step_YeoJohnson(Lot_Area, Gr_Liv_Area) %>%
101 | step_other(Neighborhood, threshold = 0.05) %>%
102 | step_dummy(all_nominal()) %>%
103 | step_interact(~ starts_with("Central_Air"):Year_Built)
104 |
105 | coords <- lin_coords %>%
106 | step_bs(Longitude, Latitude, options = list(df = 5))
107 |
108 | library(purrr)
109 | cv_splits <- cv_splits %>%
110 | mutate(coords = map(splits, prepper, recipe = coords, retain = TRUE))
111 |
112 | lm_fit_rec <- function(rec_obj, ...)
113 | lm(..., data = juice(rec_obj))
114 |
115 | cv_splits <- cv_splits %>%
116 | mutate(fits = map(coords, lm_fit_rec, Sale_Price ~ .))
117 |
118 | # Slide 12
119 |
120 | coef_summary <- map(cv_splits$fits, tidy) %>% bind_rows
121 | head(coef_summary)
122 |
123 | # Slide 13
124 |
125 | num_pred <- c("Year_Built", "Gr_Liv_Area",
126 | "Full_Bath", "Year_Sold",
127 | "Lot_Area")
128 | z_lim <- qnorm(c(0.025, 0.975))
129 | coef_summary %>%
130 | filter(term %in% num_pred) %>%
131 | ggplot(aes(x = term, y = statistic)) +
132 | geom_hline(yintercept = z_lim,
133 | lty = 2, col = "red") +
134 | geom_jitter(width = .1, alpha = .4, cex = 2) +
135 | coord_flip() +
136 | xlab("")
137 |
138 | # Slide 14
139 |
140 | coef_summary %>%
141 | filter(grepl("^Neighborhood", term)) %>%
142 | ggplot(aes(x = term, y = statistic)) +
143 | geom_hline(
144 | yintercept = z_lim,
145 | lty = 2,
146 | col = "red"
147 | ) +
148 | geom_jitter(
149 | width = .1,
150 | alpha = .4,
151 | cex = 2
152 | ) +
153 | coord_flip() +
154 | xlab("") +
155 | ylab(
156 | paste("Difference from",
157 | levels(ames_test$Neighborhood)[1])
158 | )
159 |
160 | # Slide 17
161 |
162 | library(yardstick)
163 | data(solubility_test)
164 | str(solubility_test, nchar.max = 70)
165 |
166 | # Slide 18
167 |
168 | rmse(solubility_test, truth = solubility, estimate = prediction)
169 |
170 | # Slide 19
171 |
172 | rsq(solubility_test, truth = solubility, estimate = prediction)
173 |
174 | # Slide 20
175 |
176 | library(dplyr)
177 | set.seed(3545)
178 | solubility_test <- solubility_test %>% mutate(noise = sample(prediction))
179 |
180 | rsq(solubility_test, truth = solubility, estimate = noise)
181 | rsq_trad(solubility_test, truth = solubility, estimate = noise)
182 |
183 |
--------------------------------------------------------------------------------
/Materials/Extra_Slides.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Applied Machine Learning - Extra Slides
5 |
6 |
7 |
8 |
9 |
10 |
11 |
431 |
432 |
439 |
440 |
447 |
448 |
458 |
459 |
460 |
--------------------------------------------------------------------------------
/Materials/Extra_Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Extra_Slides.pdf
--------------------------------------------------------------------------------
/Materials/Part_1_Getting_Started.R:
--------------------------------------------------------------------------------
1 | ###################################################################
2 | ## Code for Applied Machine Learning by Max Kuhn @ RStudio::conf
3 | ## https://github.com/topepo/rstudio-conf-2018
4 |
5 |
6 | library(ggplot2)
7 |
8 | thm <- theme_bw() +
9 | theme(
10 | panel.background = element_rect(fill = "transparent", colour = NA),
11 | plot.background = element_rect(fill = "transparent", colour = NA),
12 | legend.position = "top",
13 | legend.background = element_rect(fill = "transparent", colour = NA),
14 | legend.key = element_rect(fill = "transparent", colour = NA)
15 | )
16 | theme_set(thm)
17 |
18 | # Slide 12
19 |
20 | library(tidyverse)
21 |
22 | ames <-
23 | read_delim("http://bit.ly/2whgsQM", delim = "\t") %>%
24 | rename_at(vars(contains(' ')), funs(gsub(' ', '_', .))) %>%
25 | rename(Sale_Price = SalePrice) %>%
26 | filter(!is.na(Electrical)) %>%
27 | select(-Order, -PID, -Garage_Yr_Blt)
28 |
29 | ames %>%
30 | group_by(Alley) %>%
31 | summarize(mean_price = mean(Sale_Price/1000),
32 | n = sum(!is.na(Sale_Price)))
33 |
34 | # Slide 13
35 |
36 | ggplot(ames,
37 | aes(x = Garage_Type,
38 | y = Sale_Price)) +
39 | geom_violin() +
40 | coord_trans(y = "log10") +
41 | xlab("Garage Type") +
42 | ylab("Sale Price")
43 |
44 |
45 |
46 | # Slide 14
47 |
48 | library(purrr)
49 |
50 | # summarize via purrr::map
51 | by_alley <- split(ames, ames$Alley)
52 | is_list(by_alley)
53 |
54 | map(by_alley, nrow)
55 |
56 | # or better yet:
57 | map_int(by_alley, nrow)
58 |
59 |
60 | # works on non-list vectors too
61 | ames %>%
62 | mutate(Sale_Price = Sale_Price %>%
63 | map_dbl(function(x) x / 1000)) %>%
64 | select(Sale_Price, Yr_Sold) %>%
65 | head(4)
66 |
67 | # Slide 15
68 |
69 | library(AmesHousing)
70 | ames <- make_ames()
71 |
72 |
--------------------------------------------------------------------------------
/Materials/Part_1_Getting_Started.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_1_Getting_Started.pdf
--------------------------------------------------------------------------------
/Materials/Part_2_Basic_Principals.R:
--------------------------------------------------------------------------------
1 | ###################################################################
2 | ## Code for Applied Machine Learning by Max Kuhn @ RStudio::conf
3 | ## https://github.com/topepo/rstudio-conf-2018
4 |
5 | library(ggplot2)
6 |
7 | thm <- theme_bw() +
8 | theme(
9 | panel.background = element_rect(fill = "transparent", colour = NA),
10 | plot.background = element_rect(fill = "transparent", colour = NA),
11 | legend.position = "top",
12 | legend.background = element_rect(fill = "transparent", colour = NA),
13 | legend.key = element_rect(fill = "transparent", colour = NA)
14 | )
15 | theme_set(thm)
16 |
17 | # Slide 10
18 |
19 | library(AmesHousing)
20 | ames <- make_ames()
21 | nrow(ames)
22 |
23 | library(rsample)
24 |
25 | # Make sure that you get the same random numbers
26 | set.seed(4595)
27 | data_split <- initial_split(ames, strata = "Sale_Price")
28 |
29 | ames_train <- training(data_split)
30 | ames_test <- testing(data_split)
31 |
32 | nrow(ames_train)/nrow(ames)
33 |
34 | # Slide 11
35 |
36 | ggplot(ames_train, aes(x = Sale_Price)) +
37 | geom_line(stat = "density", trim = TRUE) +
38 | geom_line(data = ames_test,
39 | stat = "density",
40 | trim = TRUE, col = "red")
41 |
42 | # Slide 15
43 |
44 | simple_lm <- lm(log10(Sale_Price) ~ Longitude + Latitude, data = ames_train)
45 |
46 | library(broom)
47 | simple_lm_values <- augment(simple_lm)
48 | names(simple_lm_values)
49 |
50 | # Slide 19
51 |
52 | summary(simple_lm)
53 |
54 | # Slide 28
55 |
56 | library(rsample)
57 | set.seed(2453)
58 | cv_splits <- vfold_cv(ames_train, v = 10, strata = "Sale_Price")
59 | cv_splits
60 |
61 | # Slide 29
62 |
63 | # The `split` objects contain the information about the sample sizes
64 | cv_splits$splits[[1]]
65 |
66 | # Use the `analysis` and `assessment` functions to get the data
67 | analysis(cv_splits$splits[[1]]) %>% dim()
68 | assessment(cv_splits$splits[[1]]) %>% dim()
69 |
70 | # Slide 30
71 |
72 | library(yardstick)
73 | library(dplyr)
74 |
75 | lm_fit <- function(data_split, ...)
76 | lm(..., data = analysis(data_split))
77 |
78 | # A formula is also needed for each model:
79 | form <- as.formula(
80 | log10(Sale_Price) ~ Longitude + Latitude
81 | )
82 |
83 | model_perf <- function(data_split, mod_obj) {
84 | vars <- rsample::form_pred(mod_obj$terms)
85 | assess_dat <- assessment(data_split) %>%
86 | select(!!!vars, Sale_Price) %>%
87 | mutate(
88 | pred = predict(
89 | mod_obj,
90 | newdata = assessment(data_split)
91 | ),
92 | Sale_Price = log10(Sale_Price)
93 | )
94 |
95 | rmse <- assess_dat %>%
96 | rmse(truth = Sale_Price, estimate = pred)
97 | rsq <- assess_dat %>%
98 | rsq(truth = Sale_Price, estimate = pred)
99 | data.frame(rmse = rmse, rsq = rsq)
100 | }
101 |
102 | # Slide 31
103 |
104 | library(purrr)
105 | cv_splits <- cv_splits %>%
106 | mutate(lm_mod = map(splits, lm_fit, formula = form))
107 | cv_splits
108 |
109 | # Slide 32
110 |
111 | # map2 can be used to move over two objects of equal length
112 | lm_res <- map2_df(cv_splits$splits, cv_splits$lm_mod, model_perf) %>%
113 | dplyr::rename(rmse_simple = rmse, rsq_simple = rsq)
114 | head(lm_res, 3)
115 |
116 | ## Merge in results:
117 | cv_splits <- cv_splits %>% bind_cols(lm_res)
118 |
119 | ## Rename the columns and compute the resampling estimates:
120 | cv_splits %>% select(rmse_simple, rsq_simple) %>% colMeans
121 |
122 | # Slide 34
123 |
124 | get_assessment <- function(splits, model)
125 | augment(model, newdata = assessment(splits)) %>%
126 | mutate(.resid = log10(Sale_Price) - .fitted)
127 |
128 | holdout_results <- map2_df(cv_splits$splits, cv_splits$lm_mod, get_assessment)
129 | holdout_results %>% dim()
130 | ames_train %>% dim()
131 |
132 | # Slide 39
133 |
134 | library(caret)
135 |
136 | knn_train_mod <- knnreg(log10(Sale_Price) ~ Longitude + Latitude,
137 | data = ames_train,
138 | k = 2)
139 | repredict <- data.frame(price = log10(ames_train$Sale_Price)) %>%
140 | mutate(pred =
141 | predict(knn_train_mod,
142 | newdata = ames_train %>% select(Longitude, Latitude)
143 | )
144 | )
145 |
146 | repredict %>% rsq(truth = "price", estimate = "pred") # <- the ruckus is here
147 |
148 | # Slide 40
149 |
150 | knn_fit <- function(data_split, ...)
151 | knnreg(..., data = analysis(data_split))
152 |
153 | cv_splits <- cv_splits %>%
154 | mutate(knn_mod = map(splits, knn_fit, formula = form, k = 2))
155 |
156 | knn_res <- map2_df(cv_splits$splits, cv_splits$knn_mod, model_perf) %>%
157 | rename(rmse_knn = rmse, rsq_knn = rsq)
158 |
159 | ## Merge in results:
160 | cv_splits <- cv_splits %>% bind_cols(knn_res)
161 |
162 | colMeans(knn_res)
163 |
164 | # Slide 42
165 |
166 | rs_comp <- data.frame(
167 | rmse = c(cv_splits$rmse_simple, cv_splits$rmse_knn),
168 | Model = rep(c("Linear\nRegression", "2-NN"), each = nrow(cv_splits)),
169 | Resample = cv_splits$id
170 | )
171 |
172 | ggplot(rs_comp, aes(x = Model, y = rmse, group = Resample, col = Resample)) +
173 | geom_point() +
174 | geom_line() +
175 | theme(legend.position = "none")
176 |
177 | # Slide 43
178 |
179 | t.test(cv_splits$rmse_simple, cv_splits$rmse_knn, paired = TRUE)
180 |
181 | # Slide 49
182 |
183 | knn_rmse <- function(k, split) {
184 | mod <- knnreg(log10(Sale_Price) ~ Longitude + Latitude,
185 | data = analysis(split),
186 | k = k)
187 | # Extract the names of the predictors
188 | preds <- form_pred(mod$terms)
189 | data.frame(Sale_Price = log10(assessment(split)$Sale_Price)) %>%
190 | mutate(pred = predict(mod, assessment(split) %>% select(!!!preds))) %>%
191 | rmse(Sale_Price, pred)
192 | }
193 |
194 | # Slide 50
195 | library(dplyr)
196 |
197 | knn_grid <- function(split) {
198 | # Create grid
199 | tibble(k = 1:20) %>%
200 | # Execute grid for this resample
201 | mutate(
202 | rmse = map_dbl(k, knn_rmse, split = split),
203 | # Attach the resample indicators using `lables`
204 | id = labels(split)[[1]]
205 | )
206 | }
207 |
208 | # Slide 51
209 |
210 | iter_over_resamples <-
211 | function(resamp)
212 | map_df(resamp$splits, knn_grid)
213 |
214 | # Slide 52
215 |
216 | knn_tune_res <- iter_over_resamples(cv_splits)
217 | knn_tune_res %>% head(15)
218 |
219 | # Slide 53
220 |
221 | rmse_by_k <- knn_tune_res %>%
222 | group_by(k) %>%
223 | summarize(rmse = mean(rmse))
224 |
225 | ggplot(rmse_by_k, aes(x = k, y = rmse)) +
226 | geom_point() + geom_line()
227 |
228 | # Slide 54
229 |
230 | best_k <- knn_tune_res %>%
231 | group_by(id) %>%
232 | summarize(k = k[which.min(rmse)],
233 | rmse = rmse[which.min(rmse)])
234 |
235 | ggplot(rmse_by_k, aes(x = k, y = rmse)) +
236 | geom_point() + geom_line() +
237 | geom_line(data = knn_tune_res,
238 | aes(group = id,
239 | col = id),
240 | alpha = .2, lwd = 1) +
241 | geom_point(data = best_k, aes(col = id),
242 | alpha = .5, cex = 2)+
243 | theme(legend.position = "none")
244 |
245 | # Slide 55
246 |
247 | final_knn <- knnreg(log10(Sale_Price) ~ Longitude + Latitude,
248 | data = ames_train,
249 | k = 4)
250 |
251 |
--------------------------------------------------------------------------------
/Materials/Part_2_Basic_Principals.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_2_Basic_Principals.pdf
--------------------------------------------------------------------------------
/Materials/Part_3_Feature_Engineering.R:
--------------------------------------------------------------------------------
1 | ###################################################################
2 | ## Code for Applied Machine Learning by Max Kuhn @ RStudio::conf
3 | ## https://github.com/topepo/rstudio-conf-2018
4 |
5 | library(ggplot2)
6 |
7 | thm <- theme_bw() +
8 | theme(
9 | panel.background = element_rect(fill = "transparent", colour = NA),
10 | plot.background = element_rect(fill = "transparent", colour = NA),
11 | legend.position = "top",
12 | legend.background = element_rect(fill = "transparent", colour = NA),
13 | legend.key = element_rect(fill = "transparent", colour = NA)
14 | )
15 | theme_set(thm)
16 |
17 |
18 | # Bivariate Data used in examples
19 |
20 | library(caret)
21 | data(segmentationData)
22 |
23 | segmentationData <- segmentationData[, c("EqSphereAreaCh1", "PerimCh1", "Class", "Case")]
24 | names(segmentationData)[1:2] <- paste0("Predictor", LETTERS[1:2])
25 |
26 | segmentationData$Class <- factor(ifelse(segmentationData$Class == "PS", "One", "Two"))
27 |
28 | bivariate_data_train <- subset(segmentationData, Case == "Train")
29 | bivariate_data_test <- subset(segmentationData, Case == "Test")
30 |
31 | bivariate_data_train$Case <- NULL
32 | bivariate_data_test$Case <- NULL
33 |
34 | # Slide 4
35 |
36 | ggplot(bivariate_data_test,
37 | aes(x = PredictorA,
38 | y = PredictorB,
39 | color = Class)) +
40 | geom_point(alpha = .3, cex = 1.5) +
41 | theme(legend.position = "top")
42 |
43 | # Slide 5
44 |
45 | library(dplyr)
46 | library(recipes)
47 |
48 | bivariate_rec <- recipe(Class ~ PredictorA + PredictorB,
49 | data = bivariate_data_train) %>%
50 | step_BoxCox(all_predictors())
51 |
52 | bivariate_rec <- prep(bivariate_rec, training = bivariate_data_train, verbose = FALSE)
53 |
54 | inverse_test <- bake(bivariate_rec, newdata = bivariate_data_test, everything())
55 |
56 | ggplot(inverse_test,
57 | aes(x = 1/PredictorA,
58 | y = 1/PredictorB,
59 | color = Class)) +
60 | geom_point(alpha = .3, cex = 1.5) +
61 | theme(legend.position = "top") +
62 | xlab("1/A") + ylab("1/B")
63 |
64 | # Recreate the Ames Data
65 |
66 | library(AmesHousing)
67 | ames <- make_ames()
68 | nrow(ames)
69 |
70 | library(rsample)
71 |
72 | # Make sure that you get the same random numbers
73 | set.seed(4595)
74 | data_split <- initial_split(ames, strata = "Sale_Price")
75 |
76 | ames_train <- training(data_split)
77 | ames_test <- testing(data_split)
78 |
79 | alleys <- data.frame(Alley = levels(ames_train$Alley))
80 | alley_dummies <- model.matrix(~ Alley, data = alleys)[, -1]
81 | alley_dummies <- as.data.frame(alley_dummies)
82 | rownames(alley_dummies) <- levels(ames_train$Alley)
83 | colnames(alley_dummies) <- gsub("^Alley", "", colnames(alley_dummies))
84 |
85 |
86 | # Slide 10
87 |
88 | ggplot(ames_train, aes(x = Neighborhood)) + geom_bar() + coord_flip() + xlab("")
89 |
90 | # Slide 12
91 |
92 | library(recipes)
93 | mod_rec <- recipe(Sale_Price ~ Longitude + Latitude, data = ames_train) %>%
94 | step_log(Sale_Price, base = 10)
95 |
96 | # Slide 13
97 |
98 | mod_rec <- recipe(Sale_Price ~ Longitude + Latitude + Neighborhood, data = ames_train) %>%
99 | step_log(Sale_Price, base = 10) %>%
100 |
101 | # Lump factor levels that occur in <= 5% of data as "other"
102 | step_other(Neighborhood, threshold = 0.05) %>%
103 |
104 | # Create dummy variables for _any_ factor variables
105 | step_dummy(all_nominal())
106 |
107 | # Slide 14
108 |
109 | mod_rec_trained <- prep(mod_rec, training = ames_train, retain = TRUE, verbose = TRUE)
110 |
111 | # Slide 15
112 |
113 | mod_rec_trained
114 |
115 | # Slide 16
116 |
117 | ames_test_dummies <- bake(mod_rec_trained,newdata = ames_test)
118 | names(ames_test_dummies)
119 |
120 | # Slide 19
121 |
122 | price_breaks <- (1:6)*(10^5)
123 |
124 | ggplot(ames_train, aes(x = Year_Built, y = Sale_Price)) +
125 | geom_point(alpha = 0.4) +
126 | scale_x_log10() +
127 | scale_y_continuous(breaks = price_breaks, trans = "log10" ) +
128 | geom_smooth(method = "loess")
129 |
130 | # Slide 20
131 |
132 | library(MASS) # to get robust linear regression model
133 |
134 | ggplot(ames_train,
135 | aes(x = Year_Built,
136 | y = Sale_Price)) +
137 | geom_point(alpha = 0.4) +
138 | scale_y_continuous(breaks = price_breaks,
139 | trans = "log10") +
140 | facet_wrap(~ Central_Air, nrow = 2) +
141 | geom_smooth(method = "rlm")
142 |
143 | # Slide 21
144 |
145 | mod1 <- lm(log10(Sale_Price) ~ Year_Built + Central_Air, data = ames_train)
146 | mod2 <- lm(log10(Sale_Price) ~ Year_Built + Central_Air + Year_Built: Central_Air, data = ames_train)
147 | anova(mod1, mod2)
148 |
149 | # Slide 33
150 |
151 | recipe(Sale_Price ~ Year_Built + Central_Air, data = ames_train) %>%
152 | step_log(Sale_Price) %>%
153 | step_dummy(Central_Air) %>%
154 | step_interact(~ starts_with("Central_Air"):Year_Built) %>%
155 | prep(training = ames_train, retain = TRUE) %>%
156 | juice %>%
157 | # select a few rows with different values
158 | slice(153:157)
159 |
160 | # Slide 24
161 |
162 | library(AmesHousing)
163 | ames <- make_ames()
164 |
165 | library(rsample)
166 | set.seed(4595)
167 | data_split <- initial_split(ames, strata = "Sale_Price")
168 | ames_train <- training(data_split)
169 |
170 | set.seed(2453)
171 | cv_splits <- vfold_cv(ames_train, v = 10, strata = "Sale_Price")
172 |
173 | # Slide 25
174 |
175 | lin_coords <- recipe(Sale_Price ~ Bldg_Type + Neighborhood + Year_Built +
176 | Gr_Liv_Area + Full_Bath + Year_Sold + Lot_Area +
177 | Central_Air + Longitude + Latitude,
178 | data = ames_train) %>%
179 | step_log(Sale_Price, base = 10) %>%
180 | step_YeoJohnson(Lot_Area, Gr_Liv_Area) %>%
181 | step_other(Neighborhood, threshold = 0.05) %>%
182 | step_dummy(all_nominal()) %>%
183 | step_interact(~ starts_with("Central_Air"):Year_Built)
184 |
185 | coords <- lin_coords %>%
186 | step_bs(Longitude, Latitude, options = list(df = 5))
187 |
188 | # Slide 26
189 |
190 | ggplot(ames_train,
191 | aes(x = Longitude, y = Sale_Price)) +
192 | geom_point(alpha = .5) +
193 | geom_smooth(
194 | method = "lm",
195 | formula = y ~ splines::bs(x, 5)
196 | ) +
197 | scale_y_log10()
198 |
199 | # Slide 27
200 |
201 | ggplot(ames_train,
202 | aes(x = Latitude, y = Sale_Price)) +
203 | geom_point(alpha = .5) +
204 | geom_smooth(
205 | method = "lm",
206 | formula = y ~ splines::bs(x, 5)
207 | ) +
208 | scale_y_log10()
209 |
210 | # Slide 28
211 |
212 | prepper
213 | library(purrr)
214 | cv_splits <- cv_splits %>%
215 | mutate(coords = map(splits, prepper, recipe = coords, retain = TRUE))
216 |
217 | # Slide 29
218 |
219 | lm_fit_rec <- function(rec_obj, ...)
220 | lm(..., data = juice(rec_obj))
221 |
222 | cv_splits <- cv_splits %>%
223 | mutate(fits = map(coords, lm_fit_rec, Sale_Price ~ .))
224 | glance(cv_splits$fits[[1]])
225 |
226 | # Slide 30
227 |
228 | assess_predictions <- function(split_obj, rec_obj, mod_obj) {
229 | raw_data <- assessment(split_obj)
230 | proc_x <- bake(rec_obj, newdata = raw_data, all_predictors())
231 | # Now save _all_ of the columns and add predictions.
232 | bake(rec_obj, newdata = raw_data, everything()) %>%
233 | mutate(
234 | .fitted = predict(mod_obj, newdata = proc_x),
235 | .resid = Sale_Price - .fitted, # Sale_Price is already logged by the recipe
236 | # Save the original row number of the data
237 | .row = as.integer(split_obj, data = "assessment")
238 | )
239 | }
240 |
241 | # Slide 31
242 |
243 | cv_splits <- cv_splits %>%
244 | mutate(
245 | pred =
246 | pmap(
247 | lst(split_obj = cv_splits$splits, rec_obj = cv_splits$coords, mod_obj = cv_splits$fits),
248 | assess_predictions
249 | )
250 | )
251 |
252 | # Slide 32
253 |
254 | library(yardstick)
255 |
256 | # Compute the summary statistics
257 | map_df(cv_splits$pred, metrics, truth = Sale_Price, estimate = .fitted) %>%
258 | colMeans
259 |
260 | # Slide 33
261 |
262 | assess_pred <- bind_rows(cv_splits$pred) %>%
263 | mutate(Sale_Price = 10^Sale_Price,
264 | .fitted = 10^.fitted)
265 |
266 | ggplot(assess_pred,
267 | aes(x = Sale_Price, y = .fitted)) +
268 | geom_abline(lty = 2) +
269 | geom_point(alpha = .4) +
270 | geom_smooth(se = FALSE, col = "red")
271 |
--------------------------------------------------------------------------------
/Materials/Part_3_Feature_Engineering.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_3_Feature_Engineering.pdf
--------------------------------------------------------------------------------
/Materials/Part_4_Regression_Modeling.R:
--------------------------------------------------------------------------------
1 | ###################################################################
2 | ## Code for Applied Machine Learning by Max Kuhn @ RStudio::conf
3 | ## https://github.com/topepo/rstudio-conf-2018
4 |
5 | library(ggplot2)
6 |
7 | thm <- theme_bw() +
8 | theme(
9 | panel.background = element_rect(fill = "transparent", colour = NA),
10 | plot.background = element_rect(fill = "transparent", colour = NA),
11 | legend.position = "top",
12 | legend.background = element_rect(fill = "transparent", colour = NA),
13 | legend.key = element_rect(fill = "transparent", colour = NA)
14 | )
15 | theme_set(thm)
16 |
17 | # Slide 4
18 |
19 | load("Data/car_data.RData")
20 | library(dplyr)
21 | car_train <- car_data %>%
22 | filter(model_year < 2018)
23 |
24 | car_test <- car_data %>%
25 | filter(model_year == 2018)
26 |
27 | # Slide 8
28 |
29 | ## lm(mpg ~ . -carline + poly(eng_displ, 2), data = car_train)
30 |
31 | # Slide 9
32 |
33 | car_train %>%
34 | group_by(division) %>%
35 | count() %>%
36 | arrange(n) %>%
37 | head(8)
38 |
39 | # Slide 10
40 |
41 | library(recipes)
42 | basic_rec <- recipe(mpg ~ ., data = car_train) %>%
43 | # keep the car name but don't use as a predictor
44 | add_role(carline, new_role = "car name") %>%
45 | # collapse some divisions into "other"
46 | step_other(division, threshold = 0.005) %>%
47 | step_dummy(all_nominal(), -carline) %>%
48 | step_zv(all_predictors())
49 |
50 | # Slide 14
51 |
52 | glmn_grid <- expand.grid(alpha = seq(0, 1, by = .25), lambda = 10^seq(-3, -1, length = 20))
53 | nrow(glmn_grid)
54 |
55 | # Slide 17
56 |
57 | library(caret)
58 | ctrl <- trainControl(
59 | method = "cv",
60 | # Save the assessment predictions from the best model
61 | savePredictions = "final",
62 | # Log the progress of the tuning process
63 | verboseIter = TRUE
64 | )
65 |
66 | # Slide 18
67 |
68 | glmn_rec <- basic_rec %>%
69 | step_poly(eng_displ) %>%
70 | step_center(all_predictors()) %>%
71 | step_scale(all_predictors())
72 |
73 | set.seed(3544)
74 | glmn_mod <- train(
75 | glmn_rec,
76 | data = car_train,
77 | method = "glmnet",
78 | trControl = ctrl,
79 | tuneGrid = glmn_grid
80 | )
81 |
82 | # Slide 20
83 |
84 | ggplot(glmn_mod) + scale_x_log10() + theme(legend.position = "top")
85 |
86 | # Slide 21
87 |
88 | glmn_mod$pred %>% head(4)
89 |
90 | ggplot(glmn_mod$pred, aes(x = obs, y = pred)) +
91 | geom_abline(col = "green", alpha = .5) +
92 | geom_smooth(se = FALSE, col = "red", lty = 2, lwd = 1, alpha = .5) +
93 | geom_point(alpha = .3)
94 |
95 | # Slide 22
96 |
97 | reg_imp <- varImp(glmn_mod, scale = FALSE)
98 | ggplot(reg_imp, top = 30) + xlab("")
99 |
100 | # Slide 24
101 |
102 | library(glmnet)
103 | plot(glmn_mod$finalModel, xvar = "lambda")
104 |
105 | # If you would like to run in parallel
106 |
107 | library(doParallel)
108 | cl <- makeCluster(parallel::detectCores(logical = FALSE))
109 | registerDoParallel(cl)
110 |
111 | # Slide 37
112 |
113 | ctrl$verboseIter <- FALSE
114 |
115 | mars_grid <- expand.grid(degree = 1:2, nprune = seq(2, 60, by = 2))
116 |
117 | # Using the same seed to obtain the same
118 | # resamples as the glmnet model.
119 | set.seed(3544)
120 | mars_mod <- train(
121 | basic_rec,
122 | data = car_train,
123 | method = "earth",
124 | tuneGrid = mars_grid,
125 | trControl = ctrl
126 | )
127 |
128 | # Slide 40
129 |
130 | ggplot(mars_mod) + theme(legend.position = "top")
131 |
132 | # Slide 41
133 |
134 | ggplot(mars_mod$pred, aes(x = obs, y = pred)) +
135 | geom_abline(col = "green", alpha = .5) +
136 | geom_smooth(se = FALSE, col = "red",
137 | lty = 2, lwd = 1, alpha = .5) +
138 | geom_point(alpha = .3)
139 |
140 | # Slide 42
141 |
142 | library(earth)
143 | mars_mod$finalModel
144 |
145 | # Slide 43
146 |
147 | mars_imp <- varImp(mars_mod)
148 | ggplot(mars_imp, top = 30) + xlab("")
149 |
150 | # Slide 44
151 |
152 | set.seed(3544)
153 | mars_gcv_mod <- train(
154 | basic_rec,
155 | data = car_train,
156 | method = "gcvEarth",
157 | tuneGrid = data.frame(degree = 1:2),
158 | trControl = ctrl
159 | )
160 | mars_gcv_mod$finalModel
161 |
162 | # Slide 49
163 |
164 | set.seed(3544)
165 | mars_gcv_bag <- train(
166 | basic_rec,
167 | data = car_train,
168 | method = "bagEarthGCV",
169 | tuneGrid = data.frame(degree = 1:2),
170 | trControl = ctrl,
171 | # Number of bootstraps for `bagEarth` function
172 | B = 50
173 | )
174 |
175 | # Slide 50
176 |
177 | mars_gcv_bag
178 |
179 | # Slide 51
180 |
181 | ggplot(mars_gcv_bag$pred, aes(x = obs, y = pred)) +
182 | geom_abline(col = "green", alpha = .5) +
183 | geom_smooth(se = FALSE, col = "red",
184 | lty = 2, lwd = 1, alpha = .5) +
185 | geom_point(alpha = .3)
186 |
187 | # Slide 52
188 |
189 | car_train %>%
190 | arrange(mpg) %>%
191 | select(mpg, carline, model_year) %>%
192 | tail(10)
193 |
194 | # Slide 54
195 |
196 | rs <- resamples(
197 | list(glmn = glmn_mod, MARS = mars_mod, bagged = mars_gcv_bag)
198 | )
199 |
200 | # Slide 57
201 |
202 | library(tidyposterior)
203 | rmse_mod <- perf_mod(rs, seed = 4344, iter = 5000, metric = "RMSE")
204 |
205 | # Slide 58
206 |
207 | posteriors <- tidy(rmse_mod, seed = 366784)
208 | summary(posteriors)
209 |
210 | ggplot(posteriors)
211 |
212 | # Slide 59
213 |
214 | differences <-
215 | contrast_models(
216 | rmse_mod,
217 | list_1 = rep("bagged", 2),
218 | list_2 = c("glmn", "MARS"),
219 | seed = 2581
220 | )
221 |
222 | ggplot(differences, size = 0.25)
223 |
224 | # Slide 60
225 |
226 | summary(differences, size = 0.25)
227 |
228 | # Slide 62
229 |
230 | car_test <- car_test %>%
231 | mutate(pred = predict(mars_gcv_bag, car_test))
232 |
233 | library(yardstick)
234 | rmse(car_test, truth = mpg, estimate = pred)
235 |
236 | ggplot(car_test, aes(x = mpg, y = pred)) +
237 | geom_abline(col = "green", alpha = .5) +
238 | geom_smooth(se = FALSE, col = "red",
239 | lty = 2, lwd = 1, alpha = .5) +
240 | geom_point(alpha = .3)
241 |
242 | # Stop the cluster if you used it
243 |
244 | stopCluster(cl)
245 |
246 |
--------------------------------------------------------------------------------
/Materials/Part_4_Regression_Modeling.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_4_Regression_Modeling.pdf
--------------------------------------------------------------------------------
/Materials/Part_4_Regression_Modeling_files/figure-html/bayes-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_4_Regression_Modeling_files/figure-html/bayes-1.png
--------------------------------------------------------------------------------
/Materials/Part_4_Regression_Modeling_files/figure-html/bayes-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_4_Regression_Modeling_files/figure-html/bayes-2.png
--------------------------------------------------------------------------------
/Materials/Part_4_Regression_Modeling_files/figure-html/bayes-contrast-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_4_Regression_Modeling_files/figure-html/bayes-contrast-1.png
--------------------------------------------------------------------------------
/Materials/Part_4_Regression_Modeling_files/figure-html/mars-sim-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_4_Regression_Modeling_files/figure-html/mars-sim-1.png
--------------------------------------------------------------------------------
/Materials/Part_5_Classification.R:
--------------------------------------------------------------------------------
1 | ###################################################################
2 | ## Code for Applied Machine Learning by Max Kuhn @ RStudio::conf
3 | ## https://github.com/topepo/rstudio-conf-2018
4 |
5 | library(ggplot2)
6 |
7 | thm <- theme_bw() +
8 | theme(
9 | panel.background = element_rect(fill = "transparent", colour = NA),
10 | plot.background = element_rect(fill = "transparent", colour = NA),
11 | legend.position = "top",
12 | legend.background = element_rect(fill = "transparent", colour = NA),
13 | legend.key = element_rect(fill = "transparent", colour = NA)
14 | )
15 | theme_set(thm)
16 |
17 |
18 | # Slide 4
19 |
20 | library(yardstick)
21 | library(dplyr)
22 | two_class_example %>% head(4)
23 |
24 | # Slide 5
25 |
26 | two_class_example %>%
27 | conf_mat(truth = truth, estimate = predicted)
28 |
29 | two_class_example %>%
30 | accuracy(truth = truth, estimate = predicted)
31 |
32 | # Slide 6
33 |
34 | two_class_example %>%
35 | sens(truth = truth, estimate = predicted)
36 |
37 | two_class_example %>%
38 | spec(truth = truth, estimate = predicted)
39 |
40 | # Slide 9
41 |
42 | library(pROC)
43 | roc_obj <- roc(
44 | response = two_class_example$truth,
45 | predictor = two_class_example$Class1,
46 | # If the first level is the event of interest:
47 | levels = rev(levels(two_class_example$truth))
48 | )
49 |
50 | auc(roc_obj)
51 |
52 | plot(
53 | roc_obj,
54 | legacy.axes = TRUE,
55 | print.thres = c(.2, .5, .8),
56 | print.thres.pattern = "cut = %.2f (Spec = %.2f, Sens = %.2f)",
57 | print.thres.cex = .8
58 | )
59 |
60 | # Slide 11
61 |
62 | library(dplyr)
63 | load("Data/okc.RData")
64 | okc_train %>% dim()
65 | okc_test %>% nrow()
66 | table(okc_train$Class)
67 |
68 | # Slide 16
69 |
70 | library(caret)
71 | ctrl <- trainControl(
72 | method = "cv",
73 | # Also predict the probabilities
74 | classProbs = TRUE,
75 | # Compute the ROC AUC as well as the sens and
76 | # spec from the default 50% cutoff. The
77 | # function `twoClassSummary` will produce those.
78 | summaryFunction = twoClassSummary,
79 | savePredictions = "final",
80 | sampling = "down"
81 | )
82 |
83 | # Slide 22
84 |
85 | set.seed(5515)
86 | cart_mod <- train(
87 | x = okc_train[, names(okc_train) != "Class"],
88 | y = okc_train$Class,
89 | method = "rpart2",
90 | metric = "ROC",
91 | tuneGrid = data.frame(maxdepth = 1:20),
92 | trControl = ctrl
93 | )
94 |
95 | # Slide 23
96 |
97 | cart_mod$finalModel
98 |
99 | # Slide 24
100 |
101 | ggplot(cart_mod)
102 |
103 | # Slide 25
104 |
105 | plot_roc <- function(x, ...) {
106 | averaged <- x %>%
107 | group_by(rowIndex, obs) %>%
108 | summarise(stem = mean(stem, na.rm = TRUE))
109 | roc_obj <- roc(
110 | averaged[["obs"]],
111 | averaged[["stem"]],
112 | levels = rev(levels(averaged$obs))
113 | )
114 | plot(roc_obj, ...)
115 | }
116 | plot_roc(cart_mod$pred)
117 |
118 | # Slide 26
119 |
120 | confusionMatrix(cart_mod)
121 |
122 | # Slide 27
123 |
124 | cart_imp <- varImp(cart_mod, scale = FALSE,
125 | surrogates = FALSE, competes = FALSE)
126 | ggplot(cart_imp, top = 7) + xlab("")
127 |
128 | # Slide 35
129 |
130 | set.seed(5515)
131 | cart_bag <- train(
132 | x = okc_train[, names(okc_train) != "Class"],
133 | y = okc_train$Class,
134 | method = "treebag",
135 | metric = "ROC",
136 | trControl = ctrl
137 | )
138 |
139 | # Slide 36
140 |
141 | cart_bag
142 |
143 | # Slide 37
144 |
145 | confusionMatrix(cart_bag)
146 |
147 | # Slide 38
148 |
149 | plot_roc(cart_mod$pred)
150 | plot_roc(cart_bag$pred, col = "darkred", add = TRUE)
151 |
152 | # Slide 39
153 |
154 | bag_imp <- varImp(cart_bag, scale = FALSE)
155 | ggplot(bag_imp, top = 30) + xlab("")
156 |
157 |
158 | # Slide 46
159 |
160 | ggplot(okc_train, aes(x = essay_length, col = Class)) +
161 | geom_line(stat = "density")
162 |
163 | # Slide 48
164 |
165 | library(tidyr)
166 |
167 | pred_xtab <- table(okc_train$religion, okc_train$Class)
168 | pred_xtab <- t(apply(pred_xtab, 2, function(x) x/sum(x)))
169 | pred_xtab <- as.data.frame(pred_xtab) %>%
170 | tibble::rownames_to_column("Class") %>%
171 | gather(value, prob, -Class)
172 |
173 | ggplot(pred_xtab, aes(x = reorder(value, prob), y = prob, fill = Class)) +
174 | geom_bar(stat = "identity", position = position_dodge()) +
175 | xlab("") +
176 | ylab("Within-Class Probability")
177 |
178 | # Slide 53
179 |
180 | library(recipes)
181 | is_dummy <- vapply(okc_train, function(x) length(unique(x)) == 2 & is.numeric(x), logical(1))
182 | dummies <- names(is_dummy)[is_dummy]
183 | no_dummies <- recipe(Class ~ ., data = okc_train) %>%
184 | step_bin2factor(!!! dummies) %>%
185 | step_zv(all_predictors())
186 |
187 | smoothing_grid <- expand.grid(usekernel = TRUE, fL = 0, adjust = seq(0.5, 3.5, by = 0.5))
188 |
189 | # Slide 54
190 |
191 | set.seed(5515)
192 | nb_mod <- train(
193 | no_dummies,
194 | data = okc_train,
195 | method = "nb",
196 | metric = "ROC",
197 | tuneGrid = smoothing_grid,
198 | trControl = ctrl
199 | )
200 |
201 | # Slide 55
202 |
203 | ggplot(nb_mod)
204 |
205 | # Slide 56
206 |
207 | plot_roc(cart_mod$pred)
208 | plot_roc(cart_bag$pred, col = "red", add = TRUE)
209 | plot_roc(nb_mod$pred, col = "blue", add = TRUE)
210 |
211 | # Slide 58
212 |
213 | rs <- resamples(
214 | list(CART = cart_mod, Bagged = cart_bag, Bayes = nb_mod)
215 | )
216 | library(tidyposterior)
217 | roc_mod <- perf_mod(rs, seed = 2560, iter = 5000)
218 |
219 | # Slide 59
220 |
221 | roc_dist <- tidy(roc_mod)
222 | summary(roc_dist)
223 | differences <-
224 | contrast_models(
225 | roc_mod,
226 | list_1 = c("Bagged", "Bayes"),
227 | list_2 = c("CART", "Bagged"),
228 | seed = 650
229 | )
230 |
231 | # Slide 60
232 |
233 | summary(differences, size = 0.025)
234 |
235 | differences %>%
236 | mutate(contrast = paste(model_2, "vs", model_1)) %>%
237 | ggplot(aes(x = difference, col = contrast)) +
238 | geom_line(stat = "density") +
239 | geom_vline(xintercept = c(-0.025, 0.025), lty = 2)
240 |
241 | # Slide 62
242 |
243 | test_res <- okc_test %>%
244 | dplyr::select(Class) %>%
245 | mutate(
246 | prob = predict(nb_mod, okc_test, type = "prob")[, "stem"],
247 | pred = predict(nb_mod, okc_test)
248 | )
249 | roc_curve <- roc(test_res$Class, test_res$prob, levels = c("other", "stem"))
250 |
251 |
252 | # Slide 63
253 |
254 | plot(
255 | roc_curve,
256 | print.thres = .5,
257 | print.thres.pattern = "cut = %.2f (Sp = %.3f, Sn = %.3f)",
258 | legacy.axes = TRUE
259 | )
260 |
261 | roc_curve
262 | getTrainPerf(nb_mod)
263 |
264 | # Slide 64
265 |
266 | ggplot(test_res, aes(x = prob)) + geom_histogram(binwidth = .04) + facet_wrap(~Class)
267 |
268 |
--------------------------------------------------------------------------------
/Materials/Part_5_Classification.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_5_Classification.pdf
--------------------------------------------------------------------------------
/Materials/Part_5_Classification_files/figure-html/boot-cart-1-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_5_Classification_files/figure-html/boot-cart-1-1.png
--------------------------------------------------------------------------------
/Materials/Part_5_Classification_files/figure-html/boot-cart-2-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_5_Classification_files/figure-html/boot-cart-2-1.png
--------------------------------------------------------------------------------
/Materials/Part_5_Classification_files/figure-html/boot-cart-3-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_5_Classification_files/figure-html/boot-cart-3-1.png
--------------------------------------------------------------------------------
/Materials/Part_5_Classification_files/figure-html/cart-plot-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_5_Classification_files/figure-html/cart-plot-1.png
--------------------------------------------------------------------------------
/Materials/RData/cart_bag.RData:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/RData/cart_bag.RData
--------------------------------------------------------------------------------
/Materials/RData/cart_mod.RData:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/RData/cart_mod.RData
--------------------------------------------------------------------------------
/Materials/RData/glmn_mod.RData:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/RData/glmn_mod.RData
--------------------------------------------------------------------------------
/Materials/RData/mars_gcv_bag.RData:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/RData/mars_gcv_bag.RData
--------------------------------------------------------------------------------
/Materials/RData/mars_gcv_mod.RData:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/RData/mars_gcv_mod.RData
--------------------------------------------------------------------------------
/Materials/RData/mars_mod.RData:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/RData/mars_mod.RData
--------------------------------------------------------------------------------
/Materials/RData/nb_mod.RData:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/RData/nb_mod.RData
--------------------------------------------------------------------------------
/Materials/Template.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Presentation"
3 | author: Your Name Here
4 | output:
5 | xaringan::moon_reader:
6 | css: ["mtheme_max.css", "fonts_mtheme_max.css"]
7 | self_contained: false
8 | lib_dir: libs
9 | nature:
10 | ratio: '16:9'
11 | highlightLanguage: R
12 | countIncrementalSlides: false
13 | ---
14 |
15 | ```{r startup, include = FALSE, message = FALSE, warning = FALSE}
16 | # This is good for getting the ggplot background consistent with
17 | # the html background color
18 | library(ggplot2)
19 | thm <- theme_bw() +
20 | theme(
21 | panel.background = element_rect(fill = "transparent", colour = NA),
22 | plot.background = element_rect(fill = "transparent", colour = NA),
23 | legend.position = "top",
24 | legend.background = element_rect(fill = "transparent", colour = NA),
25 | legend.key = element_rect(fill = "transparent", colour = NA)
26 | )
27 | theme_set(thm)
28 | ```
29 |
30 | # Outline
31 |
32 | * Something
33 | * Something else
34 | * That other thing
35 |
36 |
37 | ---
38 | layout: false
39 | class: inverse, middle, center
40 |
41 | # Heading Text
42 |
43 | ---
44 |
45 | # Some Acronyms and Codes
46 |
47 | .pull-left[
48 | Test or code chunks for the lhs
49 | ]
50 | .pull-right[
51 | rhs bits
52 | ]
53 |
54 | ---
55 |
56 | # Plot on the entire slide with a hex sticker
57 |
58 | ```{r example-plot, fig.width=6, fig.height=5.5, out.width = '40%', fig.align='center', dev = 'svg', dev.args = list(bg = "transparent")}
59 | ggplot(mtcars, aes(x = disp, y = mpg))+
60 | geom_point()
61 | ```
62 |
63 | ---
64 |
65 | # Plots on one side
66 |
67 | .pull-left[
68 | show some code here but don't make image:
69 |
70 | ```{r just-dont, eval = FALSE}
71 | ggplot(mtcars, aes(x = disp, y = mpg))+
72 | geom_point()
73 | ```
74 |
75 | ]
76 | .pull-right[
77 |
78 | ```{r example-plot-again, echo = FALSE, fig.width=6, fig.height=5.5, out.width = '90%', fig.align='center', dev = 'svg', dev.args = list(bg = "transparent")}
79 | ggplot(mtcars, aes(x = disp, y = mpg))+
80 | geom_point()
81 | ```
82 | ]
83 |
84 |
--------------------------------------------------------------------------------
/Materials/Template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Presentation
5 |
6 |
7 |
8 |
9 |
10 |
11 |
77 |
78 |
85 |
86 |
93 |
94 |
104 |
105 |
106 |
--------------------------------------------------------------------------------
/Materials/fonts_mtheme_max.css:
--------------------------------------------------------------------------------
1 | @import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz);
2 | @import url(https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic);
3 | @import url(https://fonts.googleapis.com/css?family=Source+Code+Pro:400,700);
4 | @import url(https://fonts.googleapis.com/css?family=Fira+Sans:300,300i,400,400i,500,500i,700,700i);
5 | @import url(https://cdn.rawgit.com/tonsky/FiraCode/1.204/distr/fira_code.css);
6 |
7 | @import url(https://fonts.googleapis.com/css?family=Noto+Serif);
8 |
9 | body {
10 | font-family: 'Fira Sans','Droid Serif', 'Palatino Linotype', 'Book Antiqua', Palatino, 'Microsoft YaHei', 'Songti SC', serif;
11 | font-size: 120%;
12 | }
13 |
14 | p {
15 | font-family: 'Fira Sans','Droid Serif', 'Palatino Linotype', 'Book Antiqua', Palatino, 'Microsoft YaHei', 'Songti SC', serif;
16 | font-size: 120%;
17 | }
18 |
19 | ul, ol {
20 | font-family: 'Fira Sans','Droid Serif', 'Palatino Linotype', 'Book Antiqua', Palatino, 'Microsoft YaHei', 'Songti SC', serif;
21 | font-size: 100%;
22 | }
23 |
24 | .remark-code, .remark-inline-code {
25 | font-family: 'Source Code Pro', 'Lucida Console', Monaco, monospace;
26 | font-size: 80%;
27 | }
28 |
29 | .remark-inline-code {
30 | /* background: #F5F5F5; /* lighter */
31 | /* background: #e7e8e2; /* darker */
32 | border-radius: 3px;
33 | padding: 4px;
34 | }
35 |
36 | .code10 .remark-code {
37 | font-size: 10%;
38 | }
39 |
40 | .code20 .remark-code {
41 | font-size: 20%;
42 | }
43 |
44 | .code30 .remark-code {
45 | font-size: 30%;
46 | }
47 |
48 | .code40 .remark-code {
49 | font-size: 40%;
50 | }
51 |
52 | .code50 .remark-code {
53 | font-size: 50%;
54 | }
55 |
56 | .code60 .remark-code {
57 | font-size: 60%;
58 | }
59 |
60 | .code70 .remark-code {
61 | font-size: 70%;
62 | }
63 |
64 | .code80 .remark-code {
65 | font-size: 80%;
66 | }
67 |
68 | .code90 .remark-code {
69 | font-size: 90%;
70 | }
71 |
72 | .code100 .remark-code {
73 | font-size: 100%;
74 | }
75 |
76 | .font10 {
77 | font-size: 10%;
78 | }
79 |
80 | .font20 {
81 | font-size: 20%;
82 | }
83 |
84 | .font30 {
85 | font-size: 30%;
86 | }
87 |
88 | .font40 {
89 | font-size: 40%;
90 | }
91 |
92 | .font50 {
93 | font-size: 50%;
94 | }
95 |
96 | .font60 {
97 | font-size: 60%;
98 | }
99 |
100 | .font70 {
101 | font-size: 70%;
102 | }
103 |
104 | .font80 {
105 | font-size: 80%;
106 | }
107 |
108 | .font90 {
109 | font-size: 90%;
110 | }
111 |
112 | .font100 {
113 | font-size: 100%;
114 | }
115 |
116 | .font110 {
117 | font-size: 110%;
118 | }
119 |
120 | .font120 {
121 | font-size: 120%;
122 | }
123 |
124 | .font130 {
125 | font-size: 130%;
126 | }
127 |
128 | .font140 {
129 | font-size: 140%;
130 | }
131 |
132 | .font150 {
133 | font-size: 150%;
134 | }
135 |
136 | .font160 {
137 | font-size: 160%;
138 | }
139 | .font170 {
140 | font-size: 170%;
141 | }
142 | .font180 {
143 | font-size: 180%;
144 | }
145 | .font190 {
146 | font-size: 190%;
147 | }
148 | .font200 {
149 | font-size: 200%;
150 | }
151 |
--------------------------------------------------------------------------------
/Materials/images/broom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/broom.png
--------------------------------------------------------------------------------
/Materials/images/dplyr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/dplyr.png
--------------------------------------------------------------------------------
/Materials/images/ggplot2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/ggplot2.png
--------------------------------------------------------------------------------
/Materials/images/nope.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/nope.png
--------------------------------------------------------------------------------
/Materials/images/nopestradomis.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/nopestradomis.jpg
--------------------------------------------------------------------------------
/Materials/images/purrr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/purrr.png
--------------------------------------------------------------------------------
/Materials/images/readr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/readr.png
--------------------------------------------------------------------------------
/Materials/images/recipes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/recipes.png
--------------------------------------------------------------------------------
/Materials/images/review-resamp-cache.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/review-resamp-cache.png
--------------------------------------------------------------------------------
/Materials/images/rsample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/rsample.png
--------------------------------------------------------------------------------
/Materials/images/tidyposterior.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/tidyposterior.png
--------------------------------------------------------------------------------
/Materials/images/yardstick.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/yardstick.png
--------------------------------------------------------------------------------
/Materials/libs/DiagrammeR-styles-0.2/styles.css:
--------------------------------------------------------------------------------
1 | .DiagrammeR,.grViz pre {
2 | white-space: pre-wrap; /* CSS 3 */
3 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
4 | white-space: -pre-wrap; /* Opera 4-6 */
5 | white-space: -o-pre-wrap; /* Opera 7 */
6 | word-wrap: break-word; /* Internet Explorer 5.5+ */
7 | }
8 |
9 | .DiagrammeR g .label {
10 | font-family: Helvetica;
11 | font-size: 14px;
12 | color: #333333;
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/Materials/libs/Proj4Leaflet-0.7.2/proj4leaflet.js:
--------------------------------------------------------------------------------
1 | (function (factory) {
2 | var L, proj4;
3 | if (typeof define === 'function' && define.amd) {
4 | // AMD
5 | define(['leaflet', 'proj4'], factory);
6 | } else if (typeof module === 'object' && typeof module.exports === "object") {
7 | // Node/CommonJS
8 | L = require('leaflet');
9 | proj4 = require('proj4');
10 | module.exports = factory(L, proj4);
11 | } else {
12 | // Browser globals
13 | if (typeof window.L === 'undefined' || typeof window.proj4 === 'undefined')
14 | throw 'Leaflet and proj4 must be loaded first';
15 | factory(window.L, window.proj4);
16 | }
17 | }(function (L, proj4) {
18 |
19 | L.Proj = {};
20 |
21 | L.Proj._isProj4Obj = function(a) {
22 | return (typeof a.inverse !== 'undefined' &&
23 | typeof a.forward !== 'undefined');
24 | };
25 |
26 | L.Proj.ScaleDependantTransformation = function(scaleTransforms) {
27 | this.scaleTransforms = scaleTransforms;
28 | };
29 |
30 | L.Proj.ScaleDependantTransformation.prototype.transform = function(point, scale) {
31 | return this.scaleTransforms[scale].transform(point, scale);
32 | };
33 |
34 | L.Proj.ScaleDependantTransformation.prototype.untransform = function(point, scale) {
35 | return this.scaleTransforms[scale].untransform(point, scale);
36 | };
37 |
38 | L.Proj.Projection = L.Class.extend({
39 | initialize: function(a, def) {
40 | if (L.Proj._isProj4Obj(a)) {
41 | this._proj = a;
42 | } else {
43 | var code = a;
44 | if (def) {
45 | proj4.defs(code, def);
46 | } else if (proj4.defs[code] === undefined) {
47 | var urn = code.split(':');
48 | if (urn.length > 3) {
49 | code = urn[urn.length - 3] + ':' + urn[urn.length - 1];
50 | }
51 | if (proj4.defs[code] === undefined) {
52 | throw 'No projection definition for code ' + code;
53 | }
54 | }
55 | this._proj = proj4(code);
56 | }
57 | },
58 |
59 | project: function (latlng) {
60 | var point = this._proj.forward([latlng.lng, latlng.lat]);
61 | return new L.Point(point[0], point[1]);
62 | },
63 |
64 | unproject: function (point, unbounded) {
65 | var point2 = this._proj.inverse([point.x, point.y]);
66 | return new L.LatLng(point2[1], point2[0], unbounded);
67 | }
68 | });
69 |
70 | L.Proj.CRS = L.Class.extend({
71 | includes: L.CRS,
72 |
73 | options: {
74 | transformation: new L.Transformation(1, 0, -1, 0)
75 | },
76 |
77 | initialize: function(a, b, c) {
78 | var code, proj, def, options;
79 |
80 | if (L.Proj._isProj4Obj(a)) {
81 | proj = a;
82 | code = proj.srsCode;
83 | options = b || {};
84 |
85 | this.projection = new L.Proj.Projection(proj);
86 | } else {
87 | code = a;
88 | def = b;
89 | options = c || {};
90 | this.projection = new L.Proj.Projection(code, def);
91 | }
92 |
93 | L.Util.setOptions(this, options);
94 | this.code = code;
95 | this.transformation = this.options.transformation;
96 |
97 | if (this.options.origin) {
98 | this.transformation =
99 | new L.Transformation(1, -this.options.origin[0],
100 | -1, this.options.origin[1]);
101 | }
102 |
103 | if (this.options.scales) {
104 | this._scales = this.options.scales;
105 | } else if (this.options.resolutions) {
106 | this._scales = [];
107 | for (var i = this.options.resolutions.length - 1; i >= 0; i--) {
108 | if (this.options.resolutions[i]) {
109 | this._scales[i] = 1 / this.options.resolutions[i];
110 | }
111 | }
112 | }
113 | },
114 |
115 | scale: function(zoom) {
116 | var iZoom = Math.floor(zoom),
117 | baseScale,
118 | nextScale,
119 | scaleDiff,
120 | zDiff;
121 | if (zoom === iZoom) {
122 | return this._scales[zoom];
123 | } else {
124 | // Non-integer zoom, interpolate
125 | baseScale = this._scales[iZoom];
126 | nextScale = this._scales[iZoom + 1];
127 | scaleDiff = nextScale - baseScale;
128 | zDiff = (zoom - iZoom);
129 | return baseScale + scaleDiff * zDiff;
130 | }
131 | },
132 |
133 | getSize: function(zoom) {
134 | var b = this.options.bounds,
135 | s,
136 | min,
137 | max;
138 |
139 | if (b) {
140 | s = this.scale(zoom);
141 | min = this.transformation.transform(b.min, s);
142 | max = this.transformation.transform(b.max, s);
143 | return L.point(Math.abs(max.x - min.x), Math.abs(max.y - min.y));
144 | } else {
145 | // Backwards compatibility with Leaflet < 0.7
146 | s = 256 * Math.pow(2, zoom);
147 | return L.point(s, s);
148 | }
149 | }
150 | });
151 |
152 | L.Proj.CRS.TMS = L.Proj.CRS.extend({
153 | options: {
154 | tileSize: 256
155 | },
156 |
157 | initialize: function(a, b, c, d) {
158 | var code,
159 | def,
160 | proj,
161 | projectedBounds,
162 | options;
163 |
164 | if (L.Proj._isProj4Obj(a)) {
165 | proj = a;
166 | projectedBounds = b;
167 | options = c || {};
168 | options.origin = [projectedBounds[0], projectedBounds[3]];
169 | L.Proj.CRS.prototype.initialize.call(this, proj, options);
170 | } else {
171 | code = a;
172 | def = b;
173 | projectedBounds = c;
174 | options = d || {};
175 | options.origin = [projectedBounds[0], projectedBounds[3]];
176 | L.Proj.CRS.prototype.initialize.call(this, code, def, options);
177 | }
178 |
179 | this.projectedBounds = projectedBounds;
180 |
181 | this._sizes = this._calculateSizes();
182 | },
183 |
184 | _calculateSizes: function() {
185 | var sizes = [],
186 | crsBounds = this.projectedBounds,
187 | projectedTileSize,
188 | i,
189 | x,
190 | y;
191 | for (i = this._scales.length - 1; i >= 0; i--) {
192 | if (this._scales[i]) {
193 | projectedTileSize = this.options.tileSize / this._scales[i];
194 | // to prevent very small rounding errors from causing us to round up,
195 | // cut any decimals after 3rd before rounding up.
196 | x = Math.ceil(parseFloat((crsBounds[2] - crsBounds[0]) / projectedTileSize).toPrecision(3)) *
197 | projectedTileSize * this._scales[i];
198 | y = Math.ceil(parseFloat((crsBounds[3] - crsBounds[1]) / projectedTileSize).toPrecision(3)) *
199 | projectedTileSize * this._scales[i];
200 | sizes[i] = L.point(x, y);
201 | }
202 | }
203 |
204 | return sizes;
205 | },
206 |
207 | getSize: function(zoom) {
208 | return this._sizes[zoom];
209 | }
210 | });
211 |
212 | L.Proj.TileLayer = {};
213 |
214 | // Note: deprecated and not necessary since 0.7, will be removed
215 | L.Proj.TileLayer.TMS = L.TileLayer.extend({
216 | options: {
217 | continuousWorld: true
218 | },
219 |
220 | initialize: function(urlTemplate, crs, options) {
221 | var boundsMatchesGrid = true,
222 | scaleTransforms,
223 | upperY,
224 | crsBounds,
225 | i;
226 |
227 | if (!(crs instanceof L.Proj.CRS.TMS)) {
228 | throw 'CRS is not L.Proj.CRS.TMS.';
229 | }
230 |
231 | L.TileLayer.prototype.initialize.call(this, urlTemplate, options);
232 | // Enabling tms will cause Leaflet to also try to do TMS, which will
233 | // break (at least prior to 0.7.0). Actively disable it, to prevent
234 | // well-meaning users from shooting themselves in the foot.
235 | this.options.tms = false;
236 | this.crs = crs;
237 | crsBounds = this.crs.projectedBounds;
238 |
239 | // Verify grid alignment
240 | for (i = this.options.minZoom; i < this.options.maxZoom && boundsMatchesGrid; i++) {
241 | var gridHeight = (crsBounds[3] - crsBounds[1]) /
242 | this._projectedTileSize(i);
243 | boundsMatchesGrid = Math.abs(gridHeight - Math.round(gridHeight)) > 1e-3;
244 | }
245 |
246 | if (!boundsMatchesGrid) {
247 | scaleTransforms = {};
248 | for (i = this.options.minZoom; i < this.options.maxZoom; i++) {
249 | upperY = crsBounds[1] + Math.ceil((crsBounds[3] - crsBounds[1]) /
250 | this._projectedTileSize(i)) * this._projectedTileSize(i);
251 | scaleTransforms[this.crs.scale(i)] = new L.Transformation(1, -crsBounds[0], -1, upperY);
252 | }
253 |
254 | this.crs = new L.Proj.CRS.TMS(this.crs.projection._proj, crsBounds, this.crs.options);
255 | this.crs.transformation = new L.Proj.ScaleDependantTransformation(scaleTransforms);
256 | }
257 | },
258 |
259 | getTileUrl: function(tilePoint) {
260 | var zoom = this._map.getZoom(),
261 | gridHeight = Math.ceil(
262 | (this.crs.projectedBounds[3] - this.crs.projectedBounds[1]) /
263 | this._projectedTileSize(zoom));
264 |
265 | return L.Util.template(this._url, L.Util.extend({
266 | s: this._getSubdomain(tilePoint),
267 | z: this._getZoomForUrl(),
268 | x: tilePoint.x,
269 | y: gridHeight - tilePoint.y - 1
270 | }, this.options));
271 | },
272 |
273 | _projectedTileSize: function(zoom) {
274 | return (this.options.tileSize / this.crs.scale(zoom));
275 | }
276 | });
277 |
278 | L.Proj.GeoJSON = L.GeoJSON.extend({
279 | initialize: function(geojson, options) {
280 | this._callLevel = 0;
281 | L.GeoJSON.prototype.initialize.call(this, null, options);
282 | if (geojson) {
283 | this.addData(geojson);
284 | }
285 | },
286 |
287 | addData: function(geojson) {
288 | var crs;
289 |
290 | if (geojson) {
291 | if (geojson.crs && geojson.crs.type === 'name') {
292 | crs = new L.Proj.CRS(geojson.crs.properties.name);
293 | } else if (geojson.crs && geojson.crs.type) {
294 | crs = new L.Proj.CRS(geojson.crs.type + ':' + geojson.crs.properties.code);
295 | }
296 |
297 | if (crs !== undefined) {
298 | this.options.coordsToLatLng = function(coords) {
299 | var point = L.point(coords[0], coords[1]);
300 | return crs.projection.unproject(point);
301 | };
302 | }
303 | }
304 |
305 | // Base class' addData might call us recursively, but
306 | // CRS shouldn't be cleared in that case, since CRS applies
307 | // to the whole GeoJSON, inluding sub-features.
308 | this._callLevel++;
309 | try {
310 | L.GeoJSON.prototype.addData.call(this, geojson);
311 | } finally {
312 | this._callLevel--;
313 | if (this._callLevel === 0) {
314 | delete this.options.coordsToLatLng;
315 | }
316 | }
317 | }
318 | });
319 |
320 | L.Proj.geoJson = function(geojson, options) {
321 | return new L.Proj.GeoJSON(geojson, options);
322 | };
323 |
324 | L.Proj.ImageOverlay = L.ImageOverlay.extend({
325 | initialize: function(url, bounds, options) {
326 | L.ImageOverlay.prototype.initialize.call(this, url, null, options);
327 | this._projBounds = bounds;
328 | },
329 |
330 | /* Danger ahead: overriding internal methods in Leaflet.
331 | I've decided to do this rather than making a copy of L.ImageOverlay
332 | and making very tiny modifications to it. Future will tell if this
333 | was wise or not. */
334 | _animateZoom: function (e) {
335 | var northwest = L.point(this._projBounds.min.x, this._projBounds.max.y),
336 | southeast = L.point(this._projBounds.max.x, this._projBounds.min.y),
337 | topLeft = this._projectedToNewLayerPoint(northwest, e.zoom, e.center),
338 | size = this._projectedToNewLayerPoint(southeast, e.zoom, e.center).subtract(topLeft),
339 | origin = topLeft.add(size._multiplyBy((1 - 1 / e.scale) / 2));
340 |
341 | this._image.style[L.DomUtil.TRANSFORM] =
342 | L.DomUtil.getTranslateString(origin) + ' scale(' + this._map.getZoomScale(e.zoom) + ') ';
343 | },
344 |
345 | _reset: function() {
346 | var zoom = this._map.getZoom(),
347 | pixelOrigin = this._map.getPixelOrigin(),
348 | bounds = L.bounds(this._transform(this._projBounds.min, zoom)._subtract(pixelOrigin),
349 | this._transform(this._projBounds.max, zoom)._subtract(pixelOrigin)),
350 | size = bounds.getSize(),
351 | image = this._image;
352 |
353 | L.DomUtil.setPosition(image, bounds.min);
354 | image.style.width = size.x + 'px';
355 | image.style.height = size.y + 'px';
356 | },
357 |
358 | _projectedToNewLayerPoint: function (point, newZoom, newCenter) {
359 | var topLeft = this._map._getNewTopLeftPoint(newCenter, newZoom).add(this._map._getMapPanePos());
360 | return this._transform(point, newZoom)._subtract(topLeft);
361 | },
362 |
363 | _transform: function(p, zoom) {
364 | var crs = this._map.options.crs,
365 | transformation = crs.transformation,
366 | scale = crs.scale(zoom);
367 | return transformation.transform(p, scale);
368 | }
369 | });
370 |
371 | L.Proj.imageOverlay = function(url, bounds, options) {
372 | return new L.Proj.ImageOverlay(url, bounds, options);
373 | };
374 |
375 | if (typeof L.CRS !== 'undefined') {
376 | // This is left here for backwards compatibility
377 | L.CRS.proj4js = (function () {
378 | return function (code, def, transformation, options) {
379 | options = options || {};
380 | if (transformation) {
381 | options.transformation = transformation;
382 | }
383 |
384 | return new L.Proj.CRS(code, def, options);
385 | };
386 | }());
387 | }
388 |
389 | return L.Proj;
390 | }));
391 |
--------------------------------------------------------------------------------
/Materials/libs/d3-lasso-0.0.5/d3-lasso.min.js:
--------------------------------------------------------------------------------
1 | !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("d3-selection"),require("d3-drag")):"function"==typeof define&&define.amd?define(["exports","d3-selection","d3-drag"],n):n(t.d3=t.d3||{},t.d3,t.d3)}(this,function(t,n,r){"use strict";function e(t,n){return n={exports:{}},t(n,n.exports),n.exports}function o(){function t(t){function u(){p=[],h="",_.attr("d",null),m.attr("d",null),r.nodes().forEach(function(t){t.__lasso.possible=!1,t.__lasso.selected=!1,t.__lasso.hoverSelect=!1,t.__lasso.loopSelect=!1;var n=t.getBoundingClientRect();t.__lasso.lassoPoint=[Math.round(n.left+n.width/2),Math.round(n.top+n.height/2)]}),s&&r.on("mouseover.lasso",function(){this.__lasso.hoverSelect=!0}),i.start()}function l(){var t,n;"touchmove"===d3.event.sourceEvent.type?(t=d3.event.sourceEvent.touches[0].clientX,n=d3.event.sourceEvent.touches[0].clientY):(t=d3.event.sourceEvent.clientX,n=d3.event.sourceEvent.clientY);var s=d3.mouse(this)[0],u=d3.mouse(this)[1];""===h?(h=h+"M "+s+" "+u,v=[t,n],d=[s,u],b.attr("cx",s).attr("cy",u).attr("r",7).attr("display",null)):h=h+" L "+s+" "+u,p.push([t,n]);var l=Math.sqrt(Math.pow(t-v[0],2)+Math.pow(n-v[1],2)),f="M "+s+" "+u+" L "+d[0]+" "+d[1];_.attr("d",h),m.attr("d",f),a=l<=e,a&&o?m.attr("display",null):m.attr("display","none"),r.nodes().forEach(function(t){t.__lasso.loopSelect=!(!a||!o)&&c(p,t.__lasso.lassoPoint)<1,t.__lasso.possible=t.__lasso.hoverSelect||t.__lasso.loopSelect}),i.draw()}function f(){r.on("mouseover.lasso",null),r.nodes().forEach(function(t){t.__lasso.selected=t.__lasso.possible,t.__lasso.possible=!1}),_.attr("d",null),m.attr("d",null),b.attr("display","none"),i.end()}var h,v,d,p,g=t.append("g").attr("class","lasso"),_=g.append("path").attr("class","drawn"),m=g.append("path").attr("class","loop_close"),b=g.append("circle").attr("class","origin"),M=d3.drag().on("start",u).on("drag",l).on("end",f);n.call(M)}var n,r=[],e=75,o=!0,a=!1,s=!0,i={start:function(){},draw:function(){},end:function(){}};return t.items=function(n){if(!arguments.length)return r;r=n;var e=r.nodes();return e.forEach(function(t){t.__lasso={possible:!1,selected:!1}}),t},t.possibleItems=function(){return r.filter(function(){return this.__lasso.possible})},t.selectedItems=function(){return r.filter(function(){return this.__lasso.selected})},t.notPossibleItems=function(){return r.filter(function(){return!this.__lasso.possible})},t.notSelectedItems=function(){return r.filter(function(){return!this.__lasso.selected})},t.closePathDistance=function(n){return arguments.length?(e=n,t):e},t.closePathSelect=function(n){return arguments.length?(o=n===!0,t):o},t.isPathClosed=function(n){return arguments.length?(a=n===!0,t):a},t.hoverSelect=function(n){return arguments.length?(s=n===!0,t):s},t.on=function(n,r){if(!arguments.length)return i;if(1===arguments.length)return i[n];var e=["start","draw","end"];return e.indexOf(n)>-1&&(i[n]=r),t},t.targetArea=function(r){return arguments.length?(n=r,t):n},t}var a=e(function(t){function n(t,n,e){var o=t*n,a=r*t,s=a-t,i=a-s,u=t-i,l=r*n,f=l-n,c=l-f,h=n-c,v=o-i*c,d=v-u*c,p=d-i*h,g=u*h-p;return e?(e[0]=g,e[1]=o,e):[g,o]}t.exports=n;var r=+(Math.pow(2,27)+1)}),s=e(function(t){function n(t,n){var r=t+n,e=r-t,o=r-e,a=n-e,s=t-o,i=s+a;return i?[i,r]:[r]}function r(t,r){var e=0|t.length,o=0|r.length;if(1===e&&1===o)return n(t[0],r[0]);var a,s,i=e+o,u=new Array(i),l=0,f=0,c=0,h=Math.abs,v=t[f],d=h(v),p=r[c],g=h(p);d=o?(a=v,f+=1,f=o?(a=v,f+=1,f>1;return["sum(",o(t.slice(0,n)),",",o(t.slice(n)),")"].join("")}function i(t){if(2===t.length)return[["sum(prod(",t[0][0],",",t[1][1],"),prod(-",t[0][1],",",t[1][0],"))"].join("")];for(var r=[],a=0;a0){if(a<=0)return s;e=o+a}else{if(!(o<0))return s;if(a>=0)return s;e=-(o+a)}var i=b*e;return s>=i||s<=-i?s:y(t,n,r)},function(t,n,r,e){var o=t[0]-e[0],a=n[0]-e[0],s=r[0]-e[0],i=t[1]-e[1],u=n[1]-e[1],l=r[1]-e[1],f=t[2]-e[2],c=n[2]-e[2],h=r[2]-e[2],v=a*l,d=s*u,p=s*i,g=o*l,_=o*u,m=a*i,b=f*(v-d)+c*(p-g)+h*(_-m),y=(Math.abs(v)+Math.abs(d))*Math.abs(f)+(Math.abs(p)+Math.abs(g))*Math.abs(c)+(Math.abs(_)+Math.abs(m))*Math.abs(h),x=M*y;return b>x||-b>x?b:w(t,n,r,e)}];h()}),c=e(function(t){function n(t,n){for(var e=n[0],o=n[1],a=t.length,s=1,i=a,u=0,l=a-1;u0;){var b=(l+a-1)%a,M=t[b];if(M[1]!==o)break;var y=M[0];_=Math.min(_,y),m=Math.max(m,y),l=b}if(0===l)return _<=e&&e<=m?0:1;i=l+1}for(var w=t[(l+a-1)%a][1];u+1-1) {
247 | on[type] = _;
248 | }
249 | return lasso;
250 | };
251 |
252 | // Area where lasso can be triggered from
253 | lasso.targetArea = function(_) {
254 | if(!arguments.length) return targetArea;
255 | targetArea = _;
256 | return lasso;
257 | }
258 |
259 |
260 |
261 | return lasso;
262 | };
263 |
--------------------------------------------------------------------------------
/Materials/libs/ggiraph-0.2.0/styles.css:
--------------------------------------------------------------------------------
1 | .ggiraph-toolbar {
2 | position: absolute;
3 | top: 3px;
4 | right: 3px;
5 | z-index: 1001;
6 | background: rgba(255, 255, 255,.3);
7 | border-radius: 5px;
8 | padding-top:2px;
9 | opacity: 0;
10 | transition: opacity 0.3s ease 0s;
11 | }
12 |
13 | .ggiraph-toolbar-block {
14 | display: inline-block;
15 | padding-right: 10px;
16 | }
17 |
18 | .ggiraph-toolbar-icon {
19 | position: relative;
20 | cursor: pointer;
21 | box-sizing: border-box;
22 | padding-right: 3px;
23 | }
24 |
25 | .drop {
26 | stroke: #E30C37;
27 | fill: #E30C37;
28 | }
29 | .drop:hover{
30 | stroke: #333333;
31 | fill: #333333;
32 | }
33 | .neutral {
34 | stroke: #006699;
35 | fill: #006699;
36 | }
37 | .neutral:hover{
38 | stroke: #333333;
39 | fill: #333333;
40 | }
41 |
42 | .ggiraph-container {
43 | position: relative;
44 | margin:auto;
45 | }
46 |
47 | .flex-container {
48 | height: 0;
49 | padding:0;
50 | width:100%;
51 | }
52 |
53 | .svg-inline-container {
54 | position: absolute;
55 | margin:auto;
56 | width:100%;
57 | top: 0;
58 | left: 0;
59 | right: 0;
60 | }
61 |
62 | .svg-responsive-container {
63 | width:100%;
64 | }
65 |
66 | .lasso path {
67 | stroke: rgb(80,80,80);
68 | stroke-width:2px;
69 | }
70 |
71 | .lasso .drawn {
72 | fill-opacity:.05 ;
73 | }
74 |
75 | .lasso .loop_close {
76 | fill:none;
77 | stroke-dasharray: 4,4;
78 | }
79 |
80 | .lasso .origin {
81 | fill:#333333;
82 | fill-opacity:.5;
83 | }
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/Materials/libs/ggiraph-binding-0.4.1/ggiraph.js:
--------------------------------------------------------------------------------
1 | /*
2 | set_over_effect
3 | */
4 | function set_over_effect(id){
5 | d3.select("#" + id ).on("mouseover", function(d) {
6 | d3.select('#' + id +' div.ggiraph-toolbar').transition()
7 | .duration(200)
8 | .style("opacity", 0.8);
9 | })
10 | .on("mouseout", function(d) {
11 | d3.select('#' + id +' div.ggiraph-toolbar').transition()
12 | .duration(500)
13 | .style("opacity", 0);
14 | });
15 | }
16 |
17 | function set_tooltip(id, tooltip_opacity, tooltip_offx, tooltip_offy) {
18 |
19 | var div = d3.select('body').append("div")
20 | .attr("class", 'tooltip_' + id)
21 | .style("opacity", 0);
22 | var sel_tooltiped = d3.selectAll('#' + id + ' svg *[title]');
23 | sel_tooltiped.on("mouseover", function(d) {
24 | div.transition()
25 | .duration(200)
26 | .style("opacity", tooltip_opacity);
27 | div.html(d3.select(this).attr("title"))
28 | .style("left", (d3.event.pageX + tooltip_offx ) + "px")
29 | .style("top", (d3.event.pageY + tooltip_offy ) + "px");
30 | })
31 | .on("mouseout", function(d) {
32 | div.transition()
33 | .duration(500)
34 | .style("opacity", 0);
35 | });
36 |
37 | }
38 |
39 |
40 |
41 | function set_selector(container_id, sel_array_name, selected_class, sel_type, widget_id) {
42 |
43 | var sel_data_id = d3.selectAll('#' + container_id + ' svg *[data-id]');
44 |
45 | if( sel_type == "single" ){
46 | sel_data_id.call(select_data_id_single, sel_array_name, selected_class, widget_id, container_id);
47 | } else if( sel_type == "multiple" ){
48 | sel_data_id.call(select_data_id_multiple, sel_array_name, selected_class, widget_id, container_id);
49 | } else {
50 | sel_data_id.call(function(selection) {selection.on("click", null);});
51 | }
52 | }
53 |
54 | function set_highlight(id) {
55 | var sel_data_id = d3.selectAll('#' + id + ' svg *[data-id]');
56 | sel_data_id.classed("cl_data_id_" + id, true);
57 | }
58 |
59 |
60 | function resize(id, width, height) {
61 | var containerdiv = d3.select('#' + id + " div");
62 | var is_fd = window["fd_" + containerdiv.attr("id")];
63 | if(is_fd > 0){
64 | var ratio = window["ratio_" + containerdiv.attr("id")];
65 | var dady = containerdiv.node().parentNode;
66 | var dadybb = dady.getBoundingClientRect();
67 | containerdiv.style("width", (dadybb.bottom - dadybb.top) * ratio + "px");
68 | }
69 | }
70 |
71 |
72 |
73 | function lasso_on(id_str, add, sel_array_name, selected_class ){
74 |
75 | if( typeof Shiny === 'undefined' ) return false;
76 |
77 | var widget_id = window["widget_" + id_str];
78 | var svg = d3.select('#' + id_str + ' svg');
79 |
80 | var lasso_start = function() {};
81 | var lasso_draw = function() {};
82 | var lasso_end = function() {
83 | lasso.selectedItems().each( function(d, i){
84 | d3.select(this).classed(selected_class, true);
85 | var dataid = d3.select(this).attr("data-id");
86 | var index = window[sel_array_name].indexOf(dataid);
87 | if( index < 0 && add ){
88 | window[sel_array_name].push( dataid );
89 | } else if( index >= 0 && !add ){
90 | window[sel_array_name].splice(index,1);
91 | }
92 |
93 | });
94 | refresh_selected(sel_array_name, selected_class, id_str);
95 |
96 | svg.on(".dragstart", null)
97 | .on(".drag", null)
98 | .on(".dragend", null);
99 |
100 | Shiny.onInputChange(widget_id + "_selected", window[sel_array_name]);
101 | };
102 |
103 | var lasso = window["lasso_"+id_str]
104 | .closePathSelect(true)
105 | .closePathDistance(100)
106 | .items(svg.selectAll('*[data-id]'))
107 | .targetArea(svg)
108 | .on("start",lasso_start)
109 | .on("draw",lasso_draw)
110 | .on("end",lasso_end);
111 |
112 | svg.call(lasso);
113 | }
114 |
115 |
116 |
117 | function zoom_on(id, zoom_min, zoom_max){
118 | var zoom_ = window["zoom_" + id];
119 | d3.select('#' + id ).call(zoom_
120 | .on("zoom", (function() {
121 | d3.select('#' + id + ' svg g').attr("transform", d3.event.transform);
122 | })));
123 | }
124 |
125 | function zoom_off(id){
126 | var elt = d3.select('#' + id );
127 | var zoom_ = window["zoom_" + id];
128 | elt.call(zoom_.on("zoom", null));
129 | }
130 |
131 | function zoom_identity(id){
132 | var zoom_ = window["zoom_" + id];
133 | var elt = d3.select('#' + id );
134 | elt.call(zoom_.transform, d3.zoomIdentity);
135 | }
136 |
137 |
138 |
139 |
140 | function refresh_selected(sel_array_name, selected_class, id){
141 |
142 | var widget_id = window["widget_" + id];
143 | var svg = d3.select('#' + widget_id +' svg');
144 | svg.selectAll('*[data-id]').classed(selected_class, false);
145 |
146 | var selid = window[sel_array_name];
147 | d3.selectAll(selid).each(function(d, i) {
148 | svg.selectAll('*[data-id=\"'+ selid[i] + '\"]').classed(selected_class, true);
149 | });
150 |
151 | }
152 |
153 | function select_data_id_single(selection, sel_array_name, selected_class, id, container_id ) {
154 |
155 | selection.on("click", function(d,i) {
156 |
157 | var dataid = d3.select(this).attr("data-id");
158 |
159 | if( window[sel_array_name][0] == dataid ){
160 | window[sel_array_name] = [];
161 | }
162 | else {
163 | window[sel_array_name] = [dataid];
164 | }
165 | refresh_selected(sel_array_name, selected_class, container_id);
166 | Shiny.onInputChange(id + "_selected", window[sel_array_name]);
167 | });
168 | }
169 |
170 | function select_data_id_multiple(selection, sel_array_name, selected_class, id, container_id) {
171 |
172 | selection.on("click", function(d,i) {
173 |
174 | var dataid = d3.select(this).attr("data-id");
175 | var index = window[sel_array_name].indexOf(dataid);
176 | if( index < 0 ){
177 | window[sel_array_name].push( dataid );
178 | } else {
179 | window[sel_array_name].splice(index,1);
180 | }
181 | refresh_selected(sel_array_name, selected_class, container_id);
182 | Shiny.onInputChange(id + "_selected", window[sel_array_name]);
183 | });
184 | }
185 |
186 |
187 | function tooltip_remove(id){
188 | var subid = d3.select('#' + id + " div" ).attr("id");
189 | d3.selectAll(".tooltip_" + subid ).remove();
190 | }
191 |
192 |
193 |
194 | HTMLWidgets.widget({
195 |
196 | name: "ggiraph",
197 |
198 | type: "output",
199 |
200 | factory: function(el, width, height) {
201 |
202 |
203 | return {
204 | renderValue: function(x) {
205 | window["widget_" + x.uid] = el.id;
206 | var div_htmlwidget = d3.select("#" + el.id );
207 |
208 | if( HTMLWidgets.shinyMode || x.flexdashboard ){
209 | div_htmlwidget.html(x.html);
210 | }
211 | else if( x.use_wh ){
212 | div_htmlwidget.html("" +
213 | x.html + "
");
214 | } else {
215 | div_htmlwidget.html("" +
216 | x.html + "
");
217 | }
218 |
219 |
220 | div_htmlwidget.style("width", null).style("height", null);
221 |
222 | var fun_ = window[x.funname];
223 | fun_();
224 | set_over_effect(el.id);
225 | set_highlight(x.uid);
226 | set_tooltip(x.uid, x.tooltip_opacity, x.tooltip_offx, x.tooltip_offy);
227 | if( HTMLWidgets.shinyMode ){
228 |
229 | set_selector(x.uid, x.sel_array_name, x.selected_class, x.selection_type, el.id);
230 | Shiny.addCustomMessageHandler(el.id+'_set',function(message) {
231 |
232 | var varname = el.id + '_selected';
233 | d3.selectAll('#' + el.id + ' svg *[data-id]').classed('clicked_'+x.uid, false);
234 | d3.selectAll(message).each(function(d, i) {
235 | d3.selectAll('#' + el.id + ' svg *[data-id="'+ message[i] + '"]').classed('clicked_'+x.uid, true);
236 | });
237 | window[x.sel_array_name] = message;
238 | Shiny.onInputChange(varname, window[x.sel_array_name]);
239 | });
240 |
241 | Shiny.addCustomMessageHandler(el.id+'_tooltip_remove',function(message) {
242 | tooltip_remove(message);
243 | });
244 |
245 |
246 | } else{
247 | d3.selectAll(".ggiraph-toolbar-block").filter(".shinyonly").remove();
248 | }
249 | resize(el.id, width, height);
250 | },
251 |
252 | resize: function(width, height) {
253 | resize(el.id, width, height);
254 | }
255 |
256 | };
257 | }
258 | });
--------------------------------------------------------------------------------
/Materials/libs/grViz-binding-0.9.0/grViz.js:
--------------------------------------------------------------------------------
1 | HTMLWidgets.widget({
2 |
3 | name: 'grViz',
4 |
5 | type: 'output',
6 |
7 | initialize: function(el, width, height) {
8 |
9 | return {
10 | // TODO: add instance fields as required
11 | }
12 |
13 | },
14 |
15 | renderValue: function(el, x, instance) {
16 | // use this to sort of make our diagram responsive
17 | // or at a minimum fit within the bounds set by htmlwidgets
18 | // for the parent container
19 | function makeResponsive(el){
20 | var svg = el.getElementsByTagName("svg")[0];
21 | if(svg){
22 | if(svg.width) {svg.removeAttribute("width")};
23 | if(svg.height) {svg.removeAttribute("height")};
24 | svg.style.width = "100%";
25 | svg.style.height = "100%";
26 | }
27 | };
28 |
29 | if ( x.diagram != "" ) {
30 |
31 | if ( typeof x.config === "undefined" ){
32 | x.config = {};
33 | x.config.engine = "dot";
34 | x.config.options = {};
35 | }
36 |
37 | try {
38 | el.innerHTML = Viz( x.diagram, format="svg", engine=x.config.engine, options=x.config.options );
39 |
40 | makeResponsive(el);
41 |
42 | // set up a container for tasks to perform after completion
43 | // one example would be add callbacks for event handling
44 | // styling
45 | if (!(typeof x.tasks === "undefined") ){
46 | if ( (typeof x.tasks.length === "undefined") ||
47 | (typeof x.tasks === "function" ) ) {
48 | // handle a function not enclosed in array
49 | // should be able to remove once using jsonlite
50 | x.tasks = [x.tasks];
51 | }
52 | x.tasks.map(function(t){
53 | // for each tasks add it to the mermaid.tasks with el
54 | t.call(el);
55 | })
56 | }
57 | } catch(e){
58 | var p = document.createElement("pre")
59 | p.innerText = e;
60 | el.appendChild(p);
61 | }
62 | }
63 |
64 | },
65 |
66 | resize: function(el, width, height, instance) {
67 |
68 | }
69 |
70 |
71 | });
72 |
--------------------------------------------------------------------------------
/Materials/libs/grViz-binding-0.9.2/grViz.js:
--------------------------------------------------------------------------------
1 | HTMLWidgets.widget({
2 |
3 | name: 'grViz',
4 |
5 | type: 'output',
6 |
7 | initialize: function(el, width, height) {
8 |
9 | return {
10 | // TODO: add instance fields as required
11 | }
12 |
13 | },
14 |
15 | renderValue: function(el, x, instance) {
16 | // use this to sort of make our diagram responsive
17 | // or at a minimum fit within the bounds set by htmlwidgets
18 | // for the parent container
19 | function makeResponsive(el){
20 | var svg = el.getElementsByTagName("svg")[0];
21 | if(svg){
22 | if(svg.width) {svg.removeAttribute("width")};
23 | if(svg.height) {svg.removeAttribute("height")};
24 | svg.style.width = "100%";
25 | svg.style.height = "100%";
26 | }
27 | };
28 |
29 | if ( x.diagram != "" ) {
30 |
31 | if ( typeof x.config === "undefined" ){
32 | x.config = {};
33 | x.config.engine = "dot";
34 | x.config.options = {};
35 | }
36 |
37 | try {
38 | el.innerHTML = Viz( x.diagram, format="svg", engine=x.config.engine, options=x.config.options );
39 |
40 | makeResponsive(el);
41 |
42 | // set up a container for tasks to perform after completion
43 | // one example would be add callbacks for event handling
44 | // styling
45 | if (!(typeof x.tasks === "undefined") ){
46 | if ( (typeof x.tasks.length === "undefined") ||
47 | (typeof x.tasks === "function" ) ) {
48 | // handle a function not enclosed in array
49 | // should be able to remove once using jsonlite
50 | x.tasks = [x.tasks];
51 | }
52 | x.tasks.map(function(t){
53 | // for each tasks add it to the mermaid.tasks with el
54 | t.call(el);
55 | })
56 | }
57 | } catch(e){
58 | var p = document.createElement("pre")
59 | p.innerText = e;
60 | el.appendChild(p);
61 | }
62 | }
63 |
64 | },
65 |
66 | resize: function(el, width, height, instance) {
67 |
68 | }
69 |
70 |
71 | });
72 |
--------------------------------------------------------------------------------
/Materials/libs/leaflet-0.7.7/images/1px.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/libs/leaflet-0.7.7/images/1px.png
--------------------------------------------------------------------------------
/Materials/libs/leaflet-0.7.7/images/layers-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/libs/leaflet-0.7.7/images/layers-2x.png
--------------------------------------------------------------------------------
/Materials/libs/leaflet-0.7.7/images/layers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/libs/leaflet-0.7.7/images/layers.png
--------------------------------------------------------------------------------
/Materials/libs/leaflet-0.7.7/images/marker-icon-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/libs/leaflet-0.7.7/images/marker-icon-2x.png
--------------------------------------------------------------------------------
/Materials/libs/leaflet-0.7.7/images/marker-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/libs/leaflet-0.7.7/images/marker-icon.png
--------------------------------------------------------------------------------
/Materials/libs/leaflet-0.7.7/images/marker-shadow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/libs/leaflet-0.7.7/images/marker-shadow.png
--------------------------------------------------------------------------------
/Materials/libs/leaflet-0.7.7/leaflet.css:
--------------------------------------------------------------------------------
1 | /* required styles */
2 |
3 | .leaflet-map-pane,
4 | .leaflet-tile,
5 | .leaflet-marker-icon,
6 | .leaflet-marker-shadow,
7 | .leaflet-tile-pane,
8 | .leaflet-tile-container,
9 | .leaflet-overlay-pane,
10 | .leaflet-shadow-pane,
11 | .leaflet-marker-pane,
12 | .leaflet-popup-pane,
13 | .leaflet-overlay-pane svg,
14 | .leaflet-zoom-box,
15 | .leaflet-image-layer,
16 | .leaflet-layer {
17 | position: absolute;
18 | left: 0;
19 | top: 0;
20 | }
21 | .leaflet-container {
22 | overflow: hidden;
23 | -ms-touch-action: none;
24 | touch-action: none;
25 | }
26 | .leaflet-tile,
27 | .leaflet-marker-icon,
28 | .leaflet-marker-shadow {
29 | -webkit-user-select: none;
30 | -moz-user-select: none;
31 | user-select: none;
32 | -webkit-user-drag: none;
33 | }
34 | .leaflet-marker-icon,
35 | .leaflet-marker-shadow {
36 | display: block;
37 | }
38 | /* map is broken in FF if you have max-width: 100% on tiles */
39 | .leaflet-container img {
40 | max-width: none !important;
41 | }
42 | /* stupid Android 2 doesn't understand "max-width: none" properly */
43 | .leaflet-container img.leaflet-image-layer {
44 | max-width: 15000px !important;
45 | }
46 | .leaflet-tile {
47 | filter: inherit;
48 | visibility: hidden;
49 | }
50 | .leaflet-tile-loaded {
51 | visibility: inherit;
52 | }
53 | .leaflet-zoom-box {
54 | width: 0;
55 | height: 0;
56 | }
57 | /* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
58 | .leaflet-overlay-pane svg {
59 | -moz-user-select: none;
60 | }
61 |
62 | .leaflet-tile-pane { z-index: 2; }
63 | .leaflet-objects-pane { z-index: 3; }
64 | .leaflet-overlay-pane { z-index: 4; }
65 | .leaflet-shadow-pane { z-index: 5; }
66 | .leaflet-marker-pane { z-index: 6; }
67 | .leaflet-popup-pane { z-index: 7; }
68 |
69 | .leaflet-vml-shape {
70 | width: 1px;
71 | height: 1px;
72 | }
73 | .lvml {
74 | behavior: url(#default#VML);
75 | display: inline-block;
76 | position: absolute;
77 | }
78 |
79 |
80 | /* control positioning */
81 |
82 | .leaflet-control {
83 | position: relative;
84 | z-index: 7;
85 | pointer-events: auto;
86 | }
87 | .leaflet-top,
88 | .leaflet-bottom {
89 | position: absolute;
90 | z-index: 1000;
91 | pointer-events: none;
92 | }
93 | .leaflet-top {
94 | top: 0;
95 | }
96 | .leaflet-right {
97 | right: 0;
98 | }
99 | .leaflet-bottom {
100 | bottom: 0;
101 | }
102 | .leaflet-left {
103 | left: 0;
104 | }
105 | .leaflet-control {
106 | float: left;
107 | clear: both;
108 | }
109 | .leaflet-right .leaflet-control {
110 | float: right;
111 | }
112 | .leaflet-top .leaflet-control {
113 | margin-top: 10px;
114 | }
115 | .leaflet-bottom .leaflet-control {
116 | margin-bottom: 10px;
117 | }
118 | .leaflet-left .leaflet-control {
119 | margin-left: 10px;
120 | }
121 | .leaflet-right .leaflet-control {
122 | margin-right: 10px;
123 | }
124 |
125 |
126 | /* zoom and fade animations */
127 |
128 | .leaflet-fade-anim .leaflet-tile,
129 | .leaflet-fade-anim .leaflet-popup {
130 | opacity: 0;
131 | -webkit-transition: opacity 0.2s linear;
132 | -moz-transition: opacity 0.2s linear;
133 | -o-transition: opacity 0.2s linear;
134 | transition: opacity 0.2s linear;
135 | }
136 | .leaflet-fade-anim .leaflet-tile-loaded,
137 | .leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
138 | opacity: 1;
139 | }
140 |
141 | .leaflet-zoom-anim .leaflet-zoom-animated {
142 | -webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
143 | -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
144 | -o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1);
145 | transition: transform 0.25s cubic-bezier(0,0,0.25,1);
146 | }
147 | .leaflet-zoom-anim .leaflet-tile,
148 | .leaflet-pan-anim .leaflet-tile,
149 | .leaflet-touching .leaflet-zoom-animated {
150 | -webkit-transition: none;
151 | -moz-transition: none;
152 | -o-transition: none;
153 | transition: none;
154 | }
155 |
156 | .leaflet-zoom-anim .leaflet-zoom-hide {
157 | visibility: hidden;
158 | }
159 |
160 |
161 | /* cursors */
162 |
163 | .leaflet-clickable {
164 | cursor: pointer;
165 | }
166 | .leaflet-container {
167 | cursor: -webkit-grab;
168 | cursor: -moz-grab;
169 | }
170 | .leaflet-popup-pane,
171 | .leaflet-control {
172 | cursor: auto;
173 | }
174 | .leaflet-dragging .leaflet-container,
175 | .leaflet-dragging .leaflet-clickable {
176 | cursor: move;
177 | cursor: -webkit-grabbing;
178 | cursor: -moz-grabbing;
179 | }
180 |
181 |
182 | /* visual tweaks */
183 |
184 | .leaflet-container {
185 | background: #ddd;
186 | outline: 0;
187 | }
188 | .leaflet-container a {
189 | color: #0078A8;
190 | }
191 | .leaflet-container a.leaflet-active {
192 | outline: 2px solid orange;
193 | }
194 | .leaflet-zoom-box {
195 | border: 2px dotted #38f;
196 | background: rgba(255,255,255,0.5);
197 | }
198 |
199 |
200 | /* general typography */
201 | .leaflet-container {
202 | font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
203 | }
204 |
205 |
206 | /* general toolbar styles */
207 |
208 | .leaflet-bar {
209 | box-shadow: 0 1px 5px rgba(0,0,0,0.65);
210 | border-radius: 4px;
211 | }
212 | .leaflet-bar a,
213 | .leaflet-bar a:hover {
214 | background-color: #fff;
215 | border-bottom: 1px solid #ccc;
216 | width: 26px;
217 | height: 26px;
218 | line-height: 26px;
219 | display: block;
220 | text-align: center;
221 | text-decoration: none;
222 | color: black;
223 | }
224 | .leaflet-bar a,
225 | .leaflet-control-layers-toggle {
226 | background-position: 50% 50%;
227 | background-repeat: no-repeat;
228 | display: block;
229 | }
230 | .leaflet-bar a:hover {
231 | background-color: #f4f4f4;
232 | }
233 | .leaflet-bar a:first-child {
234 | border-top-left-radius: 4px;
235 | border-top-right-radius: 4px;
236 | }
237 | .leaflet-bar a:last-child {
238 | border-bottom-left-radius: 4px;
239 | border-bottom-right-radius: 4px;
240 | border-bottom: none;
241 | }
242 | .leaflet-bar a.leaflet-disabled {
243 | cursor: default;
244 | background-color: #f4f4f4;
245 | color: #bbb;
246 | }
247 |
248 | .leaflet-touch .leaflet-bar a {
249 | width: 30px;
250 | height: 30px;
251 | line-height: 30px;
252 | }
253 |
254 |
255 | /* zoom control */
256 |
257 | .leaflet-control-zoom-in,
258 | .leaflet-control-zoom-out {
259 | font: bold 18px 'Lucida Console', Monaco, monospace;
260 | text-indent: 1px;
261 | }
262 | .leaflet-control-zoom-out {
263 | font-size: 20px;
264 | }
265 |
266 | .leaflet-touch .leaflet-control-zoom-in {
267 | font-size: 22px;
268 | }
269 | .leaflet-touch .leaflet-control-zoom-out {
270 | font-size: 24px;
271 | }
272 |
273 |
274 | /* layers control */
275 |
276 | .leaflet-control-layers {
277 | box-shadow: 0 1px 5px rgba(0,0,0,0.4);
278 | background: #fff;
279 | border-radius: 5px;
280 | }
281 | .leaflet-control-layers-toggle {
282 | background-image: url(images/layers.png);
283 | width: 36px;
284 | height: 36px;
285 | }
286 | .leaflet-retina .leaflet-control-layers-toggle {
287 | background-image: url(images/layers-2x.png);
288 | background-size: 26px 26px;
289 | }
290 | .leaflet-touch .leaflet-control-layers-toggle {
291 | width: 44px;
292 | height: 44px;
293 | }
294 | .leaflet-control-layers .leaflet-control-layers-list,
295 | .leaflet-control-layers-expanded .leaflet-control-layers-toggle {
296 | display: none;
297 | }
298 | .leaflet-control-layers-expanded .leaflet-control-layers-list {
299 | display: block;
300 | position: relative;
301 | }
302 | .leaflet-control-layers-expanded {
303 | padding: 6px 10px 6px 6px;
304 | color: #333;
305 | background: #fff;
306 | }
307 | .leaflet-control-layers-selector {
308 | margin-top: 2px;
309 | position: relative;
310 | top: 1px;
311 | }
312 | .leaflet-control-layers label {
313 | display: block;
314 | }
315 | .leaflet-control-layers-separator {
316 | height: 0;
317 | border-top: 1px solid #ddd;
318 | margin: 5px -10px 5px -6px;
319 | }
320 |
321 |
322 | /* attribution and scale controls */
323 |
324 | .leaflet-container .leaflet-control-attribution {
325 | background: #fff;
326 | background: rgba(255, 255, 255, 0.7);
327 | margin: 0;
328 | }
329 | .leaflet-control-attribution,
330 | .leaflet-control-scale-line {
331 | padding: 0 5px;
332 | color: #333;
333 | }
334 | .leaflet-control-attribution a {
335 | text-decoration: none;
336 | }
337 | .leaflet-control-attribution a:hover {
338 | text-decoration: underline;
339 | }
340 | .leaflet-container .leaflet-control-attribution,
341 | .leaflet-container .leaflet-control-scale {
342 | font-size: 11px;
343 | }
344 | .leaflet-left .leaflet-control-scale {
345 | margin-left: 5px;
346 | }
347 | .leaflet-bottom .leaflet-control-scale {
348 | margin-bottom: 5px;
349 | }
350 | .leaflet-control-scale-line {
351 | border: 2px solid #777;
352 | border-top: none;
353 | line-height: 1.1;
354 | padding: 2px 5px 1px;
355 | font-size: 11px;
356 | white-space: nowrap;
357 | overflow: hidden;
358 | -moz-box-sizing: content-box;
359 | box-sizing: content-box;
360 |
361 | background: #fff;
362 | background: rgba(255, 255, 255, 0.5);
363 | }
364 | .leaflet-control-scale-line:not(:first-child) {
365 | border-top: 2px solid #777;
366 | border-bottom: none;
367 | margin-top: -2px;
368 | }
369 | .leaflet-control-scale-line:not(:first-child):not(:last-child) {
370 | border-bottom: 2px solid #777;
371 | }
372 |
373 | .leaflet-touch .leaflet-control-attribution,
374 | .leaflet-touch .leaflet-control-layers,
375 | .leaflet-touch .leaflet-bar {
376 | box-shadow: none;
377 | }
378 | .leaflet-touch .leaflet-control-layers,
379 | .leaflet-touch .leaflet-bar {
380 | border: 2px solid rgba(0,0,0,0.2);
381 | background-clip: padding-box;
382 | }
383 |
384 |
385 | /* popup */
386 |
387 | .leaflet-popup {
388 | position: absolute;
389 | text-align: center;
390 | }
391 | .leaflet-popup-content-wrapper {
392 | padding: 1px;
393 | text-align: left;
394 | border-radius: 12px;
395 | }
396 | .leaflet-popup-content {
397 | margin: 13px 19px;
398 | line-height: 1.4;
399 | }
400 | .leaflet-popup-content p {
401 | margin: 18px 0;
402 | }
403 | .leaflet-popup-tip-container {
404 | margin: 0 auto;
405 | width: 40px;
406 | height: 20px;
407 | position: relative;
408 | overflow: hidden;
409 | }
410 | .leaflet-popup-tip {
411 | width: 17px;
412 | height: 17px;
413 | padding: 1px;
414 |
415 | margin: -10px auto 0;
416 |
417 | -webkit-transform: rotate(45deg);
418 | -moz-transform: rotate(45deg);
419 | -ms-transform: rotate(45deg);
420 | -o-transform: rotate(45deg);
421 | transform: rotate(45deg);
422 | }
423 | .leaflet-popup-content-wrapper,
424 | .leaflet-popup-tip {
425 | background: white;
426 |
427 | box-shadow: 0 3px 14px rgba(0,0,0,0.4);
428 | }
429 | .leaflet-container a.leaflet-popup-close-button {
430 | position: absolute;
431 | top: 0;
432 | right: 0;
433 | padding: 4px 4px 0 0;
434 | text-align: center;
435 | width: 18px;
436 | height: 14px;
437 | font: 16px/14px Tahoma, Verdana, sans-serif;
438 | color: #c3c3c3;
439 | text-decoration: none;
440 | font-weight: bold;
441 | background: transparent;
442 | }
443 | .leaflet-container a.leaflet-popup-close-button:hover {
444 | color: #999;
445 | }
446 | .leaflet-popup-scrolled {
447 | overflow: auto;
448 | border-bottom: 1px solid #ddd;
449 | border-top: 1px solid #ddd;
450 | }
451 |
452 | .leaflet-oldie .leaflet-popup-content-wrapper {
453 | zoom: 1;
454 | }
455 | .leaflet-oldie .leaflet-popup-tip {
456 | width: 24px;
457 | margin: 0 auto;
458 |
459 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
460 | filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
461 | }
462 | .leaflet-oldie .leaflet-popup-tip-container {
463 | margin-top: -1px;
464 | }
465 |
466 | .leaflet-oldie .leaflet-control-zoom,
467 | .leaflet-oldie .leaflet-control-layers,
468 | .leaflet-oldie .leaflet-popup-content-wrapper,
469 | .leaflet-oldie .leaflet-popup-tip {
470 | border: 1px solid #999;
471 | }
472 |
473 |
474 | /* div icon */
475 |
476 | .leaflet-div-icon {
477 | background: #fff;
478 | border: 1px solid #666;
479 | }
480 |
--------------------------------------------------------------------------------
/Materials/libs/leaflet-label-0.2.2/images/death.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/libs/leaflet-label-0.2.2/images/death.png
--------------------------------------------------------------------------------
/Materials/libs/leaflet-label-0.2.2/leaflet.label-src.js:
--------------------------------------------------------------------------------
1 | /*
2 | Leaflet.label, a plugin that adds labels to markers and vectors for Leaflet powered maps.
3 | (c) 2012-2013, Jacob Toye, Smartrak
4 |
5 | https://github.com/Leaflet/Leaflet.label
6 | http://leafletjs.com
7 | https://github.com/jacobtoye
8 | */
9 | (function (factory, window) {
10 |
11 | // define an AMD module that relies on 'leaflet'
12 | if (typeof define === 'function' && define.amd) {
13 | define(['leaflet'], factory);
14 |
15 | // define a Common JS module that relies on 'leaflet'
16 | } else if (typeof exports === 'object') {
17 | module.exports = factory(require('leaflet'));
18 | }
19 |
20 | // attach your plugin to the global 'L' variable
21 | if (typeof window !== 'undefined' && window.L) {
22 | window.LeafletLabel = factory(L);
23 | }
24 | }(function (L) {
25 | L.labelVersion = '0.2.4';
26 |
27 |
28 | var LeafletLabel = L.Class.extend({
29 |
30 | includes: L.Mixin.Events,
31 |
32 | _directions: [ 'top', 'right', 'bottom', 'left' ],
33 |
34 | options: {
35 | className: '',
36 | clickable: false,
37 | direction: 'right',
38 | noHide: false,
39 | offset: [12, -15], // 6 (width of the label triangle) + 6 (padding)
40 | opacity: 1,
41 | textsize: "10px",
42 | textOnly: false,
43 | style: null,
44 | zoomAnimation: true
45 | },
46 |
47 | initialize: function (options, source) {
48 | L.setOptions(this, options);
49 |
50 | this._source = source;
51 | this._animated = L.Browser.any3d && this.options.zoomAnimation;
52 | this._isOpen = false;
53 | },
54 |
55 | _isOnMarker: function () {
56 | return this._source instanceof L.Marker;
57 | },
58 |
59 | onAdd: function (map) {
60 | this._map = map;
61 |
62 | this._pane = this.options.pane ? map._panes[this.options.pane] :
63 | this._isOnMarker() ? map._panes.markerPane : map._panes.popupPane;
64 |
65 | if (!this._container) {
66 | this._initLayout();
67 | }
68 |
69 | this._pane.appendChild(this._container);
70 |
71 | this._initInteraction();
72 |
73 | this._update();
74 |
75 | this.setOpacity(this.options.opacity);
76 |
77 | map
78 | .on('moveend', this._onMoveEnd, this)
79 | .on('viewreset', this._onViewReset, this);
80 |
81 | if (this._animated) {
82 | map.on('zoomanim', this._zoomAnimation, this);
83 | }
84 |
85 | if (L.Browser.touch && !this.options.noHide) {
86 | L.DomEvent.on(this._container, 'click', this.close, this);
87 | map.on('click', this.close, this);
88 | }
89 | },
90 |
91 | onRemove: function (map) {
92 | this._pane.removeChild(this._container);
93 |
94 | map.off({
95 | zoomanim: this._zoomAnimation,
96 | moveend: this._onMoveEnd,
97 | viewreset: this._onViewReset
98 | }, this);
99 |
100 | this._removeInteraction();
101 |
102 | this._map = null;
103 | },
104 |
105 | setLatLng: function (latlng) {
106 | this._latlng = L.latLng(latlng);
107 | if (this._map) {
108 | this._updatePosition();
109 | }
110 | return this;
111 | },
112 |
113 | setContent: function (content) {
114 | // Backup previous content and store new content
115 | this._previousContent = this._content;
116 | this._content = content;
117 |
118 | this._updateContent();
119 |
120 | return this;
121 | },
122 |
123 | close: function () {
124 | var map = this._map;
125 |
126 | if (map) {
127 | if (L.Browser.touch && !this.options.noHide) {
128 | L.DomEvent.off(this._container, 'click', this.close);
129 | map.off('click', this.close, this);
130 | }
131 |
132 | map.removeLayer(this);
133 | }
134 | },
135 |
136 | updateZIndex: function (zIndex) {
137 | this._zIndex = zIndex;
138 |
139 | if (this._container && this._zIndex) {
140 | this._container.style.zIndex = zIndex;
141 | }
142 | },
143 |
144 | setOpacity: function (opacity) {
145 | this.options.opacity = opacity;
146 |
147 | if (this._container) {
148 | L.DomUtil.setOpacity(this._container, opacity);
149 | }
150 | },
151 |
152 | _initLayout: function () {
153 | this._container = L.DomUtil.create('div', 'leaflet-label ' + this.options.className + ' leaflet-zoom-animated');
154 | this._container.style.fontSize = this.options.textsize;
155 | if (this.options.textOnly) { L.DomUtil.addClass(this._container, 'leaflet-label-text-only'); }
156 | if (this.options.style) {
157 | for (var property in this.options.style) {
158 | if (this.options.style.hasOwnProperty(property)) {
159 | this._container.style[property] = this.options.style[property];
160 | }
161 | }
162 | }
163 | this.updateZIndex(this._zIndex);
164 | },
165 |
166 | _update: function () {
167 | if (!this._map) { return; }
168 |
169 | this._container.style.visibility = 'hidden';
170 |
171 | this._updateContent();
172 | this._updatePosition();
173 |
174 | this._container.style.visibility = '';
175 | },
176 |
177 | _updateContent: function () {
178 | if (!this._content || !this._map || this._prevContent === this._content) {
179 | return;
180 | }
181 |
182 | if (typeof this._content === 'string') {
183 | this._container.innerHTML = this._content;
184 |
185 | this._prevContent = this._content;
186 |
187 | this._labelWidth = this._container.offsetWidth;
188 | }
189 | },
190 |
191 | _updatePosition: function () {
192 | var pos = this._map.latLngToLayerPoint(this._latlng);
193 |
194 | this._setPosition(pos);
195 | },
196 |
197 | _getIconHeight: function () {
198 | return this._source.options.icon ? this._source.options.icon.options.iconSize[1] : 0;
199 | },
200 |
201 | _setPosition: function (pos) {
202 | var map = this._map,
203 | container = this._container,
204 | centerPoint = map.latLngToContainerPoint(map.getCenter()),
205 | labelPoint = map.layerPointToContainerPoint(pos),
206 | direction = this._getDirection(),
207 | labelWidth = this._labelWidth,
208 | offset = L.point(this.options.offset),
209 | verticalOffset = offset.y;
210 |
211 | if (direction === 'top') {
212 | verticalOffset -= this._isOnMarker() ? this._getIconHeight() : 0;
213 |
214 | pos = pos.add(L.point(-labelWidth / 2, verticalOffset));
215 | } else if (direction === 'bottom') {
216 | verticalOffset += this._isOnMarker ? this._getIconHeight() : 0;
217 |
218 | pos = pos.add(L.point(-labelWidth / 2, verticalOffset));
219 | } else if (direction === 'right' || direction === 'auto' && labelPoint.x < centerPoint.x) {
220 | direction = 'right';
221 | pos = pos.add(offset);
222 | } else {
223 | direction = 'left';
224 | pos = pos.add(L.point(-offset.x - labelWidth, offset.y));
225 | }
226 |
227 | this._setProperClass(pos, direction);
228 | L.DomUtil.setPosition(container, pos);
229 | },
230 |
231 | _generateLabelClass: function (direction) {
232 | return 'leaflet-label-' + direction;
233 | },
234 |
235 | _setProperClass: function (pos, _direction) {
236 | var map = this._map,
237 | container = this._container,
238 | direction = _direction || this._getDirection(),
239 | labelPoint = map.layerPointToContainerPoint(pos),
240 | centerPoint = map.latLngToContainerPoint(map.getCenter()),
241 | classToAdd = this._generateLabelClass(direction);
242 |
243 | for (var i = 0; i < this._directions.length; i++) {
244 | var d = this._directions[i];
245 | if (d !== direction) {
246 | var classToRemove = this._generateLabelClass(d);
247 | L.DomUtil.removeClass(container, classToRemove);
248 | }
249 | }
250 |
251 | L.DomUtil.addClass(container, classToAdd);
252 | },
253 |
254 | _getDirection: function () {
255 | return this.options.direction;
256 | },
257 |
258 | _zoomAnimation: function (opt) {
259 | var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round();
260 |
261 | this._setPosition(pos);
262 | },
263 |
264 | _onMoveEnd: function () {
265 | if (!this._animated || this._getDirection() === 'auto') {
266 | this._updatePosition();
267 | }
268 | },
269 |
270 | _onViewReset: function (e) {
271 | /* if map resets hard, we must update the label */
272 | if (e && e.hard) {
273 | this._update();
274 | }
275 | },
276 |
277 | _initInteraction: function () {
278 | if (!this.options.clickable) { return; }
279 |
280 | var container = this._container,
281 | events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu'];
282 |
283 | L.DomUtil.addClass(container, 'leaflet-clickable');
284 | L.DomEvent.on(container, 'click', this._onMouseClick, this);
285 |
286 | for (var i = 0; i < events.length; i++) {
287 | L.DomEvent.on(container, events[i], this._fireMouseEvent, this);
288 | }
289 | },
290 |
291 | _removeInteraction: function () {
292 | if (!this.options.clickable) { return; }
293 |
294 | var container = this._container,
295 | events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu'];
296 |
297 | L.DomUtil.removeClass(container, 'leaflet-clickable');
298 | L.DomEvent.off(container, 'click', this._onMouseClick, this);
299 |
300 | for (var i = 0; i < events.length; i++) {
301 | L.DomEvent.off(container, events[i], this._fireMouseEvent, this);
302 | }
303 | },
304 |
305 | _onMouseClick: function (e) {
306 | if (this.hasEventListeners(e.type)) {
307 | L.DomEvent.stopPropagation(e);
308 | }
309 |
310 | this.fire(e.type, {
311 | originalEvent: e
312 | });
313 | },
314 |
315 | _fireMouseEvent: function (e) {
316 | this.fire(e.type, {
317 | originalEvent: e
318 | });
319 |
320 | // TODO proper custom event propagation
321 | // this line will always be called if marker is in a FeatureGroup
322 | if (e.type === 'contextmenu' && this.hasEventListeners(e.type)) {
323 | L.DomEvent.preventDefault(e);
324 | }
325 | if (e.type !== 'mousedown') {
326 | L.DomEvent.stopPropagation(e);
327 | } else {
328 | L.DomEvent.preventDefault(e);
329 | }
330 | }
331 | });
332 |
333 |
334 | /*global LeafletLabel */
335 |
336 | // This object is a mixin for L.Marker and L.CircleMarker. We declare it here as both need to include the contents.
337 | L.BaseMarkerMethods = {
338 | showLabel: function () {
339 | if (this.label && this._map) {
340 | this.label.setLatLng(this._latlng);
341 | this._map.showLabel(this.label);
342 | }
343 |
344 | return this;
345 | },
346 |
347 | hideLabel: function () {
348 | if (this.label) {
349 | this.label.close();
350 | }
351 | return this;
352 | },
353 |
354 | setLabelNoHide: function (noHide) {
355 | if (this._labelNoHide === noHide) {
356 | return;
357 | }
358 |
359 | this._labelNoHide = noHide;
360 |
361 | if (noHide) {
362 | this._removeLabelRevealHandlers();
363 | this.showLabel();
364 | } else {
365 | this._addLabelRevealHandlers();
366 | this.hideLabel();
367 | }
368 | },
369 |
370 | bindLabel: function (content, options) {
371 | var labelAnchor = this.options.icon ? this.options.icon.options.labelAnchor : this.options.labelAnchor,
372 | anchor = L.point(labelAnchor) || L.point(0, 0);
373 |
374 | anchor = anchor.add(LeafletLabel.prototype.options.offset);
375 |
376 | if (options && options.offset) {
377 | anchor = anchor.add(options.offset);
378 | }
379 |
380 | options = L.Util.extend({offset: anchor}, options);
381 |
382 | this._labelNoHide = options.noHide;
383 |
384 | if (!this.label) {
385 | if (!this._labelNoHide) {
386 | this._addLabelRevealHandlers();
387 | }
388 |
389 | this
390 | .on('remove', this.hideLabel, this)
391 | .on('move', this._moveLabel, this)
392 | .on('add', this._onMarkerAdd, this);
393 |
394 | this._hasLabelHandlers = true;
395 | }
396 |
397 | this.label = new LeafletLabel(options, this)
398 | .setContent(content);
399 |
400 | return this;
401 | },
402 |
403 | unbindLabel: function () {
404 | if (this.label) {
405 | this.hideLabel();
406 |
407 | this.label = null;
408 |
409 | if (this._hasLabelHandlers) {
410 | if (!this._labelNoHide) {
411 | this._removeLabelRevealHandlers();
412 | }
413 |
414 | this
415 | .off('remove', this.hideLabel, this)
416 | .off('move', this._moveLabel, this)
417 | .off('add', this._onMarkerAdd, this);
418 | }
419 |
420 | this._hasLabelHandlers = false;
421 | }
422 | return this;
423 | },
424 |
425 | updateLabelContent: function (content) {
426 | if (this.label) {
427 | this.label.setContent(content);
428 | }
429 | },
430 |
431 | getLabel: function () {
432 | return this.label;
433 | },
434 |
435 | _onMarkerAdd: function () {
436 | if (this._labelNoHide) {
437 | this.showLabel();
438 | }
439 | },
440 |
441 | _addLabelRevealHandlers: function () {
442 | this
443 | .on('mouseover', this.showLabel, this)
444 | .on('mouseout', this.hideLabel, this);
445 |
446 | if (L.Browser.touch) {
447 | this.on('click', this.showLabel, this);
448 | }
449 | },
450 |
451 | _removeLabelRevealHandlers: function () {
452 | this
453 | .off('mouseover', this.showLabel, this)
454 | .off('mouseout', this.hideLabel, this);
455 |
456 | if (L.Browser.touch) {
457 | this.off('click', this.showLabel, this);
458 | }
459 | },
460 |
461 | _moveLabel: function (e) {
462 | this.label.setLatLng(e.latlng);
463 | }
464 | };
465 |
466 |
467 | // Add in an option to icon that is used to set where the label anchor is
468 | L.Icon.Default.mergeOptions({
469 | labelAnchor: new L.Point(9, -20)
470 | });
471 |
472 | // Have to do this since Leaflet is loaded before this plugin and initializes
473 | // L.Marker.options.icon therefore missing our mixin above.
474 | L.Marker.mergeOptions({
475 | icon: new L.Icon.Default()
476 | });
477 |
478 | L.Marker.include(L.BaseMarkerMethods);
479 | L.Marker.include({
480 | _originalUpdateZIndex: L.Marker.prototype._updateZIndex,
481 |
482 | _updateZIndex: function (offset) {
483 | var zIndex = this._zIndex + offset;
484 |
485 | this._originalUpdateZIndex(offset);
486 |
487 | if (this.label) {
488 | this.label.updateZIndex(zIndex);
489 | }
490 | },
491 |
492 | _originalSetOpacity: L.Marker.prototype.setOpacity,
493 |
494 | setOpacity: function (opacity, labelHasSemiTransparency) {
495 | this.options.labelHasSemiTransparency = labelHasSemiTransparency;
496 |
497 | this._originalSetOpacity(opacity);
498 | },
499 |
500 | _originalUpdateOpacity: L.Marker.prototype._updateOpacity,
501 |
502 | _updateOpacity: function () {
503 | var absoluteOpacity = this.options.opacity === 0 ? 0 : 1;
504 |
505 | this._originalUpdateOpacity();
506 |
507 | if (this.label) {
508 | this.label.setOpacity(this.options.labelHasSemiTransparency ? this.options.opacity : absoluteOpacity);
509 | }
510 | },
511 |
512 | _originalSetLatLng: L.Marker.prototype.setLatLng,
513 |
514 | setLatLng: function (latlng) {
515 | if (this.label && !this._labelNoHide) {
516 | this.hideLabel();
517 | }
518 |
519 | return this._originalSetLatLng(latlng);
520 | }
521 | });
522 |
523 | // Add in an option to icon that is used to set where the label anchor is
524 | L.CircleMarker.mergeOptions({
525 | labelAnchor: new L.Point(0, 0)
526 | });
527 |
528 |
529 | L.CircleMarker.include(L.BaseMarkerMethods);
530 |
531 | /*global LeafletLabel */
532 |
533 | L.Path.include({
534 | bindLabel: function (content, options) {
535 | if (!this.label || this.label.options !== options) {
536 | this.label = new LeafletLabel(options, this);
537 | }
538 |
539 | this.label.setContent(content);
540 |
541 | if (!this._showLabelAdded) {
542 | this
543 | .on('mouseover', this._showLabel, this)
544 | .on('mousemove', this._moveLabel, this)
545 | .on('mouseout remove', this._hideLabel, this);
546 |
547 | if (L.Browser.touch) {
548 | this.on('click', this._showLabel, this);
549 | }
550 | this._showLabelAdded = true;
551 | }
552 |
553 | return this;
554 | },
555 |
556 | unbindLabel: function () {
557 | if (this.label) {
558 | this._hideLabel();
559 | this.label = null;
560 | this._showLabelAdded = false;
561 | this
562 | .off('mouseover', this._showLabel, this)
563 | .off('mousemove', this._moveLabel, this)
564 | .off('mouseout remove', this._hideLabel, this);
565 | }
566 | return this;
567 | },
568 |
569 | updateLabelContent: function (content) {
570 | if (this.label) {
571 | this.label.setContent(content);
572 | }
573 | },
574 |
575 | _showLabel: function (e) {
576 | this.label.setLatLng(e.latlng);
577 | this._map.showLabel(this.label);
578 | },
579 |
580 | _moveLabel: function (e) {
581 | this.label.setLatLng(e.latlng);
582 | },
583 |
584 | _hideLabel: function () {
585 | this.label.close();
586 | }
587 | });
588 |
589 |
590 | L.Map.include({
591 | showLabel: function (label) {
592 | return this.addLayer(label);
593 | }
594 | });
595 |
596 | L.FeatureGroup.include({
597 | // TODO: remove this when AOP is supported in Leaflet, need this as we cannot put code in removeLayer()
598 | clearLayers: function () {
599 | this.unbindLabel();
600 | this.eachLayer(this.removeLayer, this);
601 | return this;
602 | },
603 |
604 | bindLabel: function (content, options) {
605 | return this.invoke('bindLabel', content, options);
606 | },
607 |
608 | unbindLabel: function () {
609 | //return this.invoke('unbindLabel');
610 | return this.invoke('hideLabel');
611 | },
612 |
613 | updateLabelContent: function (content) {
614 | this.invoke('updateLabelContent', content);
615 | }
616 | });
617 |
618 |
619 | return LeafletLabel;
620 | }, window));
621 |
--------------------------------------------------------------------------------
/Materials/libs/leaflet-label-0.2.2/leaflet.label.css:
--------------------------------------------------------------------------------
1 | .leaflet-label {
2 | background: rgb(235, 235, 235);
3 | background: rgba(235, 235, 235, 0.81);
4 | background-clip: padding-box;
5 | border-color: #777;
6 | border-color: rgba(0,0,0,0.45);
7 | border-radius: 4px;
8 | border-style: solid;
9 | border-width: 4px;
10 | color: #111;
11 | display: block;
12 | font: 12px/20px "Helvetica Neue", Arial, Helvetica, sans-serif;
13 | font-weight: bold;
14 | padding: 1px 6px;
15 | position: absolute;
16 | -webkit-user-select: none;
17 | -moz-user-select: none;
18 | -ms-user-select: none;
19 | user-select: none;
20 | pointer-events: none;
21 | white-space: nowrap;
22 | z-index: 500;
23 | }
24 |
25 | .leaflet-label.leaflet-clickable {
26 | cursor: pointer;
27 | pointer-events: auto;
28 | }
29 |
30 | .leaflet-label:before,
31 | .leaflet-label:after {
32 | border-top: 6px solid transparent;
33 | border-bottom: 6px solid transparent;
34 | border-right: 6px solid transparent;
35 | content: none;
36 | position: absolute;
37 | top: 5px;
38 | }
39 |
40 | .leaflet-label:before {
41 | border-right: 6px solid black;
42 | border-right-color: inherit;
43 | left: -10px;
44 | }
45 |
46 | .leaflet-label:after {
47 | border-left: 6px solid black;
48 | border-left-color: inherit;
49 | right: -16px;
50 | }
51 |
52 | .leaflet-label-top:after,
53 | .leaflet-label-top:before {
54 | left: -50%;
55 | border-top-color: black;
56 | border-top-color: rgba(0,0,0,0.45);
57 | position: relative;
58 | top: 29px;
59 | }
60 |
61 | .leaflet-label-top:before {
62 | display: none;
63 | border-right-color: transparent;
64 | border-bottom-color: transparent;
65 | border-left-color: transparent;
66 | border-top-color: transparent;
67 | }
68 |
69 | .leaflet-label-top:after {
70 | content: ' ';
71 | border-right-color: transparent;
72 | border-bottom-color: transparent;
73 | border-left-color: transparent;
74 | }
75 |
76 | .leaflet-label-bottom:before {
77 | display: none;
78 | border-right-color: transparent;
79 | border-bottom-color: transparent;
80 | border-left-color: transparent;
81 | border-top-color: transparent;
82 | }
83 |
84 | .leaflet-label-bottom:after,
85 | .leaflet-label-bottom:before {
86 | left: -50%;
87 | border-bottom-color: black;
88 | border-bottom-color: rgba(0,0,0,0.45);
89 | position: relative;
90 | top: -28px;
91 | }
92 |
93 | .leaflet-label-bottom:after {
94 | border-right-color: transparent;
95 | border-top-color: transparent;
96 | border-left-color: transparent;
97 | }
98 |
99 | .leaflet-label-bottom:after,
100 | .leaflet-label-top:after,
101 | .leaflet-label-right:before,
102 | .leaflet-label-left:after {
103 | content: "";
104 | }
105 |
106 | .leaflet-label.leaflet-label-text-only,
107 | .leaflet-label.leaflet-label-text-only:before,
108 | .leaflet-label.leaflet-label-text-only:after {
109 | background: none;
110 | border: none;
111 | }
112 |
113 | .leaflet-label.leaflet-label-text-only.leaflet-label-left {
114 | margin-right: -10px;
115 | }
116 |
117 | .leaflet-label.leaflet-label-text-only.leaflet-label-right {
118 | margin-left: -10px;
119 | }
120 |
--------------------------------------------------------------------------------
/Materials/libs/leaflet-label-0.2.2/leaflet.label.js:
--------------------------------------------------------------------------------
1 | /*
2 | Leaflet.label, a plugin that adds labels to markers and vectors for Leaflet powered maps.
3 | (c) 2012-2013, Jacob Toye, Smartrak
4 |
5 | https://github.com/Leaflet/Leaflet.label
6 | http://leafletjs.com
7 | https://github.com/jacobtoye
8 | */
9 | !function(t,e){"function"==typeof define&&define.amd?define(["leaflet"],t):"object"==typeof exports&&(module.exports=t(require("leaflet"))),"undefined"!=typeof e&&e.L&&(e.LeafletLabel=t(L))}(function(t){t.labelVersion="0.2.4";var e=t.Class.extend({includes:t.Mixin.Events,_directions:["top","right","bottom","left"],options:{className:"",clickable:!1,direction:"right",noHide:!1,offset:[12,-15],opacity:1,textsize:"10px",textOnly:!1,style:null,zoomAnimation:!0},initialize:function(e,i){t.setOptions(this,e),this._source=i,this._animated=t.Browser.any3d&&this.options.zoomAnimation,this._isOpen=!1},_isOnMarker:function(){return this._source instanceof t.Marker},onAdd:function(e){this._map=e,this._pane=this.options.pane?e._panes[this.options.pane]:this._isOnMarker()?e._panes.markerPane:e._panes.popupPane,this._container||this._initLayout(),this._pane.appendChild(this._container),this._initInteraction(),this._update(),this.setOpacity(this.options.opacity),e.on("moveend",this._onMoveEnd,this).on("viewreset",this._onViewReset,this),this._animated&&e.on("zoomanim",this._zoomAnimation,this),t.Browser.touch&&!this.options.noHide&&(t.DomEvent.on(this._container,"click",this.close,this),e.on("click",this.close,this))},onRemove:function(t){this._pane.removeChild(this._container),t.off({zoomanim:this._zoomAnimation,moveend:this._onMoveEnd,viewreset:this._onViewReset},this),this._removeInteraction(),this._map=null},setLatLng:function(e){return this._latlng=t.latLng(e),this._map&&this._updatePosition(),this},setContent:function(t){return this._previousContent=this._content,this._content=t,this._updateContent(),this},close:function(){var e=this._map;e&&(t.Browser.touch&&!this.options.noHide&&(t.DomEvent.off(this._container,"click",this.close),e.off("click",this.close,this)),e.removeLayer(this))},updateZIndex:function(t){this._zIndex=t,this._container&&this._zIndex&&(this._container.style.zIndex=t)},setOpacity:function(e){this.options.opacity=e,this._container&&t.DomUtil.setOpacity(this._container,e)},_initLayout:function(){if(this._container=t.DomUtil.create("div","leaflet-label "+this.options.className+" leaflet-zoom-animated"),this._container.style.fontSize=this.options.textsize,this.options.textOnly&&t.DomUtil.addClass(this._container,"leaflet-label-text-only"),this.options.style)for(var e in this.options.style)this.options.style.hasOwnProperty(e)&&(this._container.style[e]=this.options.style[e]);this.updateZIndex(this._zIndex)},_update:function(){this._map&&(this._container.style.visibility="hidden",this._updateContent(),this._updatePosition(),this._container.style.visibility="")},_updateContent:function(){this._content&&this._map&&this._prevContent!==this._content&&"string"==typeof this._content&&(this._container.innerHTML=this._content,this._prevContent=this._content,this._labelWidth=this._container.offsetWidth)},_updatePosition:function(){var t=this._map.latLngToLayerPoint(this._latlng);this._setPosition(t)},_getIconHeight:function(){return this._source.options.icon?this._source.options.icon.options.iconSize[1]:0},_setPosition:function(e){var i=this._map,n=this._container,o=i.latLngToContainerPoint(i.getCenter()),s=i.layerPointToContainerPoint(e),a=this._getDirection(),h=this._labelWidth,l=t.point(this.options.offset),r=l.y;"top"===a?(r-=this._isOnMarker()?this._getIconHeight():0,e=e.add(t.point(-h/2,r))):"bottom"===a?(r+=this._isOnMarker?this._getIconHeight():0,e=e.add(t.point(-h/2,r))):"right"===a||"auto"===a&&s.x[1](#what-is-free) tile providers.
4 |
5 | # Usage
6 | Leaflet-providers [providers](#providers) are refered to with a `provider[.]`-string. Let's say you want to add the nice [Watercolor](http://maps.stamen.com/#watercolor/) style from Stamen to your map, you pass `Stamen.Watercolor` to the `L.tileLayer.provider`-constructor, which will return a [L.TileLayer](http://leafletjs.com/reference.html#tilelayer) instance for Stamens Watercolor tile layer.
7 |
8 | ```Javascript
9 | // add Stamen Watercolor to map.
10 | L.tileLayer.provider('Stamen.Watercolor').addTo(map);
11 | ```
12 |
13 | ## Protocol relativity (`https://`-urls)
14 |
15 | Leaflet-providers tries to use `https://` if the page uses `https://` and the provider supports it.
16 | You can force the use of `http://` by passing `force_http: true` in the options argument.
17 |
18 | ## Retina tiles
19 |
20 | Some providers have retina tiles for which the URL only needs to be slightly adjusted, e.g. `-----@2x.png`. For this, add the retina option in the URL, e.g. `-----{retina}.png`, and set a retina value in the options, e.g. `retina: '@2x'`. If Leaflet detects a retina screen (`L.Browser.retina`), the retina option passed to the tileLayer is set to the value supplied, otherwise it's replaced by an empty string.
21 |
22 | # Providers
23 |
24 | Leaflet-providers provides tile layers from different providers, including *OpenStreetMap*, *Stamen*, *Esri* and *OpenWeatherMap*. The full listing of free to use layers can be [previewed](http://leaflet-extras.github.io/leaflet-providers/preview/index.html). The page will show you the name to use with `leaflet-providers.js` and the code to use it without dependencies.
25 |
26 | ## Providers requiring registration
27 |
28 | In addition to the providers you are free1 to use, we support some layers which require registration.
29 |
30 | ### HERE (formerly Nokia).
31 |
32 | In order to use HERE layers, you must [register](http://developer.here.com/). Once registered, you can create an `app_id` and `app_code` which you have to pass to `L.tileLayer.provider` in the options:
33 |
34 | ```Javascript
35 | L.tileLayer.provider('HERE.terrainDay', {
36 | app_id: '',
37 | app_code: ''
38 | }).addTo(map);
39 | ```
40 |
41 | [Available HERE layers](http://leaflet-extras.github.io/leaflet-providers/preview/#filter=HERE)
42 |
43 | ### Mapbox
44 |
45 | In order to use Mapbox maps, you must [register](https://tiles.mapbox.com/signup). You can get map ID and ACCESS_TOKEN from [Mapbox projects](https://www.mapbox.com/projects):
46 | ```JavaScript
47 | L.tileLayer.provider('MapBox', {id: 'ID', accessToken: 'ACCESS_TOKEN'}).addTo(map);
48 | ```
49 |
50 | ### Esri/ArcGIS
51 |
52 | In order to use ArcGIS maps, you must [register](https://developers.arcgis.com/en/sign-up/) and abide by the [terms of service](https://developers.arcgis.com/en/terms/). No special syntax is required.
53 |
54 | [Available Esri layers](http://leaflet-extras.github.io/leaflet-providers/preview/#filter=Esri)
55 |
56 | # Attribution
57 |
58 | This work was inspired from , and originally created by [Stefan Seelmann](https://github.com/seelmann).
59 |
60 | ### What do we mean by *free*?
61 | 1
62 | We try to maintain leaflet-providers in such a way that you'll be able to use the layers we include without paying money.
63 | This doesn't mean no limits apply, you should always check before using these layers for anything serious.
64 |
--------------------------------------------------------------------------------
/Materials/libs/leaflet-providers-1.0.27/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "leaflet-providers",
3 | "version": "1.1.15",
4 | "homepage": "https://github.com/leaflet-extras/leaflet-providers",
5 | "description": "An extension to Leaflet that contains configurations for various free tile providers.",
6 | "dependencies": {
7 | "leaflet": "~0.7.3"
8 | },
9 | "main": "leaflet-providers.js",
10 | "keywords": [
11 | "leaflet",
12 | "stamen",
13 | "osm"
14 | ],
15 | "license": "BSD-2-Clause",
16 | "ignore": [
17 | "**/.*",
18 | "node_modules",
19 | "bower_components",
20 | "test",
21 | "tests",
22 | "preview",
23 | "*.html"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/Materials/libs/leaflet-providers-1.0.27/css/gh-fork-ribbon.css:
--------------------------------------------------------------------------------
1 | /* Left will inherit from right (so we don't need to duplicate code */
2 | .github-fork-ribbon {
3 | /* The right and left lasses determine the side we attach our banner to */
4 | position: absolute;
5 |
6 | /* Add a bit of padding to give some substance outside the "stitching" */
7 | padding: 2px 0;
8 |
9 | /* Set the base colour */
10 | background-color: #a00;
11 |
12 | /* Set a gradient: transparent black at the top to almost-transparent black at the bottom */
13 | background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.00)), to(rgba(0, 0, 0, 0.15)));
14 | background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15));
15 | background-image: -moz-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15));
16 | background-image: -o-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15));
17 | background-image: -ms-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15));
18 | background-image: linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15));
19 | filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#000000', EndColorStr='#000000');
20 |
21 | /* Add a drop shadow */
22 | -webkit-box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.5);
23 | box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.5);
24 |
25 | z-index: 9999;
26 | }
27 |
28 | .github-fork-ribbon a {
29 | /* Set the font */
30 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
31 | font-size: 13px;
32 | font-weight: 700;
33 | color: white;
34 |
35 | /* Set the text properties */
36 | text-decoration: none;
37 | text-shadow: 0 -1px rgba(0,0,0,0.5);
38 | text-align: center;
39 |
40 | /* Set the geometry. If you fiddle with these you'll also need to tweak the top and right values in #github-fork-ribbon. */
41 | width: 200px;
42 | line-height: 20px;
43 |
44 | /* Set the layout properties */
45 | display: inline-block;
46 | padding: 2px 0;
47 |
48 | /* Add "stitching" effect */
49 | border-width: 1px 0;
50 | border-style: dotted;
51 | border-color: rgba(255,255,255,0.7);
52 | }
53 |
54 | .github-fork-ribbon-wrapper {
55 | width: 150px;
56 | height: 150px;
57 | position: absolute;
58 | overflow: hidden;
59 | top: 0;
60 | }
61 |
62 | .github-fork-ribbon-wrapper.left {
63 | left: 0;
64 | }
65 |
66 | .github-fork-ribbon-wrapper.right {
67 | right: 0;
68 | }
69 |
70 | .github-fork-ribbon-wrapper.left-bottom {
71 | position: fixed;
72 | top: inherit;
73 | bottom: 0;
74 | left: 0;
75 | }
76 |
77 | .github-fork-ribbon-wrapper.right-bottom {
78 | position: fixed;
79 | top: inherit;
80 | bottom: 0;
81 | right: 0;
82 | }
83 |
84 | .github-fork-ribbon-wrapper.right .github-fork-ribbon {
85 | top: 42px;
86 | right: -43px;
87 |
88 | /* Rotate the banner 45 degrees */
89 | -webkit-transform: rotate(45deg);
90 | -moz-transform: rotate(45deg);
91 | -o-transform: rotate(45deg);
92 | transform: rotate(45deg);
93 | }
94 |
95 | .github-fork-ribbon-wrapper.left .github-fork-ribbon {
96 | top: 42px;
97 | left: -43px;
98 |
99 | /* Rotate the banner -45 degrees */
100 | -webkit-transform: rotate(-45deg);
101 | -moz-transform: rotate(-45deg);
102 | -o-transform: rotate(-45deg);
103 | transform: rotate(-45deg);
104 | }
105 |
106 |
107 | .github-fork-ribbon-wrapper.left-bottom .github-fork-ribbon {
108 | top: 80px;
109 | left: -43px;
110 |
111 | /* Rotate the banner -45 degrees */
112 | -webkit-transform: rotate(45deg);
113 | -moz-transform: rotate(45deg);
114 | -o-transform: rotate(45deg);
115 | transform: rotate(45deg);
116 | }
117 |
118 | .github-fork-ribbon-wrapper.right-bottom .github-fork-ribbon {
119 | top: 80px;
120 | right: -43px;
121 |
122 | /* Rotate the banner -45 degrees */
123 | -webkit-transform: rotate(-45deg);
124 | -moz-transform: rotate(-45deg);
125 | -o-transform: rotate(-45deg);
126 | transform: rotate(-45deg);
127 | }
--------------------------------------------------------------------------------
/Materials/libs/leaflet-providers-1.0.27/css/gh-fork-ribbon.ie.css:
--------------------------------------------------------------------------------
1 | /* IE voodoo courtesy of http://stackoverflow.com/a/4617511/263871 and
2 | * http://www.useragentman.com/IETransformsTranslator */
3 | .github-fork-ribbon-wrapper.right .github-fork-ribbon {
4 | /* IE positioning hack (couldn't find a transform-origin alternative for IE) */
5 | top: -22px;
6 | right: -62px;
7 |
8 | /* IE8+ */
9 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865474, M12=-0.7071067811865477, M21=0.7071067811865477, M22=0.7071067811865474, SizingMethod='auto expand')";
10 | /* IE6 and 7 */
11 | filter: progid:DXImageTransform.Microsoft.Matrix(
12 | M11=0.7071067811865474,
13 | M12=-0.7071067811865477,
14 | M21=0.7071067811865477,
15 | M22=0.7071067811865474,
16 | SizingMethod='auto expand'
17 | );
18 | }
19 |
20 | .github-fork-ribbon-wrapper.left .github-fork-ribbon {
21 | top: -22px;
22 | left: -22px;
23 |
24 | /* IE8+ */
25 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865483, M12=0.7071067811865467, M21=-0.7071067811865467, M22=0.7071067811865483, SizingMethod='auto expand')";
26 | /* IE6 and 7 */
27 | filter: progid:DXImageTransform.Microsoft.Matrix(
28 | M11=0.7071067811865483,
29 | M12=0.7071067811865467,
30 | M21=-0.7071067811865467,
31 | M22=0.7071067811865483,
32 | SizingMethod='auto expand'
33 | );
34 | }
35 |
36 | .github-fork-ribbon-wrapper.left-bottom .github-fork-ribbon {
37 | /* IE positioning hack (couldn't find a transform-origin alternative for IE) */
38 | top: 12px;
39 | left: -22px;
40 |
41 |
42 | /* IE8+ */
43 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865474, M12=-0.7071067811865477, M21=0.7071067811865477, M22=0.7071067811865474, SizingMethod='auto expand')";
44 | /* IE6 and 7 */
45 | /* filter: progid:DXImageTransform.Microsoft.Matrix(
46 | M11=0.7071067811865474,
47 | M12=-0.7071067811865477,
48 | M21=0.7071067811865477,
49 | M22=0.7071067811865474,
50 | SizingMethod='auto expand'
51 | );
52 | */}
53 |
54 | .github-fork-ribbon-wrapper.right-bottom .github-fork-ribbon {
55 | top: 12px;
56 | right: -62px;
57 |
58 | /* IE8+ */
59 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865483, M12=0.7071067811865467, M21=-0.7071067811865467, M22=0.7071067811865483, SizingMethod='auto expand')";
60 | /* IE6 and 7 */
61 | filter: progid:DXImageTransform.Microsoft.Matrix(
62 | M11=0.7071067811865483,
63 | M12=0.7071067811865467,
64 | M21=-0.7071067811865467,
65 | M22=0.7071067811865483,
66 | SizingMethod='auto expand'
67 | );
68 | }
--------------------------------------------------------------------------------
/Materials/libs/leaflet-providers-1.0.27/leaflet-providers.js:
--------------------------------------------------------------------------------
1 | (function (root, factory) {
2 | if (typeof define === 'function' && define.amd) {
3 | // AMD. Register as an anonymous module.
4 | define(['leaflet'], factory);
5 | } else if (typeof modules === 'object' && module.exports) {
6 | // define a Common JS module that relies on 'leaflet'
7 | module.exports = factory(require('leaflet'));
8 | } else {
9 | // Assume Leaflet is loaded into global object L already
10 | factory(L);
11 | }
12 | }(this, function (L) {
13 | 'use strict';
14 |
15 | L.TileLayer.Provider = L.TileLayer.extend({
16 | initialize: function (arg, options) {
17 | var providers = L.TileLayer.Provider.providers;
18 |
19 | var parts = arg.split('.');
20 |
21 | var providerName = parts[0];
22 | var variantName = parts[1];
23 |
24 | if (!providers[providerName]) {
25 | throw 'No such provider (' + providerName + ')';
26 | }
27 |
28 | var provider = {
29 | url: providers[providerName].url,
30 | options: providers[providerName].options
31 | };
32 |
33 | // overwrite values in provider from variant.
34 | if (variantName && 'variants' in providers[providerName]) {
35 | if (!(variantName in providers[providerName].variants)) {
36 | throw 'No such variant of ' + providerName + ' (' + variantName + ')';
37 | }
38 | var variant = providers[providerName].variants[variantName];
39 | var variantOptions;
40 | if (typeof variant === 'string') {
41 | variantOptions = {
42 | variant: variant
43 | };
44 | } else {
45 | variantOptions = variant.options;
46 | }
47 | provider = {
48 | url: variant.url || provider.url,
49 | options: L.Util.extend({}, provider.options, variantOptions)
50 | };
51 | }
52 |
53 | var forceHTTP = window.location.protocol === 'file:' || provider.options.forceHTTP;
54 | if (provider.url.indexOf('//') === 0 && forceHTTP) {
55 | provider.url = 'http:' + provider.url;
56 | }
57 |
58 | // If retina option is set
59 | if (provider.options.retina) {
60 | // Check retina screen
61 | if (options.detectRetina && L.Browser.retina) {
62 | // The retina option will be active now
63 | // But we need to prevent Leaflet retina mode
64 | options.detectRetina = false;
65 | } else {
66 | // No retina, remove option
67 | provider.options.retina = '';
68 | }
69 | }
70 |
71 | // replace attribution placeholders with their values from toplevel provider attribution,
72 | // recursively
73 | var attributionReplacer = function (attr) {
74 | if (attr.indexOf('{attribution.') === -1) {
75 | return attr;
76 | }
77 | return attr.replace(/\{attribution.(\w*)\}/,
78 | function (match, attributionName) {
79 | return attributionReplacer(providers[attributionName].options.attribution);
80 | }
81 | );
82 | };
83 | provider.options.attribution = attributionReplacer(provider.options.attribution);
84 |
85 | // Compute final options combining provider options with any user overrides
86 | var layerOpts = L.Util.extend({}, provider.options, options);
87 | L.TileLayer.prototype.initialize.call(this, provider.url, layerOpts);
88 | }
89 | });
90 |
91 | /**
92 | * Definition of providers.
93 | * see http://leafletjs.com/reference.html#tilelayer for options in the options map.
94 | */
95 |
96 | L.TileLayer.Provider.providers = {
97 | OpenStreetMap: {
98 | url: '//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
99 | options: {
100 | maxZoom: 19,
101 | attribution:
102 | '© OpenStreetMap'
103 | },
104 | variants: {
105 | Mapnik: {},
106 | BlackAndWhite: {
107 | url: 'http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png',
108 | options: {
109 | maxZoom: 18
110 | }
111 | },
112 | DE: {
113 | url: 'http://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png',
114 | options: {
115 | maxZoom: 18
116 | }
117 | },
118 | France: {
119 | url: '//{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png',
120 | options: {
121 | maxZoom: 20,
122 | attribution: '© Openstreetmap France | {attribution.OpenStreetMap}'
123 | }
124 | },
125 | HOT: {
126 | url: '//{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png',
127 | options: {
128 | attribution: '{attribution.OpenStreetMap}, Tiles courtesy of Humanitarian OpenStreetMap Team'
129 | }
130 | }
131 | }
132 | },
133 | OpenSeaMap: {
134 | url: 'http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png',
135 | options: {
136 | attribution: 'Map data: © OpenSeaMap contributors'
137 | }
138 | },
139 | OpenTopoMap: {
140 | url: '//{s}.tile.opentopomap.org/{z}/{x}/{y}.png',
141 | options: {
142 | maxZoom: 17,
143 | attribution: 'Map data: {attribution.OpenStreetMap}, SRTM | Map style: © OpenTopoMap (CC-BY-SA)'
144 | }
145 | },
146 | Thunderforest: {
147 | url: '//{s}.tile.thunderforest.com/{variant}/{z}/{x}/{y}.png',
148 | options: {
149 | attribution:
150 | '© Thunderforest, {attribution.OpenStreetMap}',
151 | variant: 'cycle'
152 | },
153 | variants: {
154 | OpenCycleMap: 'cycle',
155 | Transport: {
156 | options: {
157 | variant: 'transport',
158 | maxZoom: 19
159 | }
160 | },
161 | TransportDark: {
162 | options: {
163 | variant: 'transport-dark',
164 | maxZoom: 19
165 | }
166 | },
167 | SpinalMap: {
168 | options: {
169 | variant: 'spinal-map',
170 | maxZoom: 11
171 | }
172 | },
173 | Landscape: 'landscape',
174 | Outdoors: 'outdoors',
175 | Pioneer: 'pioneer'
176 | }
177 | },
178 | OpenMapSurfer: {
179 | url: 'http://korona.geog.uni-heidelberg.de/tiles/{variant}/x={x}&y={y}&z={z}',
180 | options: {
181 | maxZoom: 20,
182 | variant: 'roads',
183 | attribution: 'Imagery from GIScience Research Group @ University of Heidelberg — Map data {attribution.OpenStreetMap}'
184 | },
185 | variants: {
186 | Roads: 'roads',
187 | AdminBounds: {
188 | options: {
189 | variant: 'adminb',
190 | maxZoom: 19
191 | }
192 | },
193 | Grayscale: {
194 | options: {
195 | variant: 'roadsg',
196 | maxZoom: 19
197 | }
198 | }
199 | }
200 | },
201 | Hydda: {
202 | url: '//{s}.tile.openstreetmap.se/hydda/{variant}/{z}/{x}/{y}.png',
203 | options: {
204 | variant: 'full',
205 | attribution: 'Tiles courtesy of OpenStreetMap Sweden — Map data {attribution.OpenStreetMap}'
206 | },
207 | variants: {
208 | Full: 'full',
209 | Base: 'base',
210 | RoadsAndLabels: 'roads_and_labels'
211 | }
212 | },
213 | MapBox: {
214 | url: '//api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}',
215 | options: {
216 | attribution:
217 | 'Imagery from MapBox — ' +
218 | 'Map data {attribution.OpenStreetMap}',
219 | subdomains: 'abcd'
220 | }
221 | },
222 | Stamen: {
223 | url: '//stamen-tiles-{s}.a.ssl.fastly.net/{variant}/{z}/{x}/{y}.{ext}',
224 | options: {
225 | attribution:
226 | 'Map tiles by Stamen Design, ' +
227 | 'CC BY 3.0 — ' +
228 | 'Map data {attribution.OpenStreetMap}',
229 | subdomains: 'abcd',
230 | minZoom: 0,
231 | maxZoom: 20,
232 | variant: 'toner',
233 | ext: 'png'
234 | },
235 | variants: {
236 | Toner: 'toner',
237 | TonerBackground: 'toner-background',
238 | TonerHybrid: 'toner-hybrid',
239 | TonerLines: 'toner-lines',
240 | TonerLabels: 'toner-labels',
241 | TonerLite: 'toner-lite',
242 | Watercolor: {
243 | options: {
244 | variant: 'watercolor',
245 | minZoom: 1,
246 | maxZoom: 16
247 | }
248 | },
249 | Terrain: {
250 | options: {
251 | variant: 'terrain',
252 | minZoom: 0,
253 | maxZoom: 18
254 | }
255 | },
256 | TerrainBackground: {
257 | options: {
258 | variant: 'terrain-background',
259 | minZoom: 0,
260 | maxZoom: 18
261 | }
262 | },
263 | TopOSMRelief: {
264 | options: {
265 | variant: 'toposm-color-relief',
266 | ext: 'jpg',
267 | bounds: [[22, -132], [51, -56]]
268 | }
269 | },
270 | TopOSMFeatures: {
271 | options: {
272 | variant: 'toposm-features',
273 | bounds: [[22, -132], [51, -56]],
274 | opacity: 0.9
275 | }
276 | }
277 | }
278 | },
279 | Esri: {
280 | url: '//server.arcgisonline.com/ArcGIS/rest/services/{variant}/MapServer/tile/{z}/{y}/{x}',
281 | options: {
282 | variant: 'World_Street_Map',
283 | attribution: 'Tiles © Esri'
284 | },
285 | variants: {
286 | WorldStreetMap: {
287 | options: {
288 | attribution:
289 | '{attribution.Esri} — ' +
290 | 'Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012'
291 | }
292 | },
293 | DeLorme: {
294 | options: {
295 | variant: 'Specialty/DeLorme_World_Base_Map',
296 | minZoom: 1,
297 | maxZoom: 11,
298 | attribution: '{attribution.Esri} — Copyright: ©2012 DeLorme'
299 | }
300 | },
301 | WorldTopoMap: {
302 | options: {
303 | variant: 'World_Topo_Map',
304 | attribution:
305 | '{attribution.Esri} — ' +
306 | 'Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community'
307 | }
308 | },
309 | WorldImagery: {
310 | options: {
311 | variant: 'World_Imagery',
312 | attribution:
313 | '{attribution.Esri} — ' +
314 | 'Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
315 | }
316 | },
317 | WorldTerrain: {
318 | options: {
319 | variant: 'World_Terrain_Base',
320 | maxZoom: 13,
321 | attribution:
322 | '{attribution.Esri} — ' +
323 | 'Source: USGS, Esri, TANA, DeLorme, and NPS'
324 | }
325 | },
326 | WorldShadedRelief: {
327 | options: {
328 | variant: 'World_Shaded_Relief',
329 | maxZoom: 13,
330 | attribution: '{attribution.Esri} — Source: Esri'
331 | }
332 | },
333 | WorldPhysical: {
334 | options: {
335 | variant: 'World_Physical_Map',
336 | maxZoom: 8,
337 | attribution: '{attribution.Esri} — Source: US National Park Service'
338 | }
339 | },
340 | OceanBasemap: {
341 | options: {
342 | variant: 'Ocean_Basemap',
343 | maxZoom: 13,
344 | attribution: '{attribution.Esri} — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri'
345 | }
346 | },
347 | NatGeoWorldMap: {
348 | options: {
349 | variant: 'NatGeo_World_Map',
350 | maxZoom: 16,
351 | attribution: '{attribution.Esri} — National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC'
352 | }
353 | },
354 | WorldGrayCanvas: {
355 | options: {
356 | variant: 'Canvas/World_Light_Gray_Base',
357 | maxZoom: 16,
358 | attribution: '{attribution.Esri} — Esri, DeLorme, NAVTEQ'
359 | }
360 | }
361 | }
362 | },
363 | OpenWeatherMap: {
364 | url: 'http://{s}.tile.openweathermap.org/map/{variant}/{z}/{x}/{y}.png',
365 | options: {
366 | maxZoom: 19,
367 | attribution: 'Map data © OpenWeatherMap',
368 | opacity: 0.5
369 | },
370 | variants: {
371 | Clouds: 'clouds',
372 | CloudsClassic: 'clouds_cls',
373 | Precipitation: 'precipitation',
374 | PrecipitationClassic: 'precipitation_cls',
375 | Rain: 'rain',
376 | RainClassic: 'rain_cls',
377 | Pressure: 'pressure',
378 | PressureContour: 'pressure_cntr',
379 | Wind: 'wind',
380 | Temperature: 'temp',
381 | Snow: 'snow'
382 | }
383 | },
384 | HERE: {
385 | /*
386 | * HERE maps, formerly Nokia maps.
387 | * These basemaps are free, but you need an API key. Please sign up at
388 | * http://developer.here.com/getting-started
389 | *
390 | * Note that the base urls contain '.cit' whichs is HERE's
391 | * 'Customer Integration Testing' environment. Please remove for production
392 | * envirionments.
393 | */
394 | url:
395 | '//{s}.{base}.maps.cit.api.here.com/maptile/2.1/' +
396 | '{type}/{mapID}/{variant}/{z}/{x}/{y}/{size}/{format}?' +
397 | 'app_id={app_id}&app_code={app_code}&lg={language}',
398 | options: {
399 | attribution:
400 | 'Map © 1987-2014 HERE',
401 | subdomains: '1234',
402 | mapID: 'newest',
403 | 'app_id': '',
404 | 'app_code': '',
405 | base: 'base',
406 | variant: 'normal.day',
407 | maxZoom: 20,
408 | type: 'maptile',
409 | language: 'eng',
410 | format: 'png8',
411 | size: '256'
412 | },
413 | variants: {
414 | normalDay: 'normal.day',
415 | normalDayCustom: 'normal.day.custom',
416 | normalDayGrey: 'normal.day.grey',
417 | normalDayMobile: 'normal.day.mobile',
418 | normalDayGreyMobile: 'normal.day.grey.mobile',
419 | normalDayTransit: 'normal.day.transit',
420 | normalDayTransitMobile: 'normal.day.transit.mobile',
421 | normalNight: 'normal.night',
422 | normalNightMobile: 'normal.night.mobile',
423 | normalNightGrey: 'normal.night.grey',
424 | normalNightGreyMobile: 'normal.night.grey.mobile',
425 |
426 | basicMap: {
427 | options: {
428 | type: 'basetile'
429 | }
430 | },
431 | mapLabels: {
432 | options: {
433 | type: 'labeltile',
434 | format: 'png'
435 | }
436 | },
437 | trafficFlow: {
438 | options: {
439 | base: 'traffic',
440 | type: 'flowtile'
441 | }
442 | },
443 | carnavDayGrey: 'carnav.day.grey',
444 | hybridDay: {
445 | options: {
446 | base: 'aerial',
447 | variant: 'hybrid.day'
448 | }
449 | },
450 | hybridDayMobile: {
451 | options: {
452 | base: 'aerial',
453 | variant: 'hybrid.day.mobile'
454 | }
455 | },
456 | pedestrianDay: 'pedestrian.day',
457 | pedestrianNight: 'pedestrian.night',
458 | satelliteDay: {
459 | options: {
460 | base: 'aerial',
461 | variant: 'satellite.day'
462 | }
463 | },
464 | terrainDay: {
465 | options: {
466 | base: 'aerial',
467 | variant: 'terrain.day'
468 | }
469 | },
470 | terrainDayMobile: {
471 | options: {
472 | base: 'aerial',
473 | variant: 'terrain.day.mobile'
474 | }
475 | }
476 | }
477 | },
478 | FreeMapSK: {
479 | url: 'http://t{s}.freemap.sk/T/{z}/{x}/{y}.jpeg',
480 | options: {
481 | minZoom: 8,
482 | maxZoom: 16,
483 | subdomains: '1234',
484 | bounds: [[47.204642, 15.996093], [49.830896, 22.576904]],
485 | attribution:
486 | '{attribution.OpenStreetMap}, vizualization CC-By-SA 2.0 Freemap.sk'
487 | }
488 | },
489 | MtbMap: {
490 | url: 'http://tile.mtbmap.cz/mtbmap_tiles/{z}/{x}/{y}.png',
491 | options: {
492 | attribution:
493 | '{attribution.OpenStreetMap} & USGS'
494 | }
495 | },
496 | CartoDB: {
497 | url: 'http://{s}.basemaps.cartocdn.com/{variant}/{z}/{x}/{y}.png',
498 | options: {
499 | attribution: '{attribution.OpenStreetMap} © CartoDB',
500 | subdomains: 'abcd',
501 | maxZoom: 19,
502 | variant: 'light_all'
503 | },
504 | variants: {
505 | Positron: 'light_all',
506 | PositronNoLabels: 'light_nolabels',
507 | PositronOnlyLabels: 'light_only_labels',
508 | DarkMatter: 'dark_all',
509 | DarkMatterNoLabels: 'dark_nolabels',
510 | DarkMatterOnlyLabels: 'dark_only_labels'
511 | }
512 | },
513 | HikeBike: {
514 | url: 'http://{s}.tiles.wmflabs.org/{variant}/{z}/{x}/{y}.png',
515 | options: {
516 | maxZoom: 19,
517 | attribution: '{attribution.OpenStreetMap}',
518 | variant: 'hikebike'
519 | },
520 | variants: {
521 | HikeBike: {},
522 | HillShading: {
523 | options: {
524 | maxZoom: 15,
525 | variant: 'hillshading'
526 | }
527 | }
528 | }
529 | },
530 | BasemapAT: {
531 | url: '//maps{s}.wien.gv.at/basemap/{variant}/normal/google3857/{z}/{y}/{x}.{format}',
532 | options: {
533 | maxZoom: 19,
534 | attribution: 'Datenquelle: basemap.at',
535 | subdomains: ['', '1', '2', '3', '4'],
536 | format: 'png',
537 | bounds: [[46.358770, 8.782379], [49.037872, 17.189532]],
538 | variant: 'geolandbasemap'
539 | },
540 | variants: {
541 | basemap: 'geolandbasemap',
542 | grau: 'bmapgrau',
543 | overlay: 'bmapoverlay',
544 | highdpi: {
545 | options: {
546 | variant: 'bmaphidpi',
547 | format: 'jpeg'
548 | }
549 | },
550 | orthofoto: {
551 | options: {
552 | variant: 'bmaporthofoto30cm',
553 | format: 'jpeg'
554 | }
555 | }
556 | }
557 | },
558 | NASAGIBS: {
559 | url: '//map1.vis.earthdata.nasa.gov/wmts-webmerc/{variant}/default/{time}/{tilematrixset}{maxZoom}/{z}/{y}/{x}.{format}',
560 | options: {
561 | attribution:
562 | 'Imagery provided by services from the Global Imagery Browse Services (GIBS), operated by the NASA/GSFC/Earth Science Data and Information System ' +
563 | '(ESDIS) with funding provided by NASA/HQ.',
564 | bounds: [[-85.0511287776, -179.999999975], [85.0511287776, 179.999999975]],
565 | minZoom: 1,
566 | maxZoom: 9,
567 | format: 'jpg',
568 | time: '',
569 | tilematrixset: 'GoogleMapsCompatible_Level'
570 | },
571 | variants: {
572 | ModisTerraTrueColorCR: 'MODIS_Terra_CorrectedReflectance_TrueColor',
573 | ModisTerraBands367CR: 'MODIS_Terra_CorrectedReflectance_Bands367',
574 | ViirsEarthAtNight2012: {
575 | options: {
576 | variant: 'VIIRS_CityLights_2012',
577 | maxZoom: 8
578 | }
579 | },
580 | ModisTerraLSTDay: {
581 | options: {
582 | variant: 'MODIS_Terra_Land_Surface_Temp_Day',
583 | format: 'png',
584 | maxZoom: 7,
585 | opacity: 0.75
586 | }
587 | },
588 | ModisTerraSnowCover: {
589 | options: {
590 | variant: 'MODIS_Terra_Snow_Cover',
591 | format: 'png',
592 | maxZoom: 8,
593 | opacity: 0.75
594 | }
595 | },
596 | ModisTerraAOD: {
597 | options: {
598 | variant: 'MODIS_Terra_Aerosol',
599 | format: 'png',
600 | maxZoom: 6,
601 | opacity: 0.75
602 | }
603 | },
604 | ModisTerraChlorophyll: {
605 | options: {
606 | variant: 'MODIS_Terra_Chlorophyll_A',
607 | format: 'png',
608 | maxZoom: 7,
609 | opacity: 0.75
610 | }
611 | }
612 | }
613 | },
614 | NLS: {
615 | // NLS maps are copyright National library of Scotland.
616 | // http://maps.nls.uk/projects/api/index.html
617 | // Please contact NLS for anything other than non-commercial low volume usage
618 | //
619 | // Map sources: Ordnance Survey 1:1m to 1:63K, 1920s-1940s
620 | // z0-9 - 1:1m
621 | // z10-11 - quarter inch (1:253440)
622 | // z12-18 - one inch (1:63360)
623 | url: '//nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg',
624 | options: {
625 | attribution: 'National Library of Scotland Historic Maps',
626 | bounds: [[49.6, -12], [61.7, 3]],
627 | minZoom: 1,
628 | maxZoom: 18,
629 | subdomains: '0123',
630 | }
631 | }
632 | };
633 |
634 | L.tileLayer.provider = function (provider, options) {
635 | return new L.TileLayer.Provider(provider, options);
636 | };
637 |
638 | return L;
639 | }));
640 |
--------------------------------------------------------------------------------
/Materials/libs/leaflet-providers-1.0.27/license.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013 Leaflet Providers contributors
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5 |
6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 |
9 | _THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE._
--------------------------------------------------------------------------------
/Materials/libs/leaflet-providers-1.0.27/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "leaflet-providers",
3 | "version": "1.1.15",
4 | "description": "An extension to Leaflet that contains configurations for various free tile providers.",
5 | "main": "leaflet-providers.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "git://github.com/leaflet-extras/leaflet-providers.git"
9 | },
10 | "scripts": {
11 | "test": "npm run lint && npm run testsuite",
12 | "testsuite": "mocha-phantomjs tests/index.html",
13 | "lint": "eslint --config .eslintrc leaflet-providers.js index.html preview/*.js preview/*.html tests/*",
14 | "min": "uglifyjs leaflet-providers.js -mc -o leaflet-providers.min.js",
15 | "release": "mversion patch -m"
16 | },
17 | "license": "BSD-2-Clause",
18 | "bugs": {
19 | "url": "https://github.com/leaflet-extras/leaflet-providers/issues"
20 | },
21 | "files": [
22 | "leaflet-providers.js",
23 | "README.md",
24 | "CHANGELOG.md",
25 | "licence.md"
26 | ],
27 | "devDependencies": {
28 | "chai": "^2.3.0",
29 | "eslint": "^2.7.0",
30 | "eslint-plugin-html": "^1.4.0",
31 | "mocha": "^2.2.4",
32 | "mocha-phantomjs": "^3.5.3",
33 | "mversion": "^1.3.0",
34 | "phantomjs": "1.9.7-15",
35 | "uglify-js": "^2.4.15"
36 | },
37 | "autoupdate": {
38 | "source": "git",
39 | "target": "git://github.com/leaflet-extras/leaflet-providers.git",
40 | "basePath": "/",
41 | "files": [
42 | "leaflet-providers.js"
43 | ]
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Materials/libs/leaflet-providers-1.0.27/providers.json:
--------------------------------------------------------------------------------
1 | {
2 | "OpenStreetMap": {
3 | "url": "//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
4 | "options": {
5 | "maxZoom": 19,
6 | "attribution":
7 | "© OpenStreetMap"
8 | },
9 | "variants": {
10 | "Mapnik": {},
11 | "BlackAndWhite": {
12 | "url": "http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png",
13 | "options": {
14 | "maxZoom": 18
15 | }
16 | },
17 | "DE": {
18 | "url": "http://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png",
19 | "options": {
20 | "maxZoom": 18
21 | }
22 | },
23 | "France": {
24 | "url": "//{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png",
25 | "options": {
26 | "maxZoom": 20,
27 | "attribution": "© Openstreetmap France | {attribution.OpenStreetMap}"
28 | }
29 | },
30 | "HOT": {
31 | "url": "//{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png",
32 | "options": {
33 | "attribution": "{attribution.OpenStreetMap}, Tiles courtesy of Humanitarian OpenStreetMap Team"
34 | }
35 | }
36 | }
37 | },
38 | "OpenSeaMap": {
39 | "url": "http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png",
40 | "options": {
41 | "attribution": "Map data: © OpenSeaMap contributors"
42 | }
43 | },
44 | "OpenTopoMap": {
45 | "url": "//{s}.tile.opentopomap.org/{z}/{x}/{y}.png",
46 | "options": {
47 | "maxZoom": 17,
48 | "attribution": "Map data: {attribution.OpenStreetMap}, SRTM | Map style: © OpenTopoMap (CC-BY-SA)"
49 | }
50 | },
51 | "Thunderforest": {
52 | "url": "//{s}.tile.thunderforest.com/{variant}/{z}/{x}/{y}.png",
53 | "options": {
54 | "attribution":
55 | "© Thunderforest, {attribution.OpenStreetMap}",
56 | "variant": "cycle"
57 | },
58 | "variants": {
59 | "OpenCycleMap": "cycle",
60 | "Transport": {
61 | "options": {
62 | "variant": "transport",
63 | "maxZoom": 19
64 | }
65 | },
66 | "TransportDark": {
67 | "options": {
68 | "variant": "transport-dark",
69 | "maxZoom": 19
70 | }
71 | },
72 | "SpinalMap": {
73 | "options": {
74 | "variant": "spinal-map",
75 | "maxZoom": 11
76 | }
77 | },
78 | "Landscape": "landscape",
79 | "Outdoors": "outdoors",
80 | "Pioneer": "pioneer"
81 | }
82 | },
83 | "OpenMapSurfer": {
84 | "url": "http://korona.geog.uni-heidelberg.de/tiles/{variant}/x={x}&y={y}&z={z}",
85 | "options": {
86 | "maxZoom": 20,
87 | "variant": "roads",
88 | "attribution": "Imagery from GIScience Research Group @ University of Heidelberg — Map data {attribution.OpenStreetMap}"
89 | },
90 | "variants": {
91 | "Roads": "roads",
92 | "AdminBounds": {
93 | "options": {
94 | "variant": "adminb",
95 | "maxZoom": 19
96 | }
97 | },
98 | "Grayscale": {
99 | "options": {
100 | "variant": "roadsg",
101 | "maxZoom": 19
102 | }
103 | }
104 | }
105 | },
106 | "Hydda": {
107 | "url": "//{s}.tile.openstreetmap.se/hydda/{variant}/{z}/{x}/{y}.png",
108 | "options": {
109 | "variant": "full",
110 | "attribution": "Tiles courtesy of OpenStreetMap Sweden — Map data {attribution.OpenStreetMap}"
111 | },
112 | "variants": {
113 | "Full": "full",
114 | "Base": "base",
115 | "RoadsAndLabels": "roads_and_labels"
116 | }
117 | },
118 | "MapBox": {
119 | "url": "//api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}",
120 | "options": {
121 | "attribution": "Imagery from MapBox — Map data {attribution.OpenStreetMap}",
122 | "subdomains": "abcd"
123 | }
124 | },
125 | "Stamen": {
126 | "url": "//stamen-tiles-{s}.a.ssl.fastly.net/{variant}/{z}/{x}/{y}.{ext}",
127 | "options": {
128 | "attribution": "Map tiles by Stamen Design, CC BY 3.0 — Map data {attribution.OpenStreetMap}",
129 | "subdomains": "abcd",
130 | "minZoom": 0,
131 | "maxZoom": 20,
132 | "variant": "toner",
133 | "ext": "png"
134 | },
135 | "variants": {
136 | "Toner": "toner",
137 | "TonerBackground": "toner-background",
138 | "TonerHybrid": "toner-hybrid",
139 | "TonerLines": "toner-lines",
140 | "TonerLabels": "toner-labels",
141 | "TonerLite": "toner-lite",
142 | "Watercolor": {
143 | "options": {
144 | "variant": "watercolor",
145 | "minZoom": 1,
146 | "maxZoom": 16
147 | }
148 | },
149 | "Terrain": {
150 | "options": {
151 | "variant": "terrain",
152 | "minZoom": 0,
153 | "maxZoom": 18
154 | }
155 | },
156 | "TerrainBackground": {
157 | "options": {
158 | "variant": "terrain-background",
159 | "minZoom": 0,
160 | "maxZoom": 18
161 | }
162 | },
163 | "TopOSMRelief": {
164 | "options": {
165 | "variant": "toposm-color-relief",
166 | "ext": "jpg",
167 | "bounds": [[22, -132], [51, -56]]
168 | }
169 | },
170 | "TopOSMFeatures": {
171 | "options": {
172 | "variant": "toposm-features",
173 | "bounds": [[22, -132], [51, -56]],
174 | "opacity": 0.9
175 | }
176 | }
177 | }
178 | },
179 | "Esri": {
180 | "url": "//server.arcgisonline.com/ArcGIS/rest/services/{variant}/MapServer/tile/{z}/{y}/{x}",
181 | "options": {
182 | "variant": "World_Street_Map",
183 | "attribution": "Tiles © Esri"
184 | },
185 | "variants": {
186 | "WorldStreetMap": {
187 | "options": {
188 | "attribution":
189 | "Tiles © Esri Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012"
190 | }
191 | },
192 | "DeLorme": {
193 | "options": {
194 | "variant": "Specialty/DeLorme_World_Base_Map",
195 | "minZoom": 1,
196 | "maxZoom": 11,
197 | "attribution": "Tiles © Esri — Copyright: ©2012 DeLorme"
198 | }
199 | },
200 | "WorldTopoMap": {
201 | "options": {
202 | "variant": "World_Topo_Map",
203 | "attribution": "Tiles © Esri Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community"
204 | }
205 | },
206 | "WorldImagery": {
207 | "options": {
208 | "variant": "World_Imagery",
209 | "attribution": "Tiles © Esri Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community"
210 | }
211 | },
212 | "WorldTerrain": {
213 | "options": {
214 | "variant": "World_Terrain_Base",
215 | "maxZoom": 13,
216 | "attribution": "Tiles © Esri Source: USGS, Esri, TANA, DeLorme, and NPS"
217 | }
218 | },
219 | "WorldShadedRelief": {
220 | "options": {
221 | "variant": "World_Shaded_Relief",
222 | "maxZoom": 13,
223 | "attribution": "{attribution.Esri} — Source: Esri"
224 | }
225 | },
226 | "WorldPhysical": {
227 | "options": {
228 | "variant": "World_Physical_Map",
229 | "maxZoom": 8,
230 | "attribution": "{attribution.Esri} — Source: US National Park Service"
231 | }
232 | },
233 | "OceanBasemap": {
234 | "options": {
235 | "variant": "Ocean_Basemap",
236 | "maxZoom": 13,
237 | "attribution": "{attribution.Esri} — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri"
238 | }
239 | },
240 | "NatGeoWorldMap": {
241 | "options": {
242 | "variant": "NatGeo_World_Map",
243 | "maxZoom": 16,
244 | "attribution": "{attribution.Esri} — National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC"
245 | }
246 | },
247 | "WorldGrayCanvas": {
248 | "options": {
249 | "variant": "Canvas/World_Light_Gray_Base",
250 | "maxZoom": 16,
251 | "attribution": "{attribution.Esri} — Esri, DeLorme, NAVTEQ"
252 | }
253 | }
254 | }
255 | },
256 | "OpenWeatherMap": {
257 | "url": "http://{s}.tile.openweathermap.org/map/{variant}/{z}/{x}/{y}.png",
258 | "options": {
259 | "maxZoom": 19,
260 | "attribution": "Map data © OpenWeatherMap",
261 | "opacity": 0.5
262 | },
263 | "variants": {
264 | "Clouds": "clouds",
265 | "CloudsClassic": "clouds_cls",
266 | "Precipitation": "precipitation",
267 | "PrecipitationClassic": "precipitation_cls",
268 | "Rain": "rain",
269 | "RainClassic": "rain_cls",
270 | "Pressure": "pressure",
271 | "PressureContour": "pressure_cntr",
272 | "Wind": "wind",
273 | "Temperature": "temp",
274 | "Snow": "snow"
275 | }
276 | },
277 | "HERE": {
278 | "url": "//{s}.{base}.maps.cit.api.here.com/maptile/2.1/{type}/{mapID}/{variant}/{z}/{x}/{y}/{size}/{format}?app_id={app_id}&app_code={app_code}&lg={language}",
279 | "options": {
280 | "attribution":
281 | "Map © 1987-2014 HERE",
282 | "subdomains": "1234",
283 | "mapID": "newest",
284 | "app_id": "",
285 | "app_code": "",
286 | "base": "base",
287 | "variant": "normal.day",
288 | "maxZoom": 20,
289 | "type": "maptile",
290 | "language": "eng",
291 | "format": "png8",
292 | "size": "256"
293 | },
294 | "variants": {
295 | "normalDay": "normal.day",
296 | "normalDayCustom": "normal.day.custom",
297 | "normalDayGrey": "normal.day.grey",
298 | "normalDayMobile": "normal.day.mobile",
299 | "normalDayGreyMobile": "normal.day.grey.mobile",
300 | "normalDayTransit": "normal.day.transit",
301 | "normalDayTransitMobile": "normal.day.transit.mobile",
302 | "normalNight": "normal.night",
303 | "normalNightMobile": "normal.night.mobile",
304 | "normalNightGrey": "normal.night.grey",
305 | "normalNightGreyMobile": "normal.night.grey.mobile",
306 |
307 | "basicMap": {
308 | "options": {
309 | "type": "basetile"
310 | }
311 | },
312 | "mapLabels": {
313 | "options": {
314 | "type": "labeltile",
315 | "format": "png"
316 | }
317 | },
318 | "trafficFlow": {
319 | "options": {
320 | "base": "traffic",
321 | "type": "flowtile"
322 | }
323 | },
324 | "carnavDayGrey": "carnav.day.grey",
325 | "hybridDay": {
326 | "options": {
327 | "base": "aerial",
328 | "variant": "hybrid.day"
329 | }
330 | },
331 | "hybridDayMobile": {
332 | "options": {
333 | "base": "aerial",
334 | "variant": "hybrid.day.mobile"
335 | }
336 | },
337 | "pedestrianDay": "pedestrian.day",
338 | "pedestrianNight": "pedestrian.night",
339 | "satelliteDay": {
340 | "options": {
341 | "base": "aerial",
342 | "variant": "satellite.day"
343 | }
344 | },
345 | "terrainDay": {
346 | "options": {
347 | "base": "aerial",
348 | "variant": "terrain.day"
349 | }
350 | },
351 | "terrainDayMobile": {
352 | "options": {
353 | "base": "aerial",
354 | "variant": "terrain.day.mobile"
355 | }
356 | }
357 | }
358 | },
359 | "FreeMapSK": {
360 | "url": "http://t{s}.freemap.sk/T/{z}/{x}/{y}.jpeg",
361 | "options": {
362 | "minZoom": 8,
363 | "maxZoom": 16,
364 | "subdomains": "1234",
365 | "bounds": [[47.204642, 15.996093], [49.830896, 22.576904]],
366 | "attribution":
367 | "{attribution.OpenStreetMap}, vizualization CC-By-SA 2.0 Freemap.sk"
368 | }
369 | },
370 | "MtbMap": {
371 | "url": "http://tile.mtbmap.cz/mtbmap_tiles/{z}/{x}/{y}.png",
372 | "options": {
373 | "attribution":
374 | "{attribution.OpenStreetMap} & USGS"
375 | }
376 | },
377 | "CartoDB": {
378 | "url": "http://{s}.basemaps.cartocdn.com/{variant}/{z}/{x}/{y}.png",
379 | "options": {
380 | "attribution": "{attribution.OpenStreetMap} © CartoDB",
381 | "subdomains": "abcd",
382 | "maxZoom": 19,
383 | "variant": "light_all"
384 | },
385 | "variants": {
386 | "Positron": "light_all",
387 | "PositronNoLabels": "light_nolabels",
388 | "PositronOnlyLabels": "light_only_labels",
389 | "DarkMatter": "dark_all",
390 | "DarkMatterNoLabels": "dark_nolabels",
391 | "DarkMatterOnlyLabels": "dark_only_labels"
392 | }
393 | },
394 | "HikeBike": {
395 | "url": "http://{s}.tiles.wmflabs.org/{variant}/{z}/{x}/{y}.png",
396 | "options": {
397 | "maxZoom": 19,
398 | "attribution": "{attribution.OpenStreetMap}",
399 | "variant": "hikebike"
400 | },
401 | "variants": {
402 | "HikeBike": {},
403 | "HillShading": {
404 | "options": {
405 | "maxZoom": 15,
406 | "variant": "hillshading"
407 | }
408 | }
409 | }
410 | },
411 | "BasemapAT": {
412 | "url": "//maps{s}.wien.gv.at/basemap/{variant}/normal/google3857/{z}/{y}/{x}.{format}",
413 | "options": {
414 | "maxZoom": 19,
415 | "attribution": "Datenquelle: basemap.at",
416 | "subdomains": ["", "1", "2", "3", "4"],
417 | "format": "png",
418 | "bounds": [[46.358770, 8.782379], [49.037872, 17.189532]],
419 | "variant": "geolandbasemap"
420 | },
421 | "variants": {
422 | "basemap": "geolandbasemap",
423 | "grau": "bmapgrau",
424 | "overlay": "bmapoverlay",
425 | "highdpi": {
426 | "options": {
427 | "variant": "bmaphidpi",
428 | "format": "jpeg"
429 | }
430 | },
431 | "orthofoto": {
432 | "options": {
433 | "variant": "bmaporthofoto30cm",
434 | "format": "jpeg"
435 | }
436 | }
437 | }
438 | },
439 | "NASAGIBS": {
440 | "url": "//map1.vis.earthdata.nasa.gov/wmts-webmerc/{variant}/default/{time}/{tilematrixset}{maxZoom}/{z}/{y}/{x}.{format}",
441 | "options": {
442 | "attribution":
443 | "Imagery provided by services from the Global Imagery Browse Services (GIBS), operated by the NASA/GSFC/Earth Science Data and Information System (ESDIS) with funding provided by NASA/HQ.",
444 | "bounds": [[-85.0511287776, -179.999999975], [85.0511287776, 179.999999975]],
445 | "minZoom": 1,
446 | "maxZoom": 9,
447 | "format": "jpg",
448 | "time": "",
449 | "tilematrixset": "GoogleMapsCompatible_Level"
450 | },
451 | "variants": {
452 | "ModisTerraTrueColorCR": "MODIS_Terra_CorrectedReflectance_TrueColor",
453 | "ModisTerraBands367CR": "MODIS_Terra_CorrectedReflectance_Bands367",
454 | "ViirsEarthAtNight2012": {
455 | "options": {
456 | "variant": "VIIRS_CityLights_2012",
457 | "maxZoom": 8
458 | }
459 | },
460 | "ModisTerraLSTDay": {
461 | "options": {
462 | "variant": "MODIS_Terra_Land_Surface_Temp_Day",
463 | "format": "png",
464 | "maxZoom": 7,
465 | "opacity": 0.75
466 | }
467 | },
468 | "ModisTerraSnowCover": {
469 | "options": {
470 | "variant": "MODIS_Terra_Snow_Cover",
471 | "format": "png",
472 | "maxZoom": 8,
473 | "opacity": 0.75
474 | }
475 | },
476 | "ModisTerraAOD": {
477 | "options": {
478 | "variant": "MODIS_Terra_Aerosol",
479 | "format": "png",
480 | "maxZoom": 6,
481 | "opacity": 0.75
482 | }
483 | },
484 | "ModisTerraChlorophyll": {
485 | "options": {
486 | "variant": "MODIS_Terra_Chlorophyll_A",
487 | "format": "png",
488 | "maxZoom": 7,
489 | "opacity": 0.75
490 | }
491 | }
492 | }
493 | },
494 | "NLS": {
495 | "url": "//nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg",
496 | "options": {
497 | "attribution": "National Library of Scotland Historic Maps",
498 | "bounds": [[49.6, -12], [61.7, 3]],
499 | "minZoom": 1,
500 | "maxZoom": 18,
501 | "subdomains": "0123"
502 | }
503 | }
504 | }
505 |
--------------------------------------------------------------------------------
/Materials/libs/leaflet-providers-plugin-1.1.0/leaflet-providers-plugin.js:
--------------------------------------------------------------------------------
1 | LeafletWidget.methods.addProviderTiles = function(provider, layerId, group, options) {
2 | this.layerManager.addLayer(L.tileLayer.provider(provider, options), "tile", layerId, group);
3 | };
4 |
--------------------------------------------------------------------------------
/Materials/libs/leafletfix-1.0.0/leafletfix.css:
--------------------------------------------------------------------------------
1 | /* Work around CSS properties introduced on img by bootstrap */
2 | img.leaflet-tile {
3 | padding: 0;
4 | margin: 0;
5 | border-radius: 0;
6 | border: none;
7 | }
8 | .info {
9 | padding: 6px 8px;
10 | font: 14px/16px Arial, Helvetica, sans-serif;
11 | background: white;
12 | background: rgba(255,255,255,0.8);
13 | box-shadow: 0 0 15px rgba(0,0,0,0.2);
14 | border-radius: 5px;
15 | }
16 | .legend {
17 | line-height: 18px;
18 | color: #555;
19 | }
20 | .legend svg text {
21 | fill: #555;
22 | }
23 | .legend svg line {
24 | stroke: #555;
25 | }
26 | .legend i {
27 | width: 18px;
28 | height: 18px;
29 | float: left;
30 | margin-right: 8px;
31 | opacity: 0.7;
32 | }
33 |
--------------------------------------------------------------------------------
/Materials/libs/remark-css-0.0.1/example.css:
--------------------------------------------------------------------------------
1 | @import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz);
2 | @import url(https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic);
3 | @import url(https://fonts.googleapis.com/css?family=Source+Code+Pro:400,700);
4 |
5 | body { font-family: 'Droid Serif', 'Palatino Linotype', 'Book Antiqua', Palatino, 'Microsoft YaHei', 'Songti SC', serif; }
6 | h1, h2, h3 {
7 | font-family: 'Yanone Kaffeesatz';
8 | font-weight: normal;
9 | }
10 | a, a > code {
11 | color: rgb(249, 38, 114);
12 | text-decoration: none;
13 | }
14 | .footnote {
15 | position: absolute;
16 | bottom: 3em;
17 | padding-right: 4em;
18 | font-size: 90%;
19 | }
20 | .remark-code, .remark-inline-code { font-family: 'Source Code Pro', 'Lucida Console', Monaco, monospace; }
21 | .remark-code-line-highlighted { background-color: #ffff88; }
22 |
23 | .inverse {
24 | background-color: #272822;
25 | color: #d6d6d6;
26 | text-shadow: 0 0 20px #333;
27 | }
28 | .inverse h1, .inverse h2, .inverse h3 {
29 | color: #f3f3f3;
30 | line-height: 1.0em;
31 | }
32 | /* Two-column layout */
33 | .left-column {
34 | color: #777;
35 | width: 20%;
36 | height: 92%;
37 | float: left;
38 | }
39 | .left-column h2:last-of-type, .left-column h3:last-child {
40 | color: #000;
41 | }
42 | .right-column {
43 | width: 75%;
44 | float: right;
45 | padding-top: 1em;
46 | }
47 | .pull-left {
48 | float: left;
49 | width: 47%;
50 | }
51 | .pull-right {
52 | float: right;
53 | width: 47%;
54 | }
55 | .pull-right ~ * {
56 | clear: both;
57 | }
58 | img, video, iframe {
59 | max-width: 100%;
60 | }
61 | blockquote {
62 | border-left: solid 5px lightgray;
63 | padding-left: 1em;
64 | }
65 | table {
66 | margin: auto;
67 | border-top: 1px solid #666;
68 | border-bottom: 1px solid #666;
69 | }
70 | table thead th { border-bottom: 1px solid #ddd; }
71 | th, td { padding: 5px; }
72 | thead, tfoot, tr:nth-child(even) { background: #eee }
73 |
74 | @page { margin: 0; }
75 | @media print {
76 | .remark-slide-scaler {
77 | width: 100% !important;
78 | height: 100% !important;
79 | transform: scale(1) !important;
80 | top: 0 !important;
81 | left: 0 !important;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Materials/macros.js:
--------------------------------------------------------------------------------
1 | remark.macros.scale = function (percentage) {
2 | var url = this;
3 | return '
';
4 | };
5 |
--------------------------------------------------------------------------------
/Materials/mtheme_max.css:
--------------------------------------------------------------------------------
1 | a, a > code {
2 | color: #ff0000;
3 | text-decoration: none;
4 | }
5 |
6 | .footnote {
7 | position: absolute;
8 | bottom: 3em;
9 | padding-right: 4em;
10 | font-size: 90%;
11 | }
12 | .remark-code-line-highlighted { background-color: #ffff88; }
13 |
14 | .remark-slide-content {
15 | background-color: #FAFAFA;
16 | border-top: 80px solid #23373B;
17 | font-size: 20px;
18 | font-weight: 300;
19 | line-height: 1.5;
20 | padding: 1em 2em 1em 2em
21 | }
22 |
23 | .title-slide .inverse .remark-slide-content {
24 | background-color: #FAFAFA;
25 | }
26 |
27 | .inverse {
28 | background-color: #23373B;
29 | text-shadow: none;
30 | }
31 | .inverse h1, .inverse h2, .inverse h3 {
32 | color: #f3f3f3;
33 | }
34 | /* Two-column layout */
35 | .left-column {
36 | color: #777;
37 | width: 20%;
38 | height: 92%;
39 | float: left;
40 | }
41 | .left-column h2:last-of-type, .left-column h3:last-child {
42 | color: #000;
43 | }
44 | .right-column {
45 | width: 75%;
46 | float: right;
47 | padding-top: 1em;
48 | }
49 | .pull-left {
50 | float: left;
51 | width: 47%;
52 | }
53 | .pull-right {
54 | float: right;
55 | width: 47%;
56 | }
57 | .pull-right ~ * {
58 | clear: both;
59 | }
60 | img, video, iframe {
61 | max-width: 100%;
62 | }
63 | blockquote {
64 | border-left: solid 5px lightgray;
65 | padding-left: 1em;
66 | }
67 | table {
68 | margin: auto;
69 | border-top: 1px solid #666;
70 | border-bottom: 1px solid #666;
71 | }
72 | table thead th { border-bottom: 1px solid #ddd; }
73 | th, td { padding: 5px; }
74 | thead, tfoot, tr:nth-child(even) { background: #eee }
75 |
76 | @page { margin: 0; }
77 | @media print {
78 | .remark-slide-scaler {
79 | width: 100% !important;
80 | height: 100% !important;
81 | transform: scale(1) !important;
82 | top: 0 !important;
83 | left: 0 !important;
84 | }
85 | }
86 |
87 | .remark-slide-content > h1 {
88 | font-family: 'Fira Sans';
89 | font-weight: normal;
90 | font-size: 45px;
91 | margin-top: -95px;
92 | margin-left: -00px;
93 | color: #FAFAFA;
94 | }
95 |
96 | .remark-slide-content > inverse {
97 | width: 112px;
98 | height: 47px;
99 | border-bottom: 1px solid black;
100 | position: absolute;
101 | }
102 |
103 | .remark-slide-content > h2 {
104 | padding-top: -15px;
105 | padding-bottom: 00px;
106 | color: #1A292C;
107 | text-shadow: none;
108 | font-weight: 400;
109 | font-size: 35px;
110 | text-align: left;
111 | margin-left: 00px;
112 | }
113 |
114 | .remark-slide-content > h3 {
115 | padding-top: -15px;
116 | padding-bottom: 10px;
117 | color: #1A292C;
118 | text-shadow: none;
119 | font-weight: 400;
120 | font-size: 30px;
121 | text-align: left;
122 | margin-left: 00px;
123 | }
124 |
125 | .title-slide {
126 | background-color: #FAFAFA;
127 | border-top: 80px solid #FAFAFA;
128 | }
129 |
130 | .title-slide > h1 {
131 | color: #1A292C;
132 | font-size: 40px;
133 | text-shadow: none;
134 | font-weight: 400;
135 | text-align: left;
136 | margin-left: 15px;
137 | padding-top: 80px;
138 | }
139 | .title-slide > h2 {
140 | margin-top: -25px;
141 | padding-bottom: -20px;
142 | color: #1A292C;
143 | text-shadow: none;
144 | font-weight: 300;
145 | font-size: 35px;
146 | text-align: left;
147 | margin-left: 15px;
148 | }
149 | .title-slide > h3 {
150 | color: #1A292C;
151 | text-shadow: none;
152 | font-weight: 300;
153 | font-size: 25px;
154 | text-align: left;
155 | margin-left: 15px;
156 | margin-bottom: -30px;
157 | }
158 |
159 | .remark-slide-number {
160 | font-size: 13pt;
161 | font-family: 'Fira Sans';
162 | color: #272822;
163 | opacity: 1;
164 | }
165 | .inverse .remark-slide-number {
166 | font-size: 13pt;
167 | font-family: 'Fira Sans';
168 | color: #FAFAFA;
169 | opacity: 1;
170 | }
171 |
172 | /* turns off slide numbers for title page: https://github.com/gnab/remark/issues/298 */
173 | .title-slide .remark-slide-number {
174 | display: none;
175 | }
176 |
177 |
178 |
179 | .title-hex{
180 | height: 60px;
181 | align: middle;
182 | float: right;
183 | }
184 |
185 |
--------------------------------------------------------------------------------
/Preparations/installs.R:
--------------------------------------------------------------------------------
1 | from_cran <-
2 | c("AmesHousing", "broom", "caret", "devtools", "doParallel", "e1071", "earth",
3 | "glmnet", "ipred", "klaR", "pROC", "rpart", "rsample", "sessioninfo",
4 | "tidyposterior", "tidyverse", "yardstick")
5 |
6 | install.packages(from_cran, repos = "http://cran.rstudio.com")
7 |
8 | library(devtools)
9 |
10 | install_github("topepo/recipes")
11 |
12 | # If you can install from source:
13 | install_github("topepo/caret", subdir = "pkg/caret")
14 |
15 | if(!interactive())
16 | q("no")
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # rstudio-conf-2017
2 | Slide, code and data for "Applied Machine Learning" at Rstudio-conf 2017
3 |
--------------------------------------------------------------------------------