├── .gitattributes ├── .gitignore ├── Flask_Starter_Code ├── Static │ ├── css │ │ ├── justin-flicks-cool-project.webflow.css │ │ ├── normalize.css │ │ └── webflow.css │ ├── images │ │ ├── UV9qmUi-p-500.png │ │ ├── UV9qmUi.png │ │ ├── fans-black-p-1080x606.jpeg │ │ ├── fans-black-p-1600x898.jpeg │ │ ├── fans-black-p-500x281.jpeg │ │ ├── fans-black-p-800x449.jpeg │ │ └── fans-black.jpg │ └── js │ │ └── webflow.js ├── Templates │ └── index.html └── minecraft_controller.py ├── Images ├── controller_screenshot.PNG ├── lava.jpg ├── leaves.png └── water.png ├── LICENSE ├── Lessons ├── Lesson1-Variables.md ├── Lesson2-If Statements.md ├── Lesson3-Loops.md ├── Lesson4-Functions.md └── Lesson5-Bringing It All Together with Flask.md ├── README.md └── requirements.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | 2 | Flask_Starter_Code/Static/* linguist-vendored 3 | Flask_Starter_Code/Templates/* linguist-vendored 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | 3 | instance/ 4 | .webassets-cache 5 | 6 | .env 7 | .venv 8 | env/ 9 | venv/ 10 | ENV/ 11 | env.bak/ 12 | venv.bak/ 13 | -------------------------------------------------------------------------------- /Flask_Starter_Code/Static/css/justin-flicks-cool-project.webflow.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 126px; 3 | background-color: #000; 4 | background-image: url('../images/fans-black.jpg'); 5 | background-size: cover; 6 | font-family: 'Roboto Condensed', sans-serif; 7 | color: #fff; 8 | font-size: 14px; 9 | line-height: 20px; 10 | text-align: center; 11 | } 12 | 13 | h1 { 14 | margin: 10px 0px; 15 | font-family: 'Roboto Condensed', sans-serif; 16 | color: #2d3338; 17 | font-size: 69px; 18 | line-height: 54px; 19 | font-style: normal; 20 | font-weight: 700; 21 | text-shadow: none; 22 | } 23 | 24 | h2 { 25 | margin: 0px 0px 10px; 26 | font-size: 32px; 27 | line-height: 36px; 28 | font-weight: 400; 29 | text-shadow: none; 30 | } 31 | 32 | h3 { 33 | margin: 5px 0px; 34 | font-size: 22px; 35 | line-height: 30px; 36 | font-weight: 400; 37 | text-shadow: none; 38 | } 39 | 40 | h4 { 41 | margin: 10px 0px; 42 | font-size: 18px; 43 | line-height: 24px; 44 | font-weight: 700; 45 | } 46 | 47 | h5 { 48 | margin: 10px 0px; 49 | font-size: 14px; 50 | line-height: 20px; 51 | font-weight: 700; 52 | } 53 | 54 | h6 { 55 | margin: 10px 0px; 56 | font-size: 12px; 57 | line-height: 18px; 58 | font-weight: 700; 59 | } 60 | 61 | p { 62 | margin-top: 0px; 63 | margin-bottom: 5px; 64 | font-size: 16px; 65 | line-height: 23px; 66 | font-weight: 300; 67 | letter-spacing: 0px; 68 | text-shadow: none; 69 | } 70 | 71 | .button { 72 | display: block; 73 | width: 100%; 74 | height: 54px; 75 | margin-left: -1px; 76 | padding: 4px 29px; 77 | border: 3px solid #fff; 78 | background-color: transparent; 79 | -webkit-transition: background-color 300ms ease, color 300ms ease; 80 | transition: background-color 300ms ease, color 300ms ease; 81 | color: #fff; 82 | font-size: 22px; 83 | font-weight: 700; 84 | text-align: center; 85 | text-decoration: none; 86 | text-transform: uppercase; 87 | } 88 | 89 | .button:hover { 90 | background-color: #fff; 91 | color: #000; 92 | } 93 | 94 | .subtitle { 95 | padding-bottom: 67px; 96 | font-family: 'Roboto Condensed', sans-serif; 97 | font-size: 31px; 98 | line-height: 35px; 99 | font-weight: 400; 100 | text-shadow: none; 101 | } 102 | 103 | .field { 104 | height: 54px; 105 | margin-bottom: 19px; 106 | padding-right: 20px; 107 | padding-left: 20px; 108 | border: 0px solid #000; 109 | -webkit-transition: box-shadow 150ms ease; 110 | transition: box-shadow 150ms ease; 111 | color: #262c46; 112 | font-size: 16px; 113 | text-align: center; 114 | text-transform: uppercase; 115 | } 116 | 117 | .field:focus { 118 | box-shadow: inset 0 0 0 2px #00caf2; 119 | } 120 | 121 | .sign-up-form { 122 | display: block; 123 | width: 415px; 124 | margin: 35px auto 66px; 125 | } 126 | 127 | .social-widget { 128 | width: 100px; 129 | float: left; 130 | -webkit-transition: opacity 300ms ease; 131 | transition: opacity 300ms ease; 132 | } 133 | 134 | .social-widget.full-opacity { 135 | opacity: 1; 136 | } 137 | 138 | .social-widget-wrapper { 139 | display: block; 140 | width: 223px; 141 | margin-right: auto; 142 | margin-left: auto; 143 | padding-left: 20px; 144 | } 145 | 146 | .social-widget-wrapper.thank-you { 147 | display: block; 148 | width: 216px; 149 | margin-top: 13px; 150 | margin-right: auto; 151 | margin-left: auto; 152 | padding-left: 16px; 153 | } 154 | 155 | .success-message { 156 | padding: 20px; 157 | border-radius: 2px; 158 | background-color: #737373; 159 | -webkit-transition: all 300ms ease; 160 | transition: all 300ms ease; 161 | } 162 | 163 | .spread-word { 164 | margin-top: 12px; 165 | font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; 166 | color: hsla(0, 0%, 100%, .6); 167 | font-size: 10px; 168 | line-height: 16px; 169 | font-weight: 400; 170 | letter-spacing: 0px; 171 | text-transform: uppercase; 172 | text-shadow: none; 173 | } 174 | 175 | .error-message { 176 | padding-bottom: 5px; 177 | border-radius: 2px; 178 | background-color: #5c3245; 179 | } 180 | 181 | .content-wrapper { 182 | display: inline-block; 183 | width: 60%; 184 | } 185 | 186 | .header-section { 187 | height: 100%; 188 | padding-top: 104px; 189 | background-color: #e0ddd7; 190 | text-align: center; 191 | } 192 | 193 | .footer-section { 194 | position: fixed; 195 | left: 0px; 196 | right: 0px; 197 | bottom: 0px; 198 | padding-top: 114px; 199 | padding-bottom: 0px; 200 | background-color: rgba(0, 0, 0, .18); 201 | color: #7e7c87; 202 | } 203 | 204 | .copyright { 205 | color: hsla(0, 0%, 100%, .52); 206 | text-align: left; 207 | } 208 | 209 | .bars-wrapper { 210 | height: 7px; 211 | background-color: #1abc9c; 212 | } 213 | 214 | .bar { 215 | width: 14.285%; 216 | height: 7px; 217 | float: left; 218 | background-color: #1abc9c; 219 | } 220 | 221 | .bar._2 { 222 | background-color: #f2ca27; 223 | } 224 | 225 | .bar._3 { 226 | background-color: #e67e22; 227 | } 228 | 229 | .bar._4 { 230 | background-color: #16a085; 231 | } 232 | 233 | .bar._5 { 234 | background-color: #2980b9; 235 | } 236 | 237 | .bar._6 { 238 | background-color: #e74c3c; 239 | } 240 | 241 | .bar._7 { 242 | background-color: #a366bc; 243 | } 244 | 245 | .container { 246 | padding-right: 127px; 247 | padding-left: 127px; 248 | background-color: rgba(0, 152, 255, 0); 249 | background-image: -webkit-linear-gradient(270deg, hsla(0, 25%, 94%, .43), hsla(0, 25%, 94%, .43)); 250 | background-image: linear-gradient(180deg, hsla(0, 25%, 94%, .43), hsla(0, 25%, 94%, .43)); 251 | } 252 | 253 | .image-crop { 254 | overflow: hidden; 255 | height: 260px; 256 | } 257 | 258 | .social-section { 259 | padding-top: 58px; 260 | padding-bottom: 58px; 261 | text-align: center; 262 | } 263 | 264 | .share-btn { 265 | display: inline-block; 266 | width: 61px; 267 | margin-right: 14px; 268 | margin-left: 14px; 269 | } 270 | 271 | .share-wrapper { 272 | margin-top: 32px; 273 | } 274 | 275 | .refer { 276 | color: hsla(0, 0%, 100%, .59); 277 | } 278 | 279 | .align-right { 280 | text-align: right; 281 | } 282 | 283 | .social-btn { 284 | margin-left: 17px; 285 | opacity: 0.44; 286 | -webkit-transition: all 200ms ease; 287 | transition: all 200ms ease; 288 | } 289 | 290 | .social-btn:hover { 291 | opacity: 1; 292 | } 293 | 294 | .logo { 295 | display: inline-block; 296 | margin: 68px auto 19px; 297 | padding: 21px; 298 | border: 8px solid #0f0202; 299 | color: hsla(0, 3%, 6%, .81); 300 | font-weight: 700; 301 | letter-spacing: 8px; 302 | text-shadow: none; 303 | } 304 | 305 | .about { 306 | font-family: 'Roboto Condensed', sans-serif; 307 | letter-spacing: 2px; 308 | text-transform: uppercase; 309 | } 310 | 311 | .join { 312 | display: block; 313 | width: 40%; 314 | margin-top: -12px; 315 | margin-bottom: 15px; 316 | float: left; 317 | font-size: 22px; 318 | letter-spacing: 4px; 319 | text-transform: uppercase; 320 | text-shadow: none; 321 | } 322 | 323 | .beta-line { 324 | width: 30%; 325 | height: 1px; 326 | float: left; 327 | background-color: hsla(0, 0%, 100%, .36); 328 | } 329 | 330 | .body { 331 | margin-right: 0px; 332 | background-image: url('../images/UV9qmUi.png'); 333 | } 334 | 335 | .button-5 { 336 | margin-left: 19px; 337 | padding-right: 45px; 338 | padding-left: 45px; 339 | background-color: #241b8b; 340 | } 341 | 342 | .button-2 { 343 | margin-left: -86px; 344 | padding-right: 45px; 345 | padding-left: 45px; 346 | background-color: #006904; 347 | } 348 | 349 | .button-3 { 350 | margin-left: 22px; 351 | padding-right: 45px; 352 | padding-left: 47px; 353 | background-color: #b84444; 354 | } 355 | 356 | .button-4 { 357 | margin-left: 19px; 358 | padding-right: 45px; 359 | padding-left: 45px; 360 | background-color: #bcd40b; 361 | } 362 | 363 | .form { 364 | margin-right: -53px; 365 | padding-right: 0px; 366 | } 367 | 368 | .text-block { 369 | padding-right: 16px; 370 | padding-left: 0px; 371 | color: #1b0303; 372 | font-size: 32px; 373 | } 374 | 375 | @media (max-width: 991px) { 376 | .subtitle { 377 | font-size: 29px; 378 | text-shadow: none; 379 | } 380 | .content-wrapper { 381 | width: 81%; 382 | } 383 | .container { 384 | padding-right: 57px; 385 | padding-left: 57px; 386 | } 387 | .social-btn { 388 | -webkit-transition: all 200ms ease; 389 | transition: all 200ms ease; 390 | } 391 | .social-btn:hover { 392 | opacity: 0.8; 393 | } 394 | .join { 395 | width: 50%; 396 | font-size: 21px; 397 | text-shadow: none; 398 | } 399 | .beta-line { 400 | width: 25%; 401 | } 402 | } 403 | 404 | @media (max-width: 767px) { 405 | body { 406 | padding-top: 65px; 407 | } 408 | .subtitle { 409 | margin-right: 0px; 410 | margin-left: 0px; 411 | padding-bottom: 43px; 412 | text-shadow: none; 413 | } 414 | .sign-up-form { 415 | margin-bottom: 64px; 416 | } 417 | .content-wrapper { 418 | width: 100%; 419 | padding-right: 24px; 420 | padding-left: 24px; 421 | } 422 | .header-section { 423 | padding-top: 37px; 424 | } 425 | .footer-section { 426 | position: static; 427 | padding-top: 23px; 428 | padding-bottom: 23px; 429 | background-color: rgba(0, 0, 0, .49); 430 | } 431 | .container { 432 | padding-right: 10px; 433 | padding-left: 10px; 434 | } 435 | .social-section { 436 | padding-top: 35px; 437 | padding-bottom: 35px; 438 | } 439 | .logo { 440 | text-shadow: none; 441 | } 442 | .join { 443 | text-shadow: none; 444 | } 445 | } 446 | 447 | @media (max-width: 479px) { 448 | h2 { 449 | font-size: 30px; 450 | line-height: 31px; 451 | text-shadow: none; 452 | } 453 | p { 454 | font-size: 20px; 455 | text-shadow: none; 456 | } 457 | .button { 458 | width: 100%; 459 | margin-left: 0px; 460 | border-top-left-radius: 2px; 461 | border-bottom-left-radius: 2px; 462 | } 463 | .subtitle { 464 | padding-bottom: 36px; 465 | font-size: 22px; 466 | line-height: 26px; 467 | text-shadow: none; 468 | } 469 | .field { 470 | width: 100%; 471 | border-top-right-radius: 2px; 472 | border-bottom-right-radius: 2px; 473 | text-align: center; 474 | } 475 | .sign-up-form { 476 | width: 100%; 477 | margin-top: 22px; 478 | } 479 | .social-widget { 480 | width: 96px; 481 | } 482 | .social-widget-wrapper { 483 | display: block; 484 | width: 221px; 485 | margin-right: auto; 486 | margin-bottom: 15px; 487 | margin-left: auto; 488 | } 489 | .copyright { 490 | margin-bottom: 16px; 491 | text-align: center; 492 | } 493 | .container { 494 | padding-right: 10px; 495 | padding-left: 10px; 496 | } 497 | .image-crop { 498 | height: auto; 499 | margin-bottom: 40px; 500 | } 501 | .social-section { 502 | padding-right: 14px; 503 | padding-left: 14px; 504 | } 505 | .align-right { 506 | text-align: center; 507 | } 508 | .social-btn { 509 | margin-right: 17px; 510 | } 511 | .logo { 512 | font-size: 43px; 513 | text-shadow: none; 514 | } 515 | .join { 516 | width: 75%; 517 | font-size: 19px; 518 | line-height: 22px; 519 | letter-spacing: 4px; 520 | text-shadow: none; 521 | } 522 | .beta-line { 523 | width: 12%; 524 | } 525 | } 526 | 527 | -------------------------------------------------------------------------------- /Flask_Starter_Code/Static/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ 2 | /** 3 | * 1. Set default font family to sans-serif. 4 | * 2. Prevent iOS and IE text size adjust after device orientation change, 5 | * without disabling user zoom. 6 | */ 7 | html { 8 | font-family: sans-serif; 9 | /* 1 */ 10 | -ms-text-size-adjust: 100%; 11 | /* 2 */ 12 | -webkit-text-size-adjust: 100%; 13 | /* 2 */ 14 | } 15 | /** 16 | * Remove default margin. 17 | */ 18 | body { 19 | margin: 0; 20 | } 21 | /* HTML5 display definitions 22 | ========================================================================== */ 23 | /** 24 | * Correct `block` display not defined for any HTML5 element in IE 8/9. 25 | * Correct `block` display not defined for `details` or `summary` in IE 10/11 26 | * and Firefox. 27 | * Correct `block` display not defined for `main` in IE 11. 28 | */ 29 | article, 30 | aside, 31 | details, 32 | figcaption, 33 | figure, 34 | footer, 35 | header, 36 | hgroup, 37 | main, 38 | menu, 39 | nav, 40 | section, 41 | summary { 42 | display: block; 43 | } 44 | /** 45 | * 1. Correct `inline-block` display not defined in IE 8/9. 46 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. 47 | */ 48 | audio, 49 | canvas, 50 | progress, 51 | video { 52 | display: inline-block; 53 | /* 1 */ 54 | vertical-align: baseline; 55 | /* 2 */ 56 | } 57 | /** 58 | * Prevent modern browsers from displaying `audio` without controls. 59 | * Remove excess height in iOS 5 devices. 60 | */ 61 | audio:not([controls]) { 62 | display: none; 63 | height: 0; 64 | } 65 | /** 66 | * Address `[hidden]` styling not present in IE 8/9/10. 67 | * Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22. 68 | */ 69 | [hidden], 70 | template { 71 | display: none; 72 | } 73 | /* Links 74 | ========================================================================== */ 75 | /** 76 | * Remove the gray background color from active links in IE 10. 77 | */ 78 | a { 79 | background-color: transparent; 80 | } 81 | /** 82 | * Improve readability of focused elements when they are also in an 83 | * active/hover state. 84 | */ 85 | a:active, 86 | a:hover { 87 | outline: 0; 88 | } 89 | /* Text-level semantics 90 | ========================================================================== */ 91 | /** 92 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome. 93 | */ 94 | abbr[title] { 95 | border-bottom: 1px dotted; 96 | } 97 | /** 98 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. 99 | */ 100 | b, 101 | strong { 102 | font-weight: bold; 103 | } 104 | /** 105 | * Address styling not present in Safari and Chrome. 106 | */ 107 | dfn { 108 | font-style: italic; 109 | } 110 | /** 111 | * Address variable `h1` font-size and margin within `section` and `article` 112 | * contexts in Firefox 4+, Safari, and Chrome. 113 | */ 114 | h1 { 115 | font-size: 2em; 116 | margin: 0.67em 0; 117 | } 118 | /** 119 | * Address styling not present in IE 8/9. 120 | */ 121 | mark { 122 | background: #ff0; 123 | color: #000; 124 | } 125 | /** 126 | * Address inconsistent and variable font size in all browsers. 127 | */ 128 | small { 129 | font-size: 80%; 130 | } 131 | /** 132 | * Prevent `sub` and `sup` affecting `line-height` in all browsers. 133 | */ 134 | sub, 135 | sup { 136 | font-size: 75%; 137 | line-height: 0; 138 | position: relative; 139 | vertical-align: baseline; 140 | } 141 | sup { 142 | top: -0.5em; 143 | } 144 | sub { 145 | bottom: -0.25em; 146 | } 147 | /* Embedded content 148 | ========================================================================== */ 149 | /** 150 | * Remove border when inside `a` element in IE 8/9/10. 151 | */ 152 | img { 153 | border: 0; 154 | } 155 | /** 156 | * Correct overflow not hidden in IE 9/10/11. 157 | */ 158 | svg:not(:root) { 159 | overflow: hidden; 160 | } 161 | /* Grouping content 162 | ========================================================================== */ 163 | /** 164 | * Address margin not present in IE 8/9 and Safari. 165 | */ 166 | figure { 167 | margin: 1em 40px; 168 | } 169 | /** 170 | * Address differences between Firefox and other browsers. 171 | */ 172 | hr { 173 | box-sizing: content-box; 174 | height: 0; 175 | } 176 | /** 177 | * Contain overflow in all browsers. 178 | */ 179 | pre { 180 | overflow: auto; 181 | } 182 | /** 183 | * Address odd `em`-unit font size rendering in all browsers. 184 | */ 185 | code, 186 | kbd, 187 | pre, 188 | samp { 189 | font-family: monospace, monospace; 190 | font-size: 1em; 191 | } 192 | /* Forms 193 | ========================================================================== */ 194 | /** 195 | * Known limitation: by default, Chrome and Safari on OS X allow very limited 196 | * styling of `select`, unless a `border` property is set. 197 | */ 198 | /** 199 | * 1. Correct color not being inherited. 200 | * Known issue: affects color of disabled elements. 201 | * 2. Correct font properties not being inherited. 202 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. 203 | */ 204 | button, 205 | input, 206 | optgroup, 207 | select, 208 | textarea { 209 | color: inherit; 210 | /* 1 */ 211 | font: inherit; 212 | /* 2 */ 213 | margin: 0; 214 | /* 3 */ 215 | } 216 | /** 217 | * Address `overflow` set to `hidden` in IE 8/9/10/11. 218 | */ 219 | button { 220 | overflow: visible; 221 | } 222 | /** 223 | * Address inconsistent `text-transform` inheritance for `button` and `select`. 224 | * All other form control elements do not inherit `text-transform` values. 225 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. 226 | * Correct `select` style inheritance in Firefox. 227 | */ 228 | button, 229 | select { 230 | text-transform: none; 231 | } 232 | /** 233 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 234 | * and `video` controls. 235 | * 2. Correct inability to style clickable `input` types in iOS. 236 | * 3. Improve usability and consistency of cursor style between image-type 237 | * `input` and others. 238 | * 4. CUSTOM FOR WEBFLOW: Removed the input[type="submit"] selector to reduce 239 | * specificity and defer to the .w-button selector 240 | */ 241 | button, 242 | html input[type="button"], 243 | input[type="reset"] { 244 | -webkit-appearance: button; 245 | /* 2 */ 246 | cursor: pointer; 247 | /* 3 */ 248 | } 249 | /** 250 | * Re-set default cursor for disabled elements. 251 | */ 252 | button[disabled], 253 | html input[disabled] { 254 | cursor: default; 255 | } 256 | /** 257 | * Remove inner padding and border in Firefox 4+. 258 | */ 259 | button::-moz-focus-inner, 260 | input::-moz-focus-inner { 261 | border: 0; 262 | padding: 0; 263 | } 264 | /** 265 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in 266 | * the UA stylesheet. 267 | */ 268 | input { 269 | line-height: normal; 270 | } 271 | /** 272 | * It's recommended that you don't attempt to style these elements. 273 | * Firefox's implementation doesn't respect box-sizing, padding, or width. 274 | * 275 | * 1. Address box sizing set to `content-box` in IE 8/9/10. 276 | * 2. Remove excess padding in IE 8/9/10. 277 | */ 278 | input[type="checkbox"], 279 | input[type="radio"] { 280 | box-sizing: border-box; 281 | /* 1 */ 282 | padding: 0; 283 | /* 2 */ 284 | } 285 | /** 286 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain 287 | * `font-size` values of the `input`, it causes the cursor style of the 288 | * decrement button to change from `default` to `text`. 289 | */ 290 | input[type="number"]::-webkit-inner-spin-button, 291 | input[type="number"]::-webkit-outer-spin-button { 292 | height: auto; 293 | } 294 | /** 295 | * 1. CUSTOM FOR WEBFLOW: changed from `textfield` to `none` to normalize iOS rounded input 296 | * 2. CUSTOM FOR WEBFLOW: box-sizing: content-box rule removed 297 | * (similar to normalize.css >=4.0.0) 298 | */ 299 | input[type="search"] { 300 | -webkit-appearance: none; 301 | /* 1 */ 302 | } 303 | /** 304 | * Remove inner padding and search cancel button in Safari and Chrome on OS X. 305 | * Safari (but not Chrome) clips the cancel button when the search input has 306 | * padding (and `textfield` appearance). 307 | */ 308 | input[type="search"]::-webkit-search-cancel-button, 309 | input[type="search"]::-webkit-search-decoration { 310 | -webkit-appearance: none; 311 | } 312 | /** 313 | * Define consistent border, margin, and padding. 314 | */ 315 | fieldset { 316 | border: 1px solid #c0c0c0; 317 | margin: 0 2px; 318 | padding: 0.35em 0.625em 0.75em; 319 | } 320 | /** 321 | * 1. Correct `color` not being inherited in IE 8/9/10/11. 322 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 323 | */ 324 | legend { 325 | border: 0; 326 | /* 1 */ 327 | padding: 0; 328 | /* 2 */ 329 | } 330 | /** 331 | * Remove default vertical scrollbar in IE 8/9/10/11. 332 | */ 333 | textarea { 334 | overflow: auto; 335 | } 336 | /** 337 | * Don't inherit the `font-weight` (applied by a rule above). 338 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. 339 | */ 340 | optgroup { 341 | font-weight: bold; 342 | } 343 | /* Tables 344 | ========================================================================== */ 345 | /** 346 | * Remove most spacing between table cells. 347 | */ 348 | table { 349 | border-collapse: collapse; 350 | border-spacing: 0; 351 | } 352 | td, 353 | th { 354 | padding: 0; 355 | } 356 | -------------------------------------------------------------------------------- /Flask_Starter_Code/Static/css/webflow.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'webflow-icons'; 3 | src: url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg6SAy0AAAC8AAAAYGNtYXAaVcxaAAABHAAAAExnYXNwAAAAEAAAAWgAAAAIZ2x5ZgscV1gAAAFwAAABhGhlYWQCkFKvAAAC9AAAADZoaGVhB0MDyQAAAywAAAAkaG10eBIAA10AAANQAAAAIGxvY2EBMADyAAADcAAAABJtYXhwAAwATQAAA4QAAAAgbmFtZWTuiIAAAAOkAAABe3Bvc3QAAwAAAAAFIAAAACAAAwQAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADmAwPA/8D/wAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAACAAAAAwAAABQAAwABAAAAFAAEADgAAAAKAAgAAgACAAEAIOYD//3//wAAAAAAIOYA//3//wAB/+MaBAADAAEAAAAAAAAAAAAAAAEAAf//AA8AAQAAAAAAAAAAAAIAADc5AQAAAAABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQEgAAADIAOAAAUAAAkBBwkBFwMg/kBAAYD+gEABwAHAQP6A/oBAAAEA4AAAAuADgAAFAAATARcJAQfgAcBA/oABgEABwAHAQP6A/oBAAAADAMAA4ANAAsAAGAAxAEoAAAEhIg4CHQEUHgIzITI+Aj0BNC4CIxUhIg4CHQEUHgIzITI+Aj0BNC4CIxUhIg4CHQEUHgIzITI+Aj0BNC4CIwMg/cAHCwkFBQkLBwJABwsJBQUJCwf9wAcLCQUFCQsHAkAHCwkFBQkLB/3ABwsJBQUJCwcCQAcLCQUFCQsHAsAFCQsHIAcLCQUFCQsHIAcLCQXABQkLByAHCwkFBQkLByAHCwkFwAUJCwcgBwsJBQUJCwcgBwsJBQAAAAABAJ0AtAOBApUABQAACQIHCQEDJP7r/upcAXEBcgKU/usBFFv+egGGAAAAAAEAAAABAADSLAJOXw889QALBAAAAAAAz/iHGQAAAADP+IcZAAAAAAOBA4AAAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAAAAA4EAAQAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAACAAAABAABIAQAAOAEAADABAAAnQAAAAAACgAUAB4AMgBGAKwAwgAAAAEAAAAIAEsAAwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAOAK4AAQAAAAAAAQAaAAAAAQAAAAAAAgAOAHEAAQAAAAAAAwAaADAAAQAAAAAABAAaAH8AAQAAAAAABQAWABoAAQAAAAAABgANAEoAAQAAAAAACgA0AJkAAwABBAkAAQAaAAAAAwABBAkAAgAOAHEAAwABBAkAAwAaADAAAwABBAkABAAaAH8AAwABBAkABQAWABoAAwABBAkABgAaAFcAAwABBAkACgA0AJkAdwBlAGIAZgBsAG8AdwAtAGkAYwBvAG4AcwBWAGUAcgBzAGkAbwBuACAAMQAuADAAdwBlAGIAZgBsAG8AdwAtAGkAYwBvAG4Ac3dlYmZsb3ctaWNvbnMAdwBlAGIAZgBsAG8AdwAtAGkAYwBvAG4AcwBSAGUAZwB1AGwAYQByAHcAZQBiAGYAbABvAHcALQBpAGMAbwBuAHMARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAuAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format('truetype'), url(data:application/font-woff;charset=utf-8;base64,d09GRk9UVE8AAAVcAAoAAAAABRQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAAA9AAAAZMAAAGTuzUomU9TLzIAAAKIAAAAYAAAAGAOkgMtY21hcAAAAugAAABMAAAATBpVzFpnYXNwAAADNAAAAAgAAAAIAAAAEGhlYWQAAAM8AAAANgAAADYCkFKvaGhlYQAAA3QAAAAkAAAAJAdDA8lobXR4AAADmAAAACAAAAAgEgADXW1heHAAAAO4AAAABgAAAAYACFAAbmFtZQAAA8AAAAF7AAABe2TuiIBwb3N0AAAFPAAAACAAAAAgAAMAAAEABAQAAQEBDndlYmZsb3ctaWNvbnMAAQIAAQA6+BwC+BsD+BgEHgoACXf/i4seCgAJd/+LiwwHi0v6lPpUBR0AAACaDx0AAACfER0AAAAJHQAAAYoSAAkBAQ4bHR8iJywxNndlYmZsb3ctaWNvbnN3ZWJmbG93LWljb25zdTB1MXUyMHVFNjAwdUU2MDF1RTYwMnVFNjAzAAACAYkABgAIAQEEBwoNJDvH4P6UDv6UDv6UDvyUDvm0+FQV/FT4VEtL+BT8FPwU/BTLSwUO93T4VBX4VPhUy0v8FPwU+BT8FEtLBQ75tPlUFfzUiwV5i319i3kIi2sFi3mZfZ2LCPjUiwWdi5mZi50Ii6sFi519mXmLCIv7VBX81IsFeYt9fYt5CItrBYt5mX2diwj41IsFnYuZmYudCIurBYudfZl5iwiL+1QV/NSLBXmLfX2LeQiLawWLeZl9nYsI+NSLBZ2LmZmLnQiLqwWLnX2ZeYsIDvm4+SkV+6n7qvuq96ovLvgG/Bj4BvgYBQ76lBT6lBWLDAoAAAMEAAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAA5gMDwP/A/8ADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAgAAAAMAAAAUAAMAAQAAABQABAA4AAAACgAIAAIAAgABACDmA//9//8AAAAAACDmAP/9//8AAf/jGgQAAwABAAAAAAAAAAAAAAABAAH//wAPAAEAAAABAAC1pQTjXw889QALBAAAAAAAz/iHGQAAAADP+IcZAAAAAAOBA4AAAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAAAAA4EAAQAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAACAAAABAABIAQAAOAEAADABAAAnQAAUAAACAAAAAAADgCuAAEAAAAAAAEAGgAAAAEAAAAAAAIADgBxAAEAAAAAAAMAGgAwAAEAAAAAAAQAGgB/AAEAAAAAAAUAFgAaAAEAAAAAAAYADQBKAAEAAAAAAAoANACZAAMAAQQJAAEAGgAAAAMAAQQJAAIADgBxAAMAAQQJAAMAGgAwAAMAAQQJAAQAGgB/AAMAAQQJAAUAFgAaAAMAAQQJAAYAGgBXAAMAAQQJAAoANACZAHcAZQBiAGYAbABvAHcALQBpAGMAbwBuAHMAVgBlAHIAcwBpAG8AbgAgADEALgAwAHcAZQBiAGYAbABvAHcALQBpAGMAbwBuAHN3ZWJmbG93LWljb25zAHcAZQBiAGYAbABvAHcALQBpAGMAbwBuAHMAUgBlAGcAdQBsAGEAcgB3AGUAYgBmAGwAbwB3AC0AaQBjAG8AbgBzAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format('woff'); 4 | font-weight: normal; 5 | font-style: normal; 6 | } 7 | [class^="w-icon-"], 8 | [class*=" w-icon-"] { 9 | font-family: 'webflow-icons'; 10 | speak: none; 11 | font-style: normal; 12 | font-weight: normal; 13 | font-variant: normal; 14 | text-transform: none; 15 | line-height: 1; 16 | -webkit-font-smoothing: antialiased; 17 | -moz-osx-font-smoothing: grayscale; 18 | } 19 | .w-icon-slider-right:before { 20 | content: "\e600"; 21 | } 22 | .w-icon-slider-left:before { 23 | content: "\e601"; 24 | } 25 | .w-icon-nav-menu:before { 26 | content: "\e602"; 27 | } 28 | .w-icon-arrow-down:before, 29 | .w-icon-dropdown-toggle:before { 30 | content: "\e603"; 31 | } 32 | * { 33 | -webkit-box-sizing: border-box; 34 | -moz-box-sizing: border-box; 35 | box-sizing: border-box; 36 | } 37 | html { 38 | height: 100%; 39 | } 40 | body { 41 | margin: 0; 42 | min-height: 100%; 43 | background-color: #fff; 44 | font-family: Arial, sans-serif; 45 | font-size: 14px; 46 | line-height: 20px; 47 | color: #333; 48 | } 49 | img { 50 | max-width: 100%; 51 | vertical-align: middle; 52 | display: inline-block; 53 | } 54 | html.w-mod-touch * { 55 | background-attachment: scroll !important; 56 | } 57 | .w-block { 58 | display: block; 59 | } 60 | .w-inline-block { 61 | max-width: 100%; 62 | display: inline-block; 63 | } 64 | .w-clearfix:before, 65 | .w-clearfix:after { 66 | content: " "; 67 | display: table; 68 | } 69 | .w-clearfix:after { 70 | clear: both; 71 | } 72 | .w-hidden { 73 | display: none; 74 | } 75 | .w-button { 76 | display: inline-block; 77 | padding: 9px 15px; 78 | background-color: #3898EC; 79 | color: white; 80 | border: 0; 81 | line-height: inherit; 82 | text-decoration: none; 83 | cursor: pointer; 84 | border-radius: 0; 85 | } 86 | input.w-button { 87 | -webkit-appearance: button; 88 | } 89 | html[data-w-dynpage] [data-w-cloak] { 90 | color: transparent !important; 91 | } 92 | .w-webflow-badge, 93 | .w-webflow-badge * { 94 | position: static; 95 | left: auto; 96 | top: auto; 97 | right: auto; 98 | bottom: auto; 99 | z-index: auto; 100 | display: block; 101 | visibility: visible; 102 | overflow: visible; 103 | overflow-x: visible; 104 | overflow-y: visible; 105 | box-sizing: border-box; 106 | width: auto; 107 | height: auto; 108 | max-height: none; 109 | max-width: none; 110 | min-height: 0; 111 | min-width: 0; 112 | margin: 0; 113 | padding: 0; 114 | float: none; 115 | clear: none; 116 | border: 0 none transparent; 117 | border-radius: 0; 118 | background: none; 119 | background-image: none; 120 | background-position: 0% 0%; 121 | background-size: auto auto; 122 | background-repeat: repeat; 123 | background-origin: padding-box; 124 | background-clip: border-box; 125 | background-attachment: scroll; 126 | background-color: transparent; 127 | box-shadow: none; 128 | opacity: 1.0; 129 | transform: none; 130 | transition: none; 131 | direction: ltr; 132 | font-family: inherit; 133 | font-weight: inherit; 134 | color: inherit; 135 | font-size: inherit; 136 | line-height: inherit; 137 | font-style: inherit; 138 | font-variant: inherit; 139 | text-align: inherit; 140 | letter-spacing: inherit; 141 | text-decoration: inherit; 142 | text-indent: 0; 143 | text-transform: inherit; 144 | list-style-type: disc; 145 | text-shadow: none; 146 | font-smoothing: auto; 147 | vertical-align: baseline; 148 | cursor: inherit; 149 | white-space: inherit; 150 | word-break: normal; 151 | word-spacing: normal; 152 | word-wrap: normal; 153 | } 154 | .w-webflow-badge { 155 | position: fixed !important; 156 | display: inline-block !important; 157 | visibility: visible !important; 158 | opacity: 1 !important; 159 | z-index: 2147483647 !important; 160 | top: auto !important; 161 | right: 12px !important; 162 | bottom: 12px !important; 163 | left: auto !important; 164 | color: #AAADB0 !important; 165 | background-color: #fff !important; 166 | border-radius: 3px !important; 167 | padding: 6px 8px 6px 6px !important; 168 | font-size: 12px !important; 169 | opacity: 1.0 !important; 170 | line-height: 14px !important; 171 | text-decoration: none !important; 172 | transform: none !important; 173 | margin: 0 !important; 174 | width: auto !important; 175 | height: auto !important; 176 | overflow: visible !important; 177 | white-space: nowrap; 178 | box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1), 0px 1px 3px rgba(0, 0, 0, 0.1); 179 | } 180 | .w-webflow-badge > img { 181 | display: inline-block !important; 182 | visibility: visible !important; 183 | opacity: 1 !important; 184 | vertical-align: middle !important; 185 | } 186 | h1, 187 | h2, 188 | h3, 189 | h4, 190 | h5, 191 | h6 { 192 | font-weight: bold; 193 | margin-bottom: 10px; 194 | } 195 | h1 { 196 | font-size: 38px; 197 | line-height: 44px; 198 | margin-top: 20px; 199 | } 200 | h2 { 201 | font-size: 32px; 202 | line-height: 36px; 203 | margin-top: 20px; 204 | } 205 | h3 { 206 | font-size: 24px; 207 | line-height: 30px; 208 | margin-top: 20px; 209 | } 210 | h4 { 211 | font-size: 18px; 212 | line-height: 24px; 213 | margin-top: 10px; 214 | } 215 | h5 { 216 | font-size: 14px; 217 | line-height: 20px; 218 | margin-top: 10px; 219 | } 220 | h6 { 221 | font-size: 12px; 222 | line-height: 18px; 223 | margin-top: 10px; 224 | } 225 | p { 226 | margin-top: 0; 227 | margin-bottom: 10px; 228 | } 229 | blockquote { 230 | margin: 0 0 10px 0; 231 | padding: 10px 20px; 232 | border-left: 5px solid #E2E2E2; 233 | font-size: 18px; 234 | line-height: 22px; 235 | } 236 | figure { 237 | margin: 0; 238 | margin-bottom: 10px; 239 | } 240 | figcaption { 241 | margin-top: 5px; 242 | text-align: center; 243 | } 244 | ul, 245 | ol { 246 | margin-top: 0px; 247 | margin-bottom: 10px; 248 | padding-left: 40px; 249 | } 250 | .w-list-unstyled { 251 | padding-left: 0; 252 | list-style: none; 253 | } 254 | .w-embed:before, 255 | .w-embed:after { 256 | content: " "; 257 | display: table; 258 | } 259 | .w-embed:after { 260 | clear: both; 261 | } 262 | .w-video { 263 | width: 100%; 264 | position: relative; 265 | padding: 0; 266 | } 267 | .w-video iframe, 268 | .w-video object, 269 | .w-video embed { 270 | position: absolute; 271 | top: 0; 272 | left: 0; 273 | width: 100%; 274 | height: 100%; 275 | } 276 | fieldset { 277 | padding: 0; 278 | margin: 0; 279 | border: 0; 280 | } 281 | button, 282 | html input[type="button"], 283 | input[type="reset"] { 284 | border: 0; 285 | cursor: pointer; 286 | -webkit-appearance: button; 287 | } 288 | .w-form { 289 | margin: 0 0 15px; 290 | } 291 | .w-form-done { 292 | display: none; 293 | padding: 20px; 294 | text-align: center; 295 | background-color: #dddddd; 296 | } 297 | .w-form-fail { 298 | display: none; 299 | margin-top: 10px; 300 | padding: 10px; 301 | background-color: #ffdede; 302 | } 303 | label { 304 | display: block; 305 | margin-bottom: 5px; 306 | font-weight: bold; 307 | } 308 | .w-input, 309 | .w-select { 310 | display: block; 311 | width: 100%; 312 | height: 38px; 313 | padding: 8px 12px; 314 | margin-bottom: 10px; 315 | font-size: 14px; 316 | line-height: 1.428571429; 317 | color: #333333; 318 | vertical-align: middle; 319 | background-color: #ffffff; 320 | border: 1px solid #cccccc; 321 | } 322 | .w-input:-moz-placeholder, 323 | .w-select:-moz-placeholder { 324 | color: #999; 325 | } 326 | .w-input::-moz-placeholder, 327 | .w-select::-moz-placeholder { 328 | color: #999; 329 | opacity: 1; 330 | } 331 | .w-input:-ms-input-placeholder, 332 | .w-select:-ms-input-placeholder { 333 | color: #999; 334 | } 335 | .w-input::-webkit-input-placeholder, 336 | .w-select::-webkit-input-placeholder { 337 | color: #999; 338 | } 339 | .w-input:focus, 340 | .w-select:focus { 341 | border-color: #3898EC; 342 | outline: 0; 343 | } 344 | .w-input[disabled], 345 | .w-select[disabled], 346 | .w-input[readonly], 347 | .w-select[readonly], 348 | fieldset[disabled] .w-input, 349 | fieldset[disabled] .w-select { 350 | cursor: not-allowed; 351 | background-color: #eeeeee; 352 | } 353 | textarea.w-input, 354 | textarea.w-select { 355 | height: auto; 356 | } 357 | .w-select { 358 | background-image: -webkit-linear-gradient(white 0%, #f3f3f3 100%); 359 | background-image: linear-gradient(white 0%, #f3f3f3 100%); 360 | } 361 | .w-select[multiple] { 362 | height: auto; 363 | } 364 | .w-form-label { 365 | display: inline-block; 366 | cursor: pointer; 367 | font-weight: normal; 368 | margin-bottom: 0px; 369 | } 370 | .w-checkbox, 371 | .w-radio { 372 | display: block; 373 | margin-bottom: 5px; 374 | padding-left: 20px; 375 | } 376 | .w-checkbox:before, 377 | .w-radio:before, 378 | .w-checkbox:after, 379 | .w-radio:after { 380 | content: " "; 381 | display: table; 382 | } 383 | .w-checkbox:after, 384 | .w-radio:after { 385 | clear: both; 386 | } 387 | .w-checkbox-input, 388 | .w-radio-input { 389 | margin: 4px 0 0; 390 | margin-top: 1px \9; 391 | line-height: normal; 392 | float: left; 393 | margin-left: -20px; 394 | } 395 | .w-radio-input { 396 | margin-top: 3px; 397 | } 398 | .w-container { 399 | margin-left: auto; 400 | margin-right: auto; 401 | max-width: 940px; 402 | } 403 | .w-container:before, 404 | .w-container:after { 405 | content: " "; 406 | display: table; 407 | } 408 | .w-container:after { 409 | clear: both; 410 | } 411 | .w-container .w-row { 412 | margin-left: -10px; 413 | margin-right: -10px; 414 | } 415 | .w-row:before, 416 | .w-row:after { 417 | content: " "; 418 | display: table; 419 | } 420 | .w-row:after { 421 | clear: both; 422 | } 423 | .w-row .w-row { 424 | margin-left: 0; 425 | margin-right: 0; 426 | } 427 | .w-col { 428 | position: relative; 429 | float: left; 430 | width: 100%; 431 | min-height: 1px; 432 | padding-left: 10px; 433 | padding-right: 10px; 434 | } 435 | .w-col .w-col { 436 | padding-left: 0; 437 | padding-right: 0; 438 | } 439 | .w-col-1 { 440 | width: 8.33333333%; 441 | } 442 | .w-col-2 { 443 | width: 16.66666667%; 444 | } 445 | .w-col-3 { 446 | width: 25%; 447 | } 448 | .w-col-4 { 449 | width: 33.33333333%; 450 | } 451 | .w-col-5 { 452 | width: 41.66666667%; 453 | } 454 | .w-col-6 { 455 | width: 50%; 456 | } 457 | .w-col-7 { 458 | width: 58.33333333%; 459 | } 460 | .w-col-8 { 461 | width: 66.66666667%; 462 | } 463 | .w-col-9 { 464 | width: 75%; 465 | } 466 | .w-col-10 { 467 | width: 83.33333333%; 468 | } 469 | .w-col-11 { 470 | width: 91.66666667%; 471 | } 472 | .w-col-12 { 473 | width: 100%; 474 | } 475 | .w-hidden-main { 476 | display: none !important; 477 | } 478 | @media screen and (max-width: 991px) { 479 | .w-container { 480 | max-width: 728px; 481 | } 482 | .w-hidden-main { 483 | display: inherit !important; 484 | } 485 | .w-hidden-medium { 486 | display: none !important; 487 | } 488 | .w-col-medium-1 { 489 | width: 8.33333333%; 490 | } 491 | .w-col-medium-2 { 492 | width: 16.66666667%; 493 | } 494 | .w-col-medium-3 { 495 | width: 25%; 496 | } 497 | .w-col-medium-4 { 498 | width: 33.33333333%; 499 | } 500 | .w-col-medium-5 { 501 | width: 41.66666667%; 502 | } 503 | .w-col-medium-6 { 504 | width: 50%; 505 | } 506 | .w-col-medium-7 { 507 | width: 58.33333333%; 508 | } 509 | .w-col-medium-8 { 510 | width: 66.66666667%; 511 | } 512 | .w-col-medium-9 { 513 | width: 75%; 514 | } 515 | .w-col-medium-10 { 516 | width: 83.33333333%; 517 | } 518 | .w-col-medium-11 { 519 | width: 91.66666667%; 520 | } 521 | .w-col-medium-12 { 522 | width: 100%; 523 | } 524 | .w-col-stack { 525 | width: 100%; 526 | left: auto; 527 | right: auto; 528 | } 529 | } 530 | @media screen and (max-width: 767px) { 531 | .w-hidden-main { 532 | display: inherit !important; 533 | } 534 | .w-hidden-medium { 535 | display: inherit !important; 536 | } 537 | .w-hidden-small { 538 | display: none !important; 539 | } 540 | .w-row, 541 | .w-container .w-row { 542 | margin-left: 0; 543 | margin-right: 0; 544 | } 545 | .w-col { 546 | width: 100%; 547 | left: auto; 548 | right: auto; 549 | } 550 | .w-col-small-1 { 551 | width: 8.33333333%; 552 | } 553 | .w-col-small-2 { 554 | width: 16.66666667%; 555 | } 556 | .w-col-small-3 { 557 | width: 25%; 558 | } 559 | .w-col-small-4 { 560 | width: 33.33333333%; 561 | } 562 | .w-col-small-5 { 563 | width: 41.66666667%; 564 | } 565 | .w-col-small-6 { 566 | width: 50%; 567 | } 568 | .w-col-small-7 { 569 | width: 58.33333333%; 570 | } 571 | .w-col-small-8 { 572 | width: 66.66666667%; 573 | } 574 | .w-col-small-9 { 575 | width: 75%; 576 | } 577 | .w-col-small-10 { 578 | width: 83.33333333%; 579 | } 580 | .w-col-small-11 { 581 | width: 91.66666667%; 582 | } 583 | .w-col-small-12 { 584 | width: 100%; 585 | } 586 | } 587 | @media screen and (max-width: 479px) { 588 | .w-container { 589 | max-width: none; 590 | } 591 | .w-hidden-main { 592 | display: inherit !important; 593 | } 594 | .w-hidden-medium { 595 | display: inherit !important; 596 | } 597 | .w-hidden-small { 598 | display: inherit !important; 599 | } 600 | .w-hidden-tiny { 601 | display: none !important; 602 | } 603 | .w-col { 604 | width: 100%; 605 | } 606 | .w-col-tiny-1 { 607 | width: 8.33333333%; 608 | } 609 | .w-col-tiny-2 { 610 | width: 16.66666667%; 611 | } 612 | .w-col-tiny-3 { 613 | width: 25%; 614 | } 615 | .w-col-tiny-4 { 616 | width: 33.33333333%; 617 | } 618 | .w-col-tiny-5 { 619 | width: 41.66666667%; 620 | } 621 | .w-col-tiny-6 { 622 | width: 50%; 623 | } 624 | .w-col-tiny-7 { 625 | width: 58.33333333%; 626 | } 627 | .w-col-tiny-8 { 628 | width: 66.66666667%; 629 | } 630 | .w-col-tiny-9 { 631 | width: 75%; 632 | } 633 | .w-col-tiny-10 { 634 | width: 83.33333333%; 635 | } 636 | .w-col-tiny-11 { 637 | width: 91.66666667%; 638 | } 639 | .w-col-tiny-12 { 640 | width: 100%; 641 | } 642 | } 643 | .w-widget { 644 | position: relative; 645 | } 646 | .w-widget-map { 647 | width: 100%; 648 | height: 400px; 649 | } 650 | .w-widget-map label { 651 | width: auto; 652 | display: inline; 653 | } 654 | .w-widget-map img { 655 | max-width: inherit; 656 | } 657 | .w-widget-map .gm-style-iw { 658 | width: 90% !important; 659 | height: auto !important; 660 | top: 7px !important; 661 | left: 6% !important; 662 | display: inline; 663 | text-align: center; 664 | overflow: hidden; 665 | } 666 | .w-widget-map .gm-style-iw + div { 667 | display: none; 668 | } 669 | .w-widget-twitter { 670 | overflow: hidden; 671 | } 672 | .w-widget-twitter-count-shim { 673 | display: inline-block; 674 | vertical-align: top; 675 | position: relative; 676 | width: 28px; 677 | height: 20px; 678 | text-align: center; 679 | background: white; 680 | border: #758696 solid 1px; 681 | border-radius: 3px; 682 | } 683 | .w-widget-twitter-count-shim * { 684 | pointer-events: none; 685 | -webkit-user-select: none; 686 | -moz-user-select: none; 687 | -ms-user-select: none; 688 | user-select: none; 689 | } 690 | .w-widget-twitter-count-shim .w-widget-twitter-count-inner { 691 | position: relative; 692 | font-size: 15px; 693 | line-height: 12px; 694 | text-align: center; 695 | color: #999; 696 | font-family: serif; 697 | } 698 | .w-widget-twitter-count-shim .w-widget-twitter-count-clear { 699 | position: relative; 700 | display: block; 701 | } 702 | .w-widget-twitter-count-shim.w--large { 703 | width: 36px; 704 | height: 28px; 705 | margin-left: 7px; 706 | } 707 | .w-widget-twitter-count-shim.w--large .w-widget-twitter-count-inner { 708 | font-size: 18px; 709 | line-height: 18px; 710 | } 711 | .w-widget-twitter-count-shim:not(.w--vertical) { 712 | margin-left: 5px; 713 | margin-right: 8px; 714 | } 715 | .w-widget-twitter-count-shim:not(.w--vertical).w--large { 716 | margin-left: 6px; 717 | } 718 | .w-widget-twitter-count-shim:not(.w--vertical):before, 719 | .w-widget-twitter-count-shim:not(.w--vertical):after { 720 | top: 50%; 721 | left: 0; 722 | border: solid transparent; 723 | content: " "; 724 | height: 0; 725 | width: 0; 726 | position: absolute; 727 | pointer-events: none; 728 | } 729 | .w-widget-twitter-count-shim:not(.w--vertical):before { 730 | border-color: rgba(117, 134, 150, 0); 731 | border-right-color: #5d6c7b; 732 | border-width: 4px; 733 | margin-left: -9px; 734 | margin-top: -4px; 735 | } 736 | .w-widget-twitter-count-shim:not(.w--vertical).w--large:before { 737 | border-width: 5px; 738 | margin-left: -10px; 739 | margin-top: -5px; 740 | } 741 | .w-widget-twitter-count-shim:not(.w--vertical):after { 742 | border-color: rgba(255, 255, 255, 0); 743 | border-right-color: white; 744 | border-width: 4px; 745 | margin-left: -8px; 746 | margin-top: -4px; 747 | } 748 | .w-widget-twitter-count-shim:not(.w--vertical).w--large:after { 749 | border-width: 5px; 750 | margin-left: -9px; 751 | margin-top: -5px; 752 | } 753 | .w-widget-twitter-count-shim.w--vertical { 754 | width: 61px; 755 | height: 33px; 756 | margin-bottom: 8px; 757 | } 758 | .w-widget-twitter-count-shim.w--vertical:before, 759 | .w-widget-twitter-count-shim.w--vertical:after { 760 | top: 100%; 761 | left: 50%; 762 | border: solid transparent; 763 | content: " "; 764 | height: 0; 765 | width: 0; 766 | position: absolute; 767 | pointer-events: none; 768 | } 769 | .w-widget-twitter-count-shim.w--vertical:before { 770 | border-color: rgba(117, 134, 150, 0); 771 | border-top-color: #5d6c7b; 772 | border-width: 5px; 773 | margin-left: -5px; 774 | } 775 | .w-widget-twitter-count-shim.w--vertical:after { 776 | border-color: rgba(255, 255, 255, 0); 777 | border-top-color: white; 778 | border-width: 4px; 779 | margin-left: -4px; 780 | } 781 | .w-widget-twitter-count-shim.w--vertical .w-widget-twitter-count-inner { 782 | font-size: 18px; 783 | line-height: 22px; 784 | } 785 | .w-widget-twitter-count-shim.w--vertical.w--large { 786 | width: 76px; 787 | } 788 | .w-widget-gplus { 789 | overflow: hidden; 790 | } 791 | .w-background-video { 792 | position: relative; 793 | overflow: hidden; 794 | height: 500px; 795 | color: white; 796 | } 797 | .w-background-video > video { 798 | background-size: cover; 799 | background-position: 50% 50%; 800 | position: absolute; 801 | right: -100%; 802 | bottom: -100%; 803 | top: -100%; 804 | left: -100%; 805 | margin: auto; 806 | min-width: 100%; 807 | min-height: 100%; 808 | z-index: -100; 809 | } 810 | .w-background-video > video::-webkit-media-controls-start-playback-button { 811 | display: none !important; 812 | -webkit-appearance: none; 813 | } 814 | .w-slider { 815 | position: relative; 816 | height: 300px; 817 | text-align: center; 818 | background: #dddddd; 819 | clear: both; 820 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 821 | tap-highlight-color: rgba(0, 0, 0, 0); 822 | } 823 | .w-slider-mask { 824 | position: relative; 825 | display: block; 826 | overflow: hidden; 827 | z-index: 1; 828 | left: 0; 829 | right: 0; 830 | height: 100%; 831 | white-space: nowrap; 832 | } 833 | .w-slide { 834 | position: relative; 835 | display: inline-block; 836 | vertical-align: top; 837 | width: 100%; 838 | height: 100%; 839 | white-space: normal; 840 | text-align: left; 841 | } 842 | .w-slider-nav { 843 | position: absolute; 844 | z-index: 2; 845 | top: auto; 846 | right: 0; 847 | bottom: 0; 848 | left: 0; 849 | margin: auto; 850 | padding-top: 10px; 851 | height: 40px; 852 | text-align: center; 853 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 854 | tap-highlight-color: rgba(0, 0, 0, 0); 855 | } 856 | .w-slider-nav.w-round > div { 857 | border-radius: 100%; 858 | } 859 | .w-slider-nav.w-num > div { 860 | width: auto; 861 | height: auto; 862 | padding: 0.2em 0.5em; 863 | font-size: inherit; 864 | line-height: inherit; 865 | } 866 | .w-slider-nav.w-shadow > div { 867 | box-shadow: 0 0 3px rgba(51, 51, 51, 0.4); 868 | } 869 | .w-slider-nav-invert { 870 | color: #fff; 871 | } 872 | .w-slider-nav-invert > div { 873 | background-color: rgba(34, 34, 34, 0.4); 874 | } 875 | .w-slider-nav-invert > div.w-active { 876 | background-color: #222; 877 | } 878 | .w-slider-dot { 879 | position: relative; 880 | display: inline-block; 881 | width: 1em; 882 | height: 1em; 883 | background-color: rgba(255, 255, 255, 0.4); 884 | cursor: pointer; 885 | margin: 0 3px 0.5em; 886 | transition: background-color 100ms, color 100ms; 887 | } 888 | .w-slider-dot.w-active { 889 | background-color: #fff; 890 | } 891 | .w-slider-arrow-left, 892 | .w-slider-arrow-right { 893 | position: absolute; 894 | width: 80px; 895 | top: 0; 896 | right: 0; 897 | bottom: 0; 898 | left: 0; 899 | margin: auto; 900 | cursor: pointer; 901 | overflow: hidden; 902 | color: white; 903 | font-size: 40px; 904 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 905 | tap-highlight-color: rgba(0, 0, 0, 0); 906 | -webkit-user-select: none; 907 | -moz-user-select: none; 908 | -ms-user-select: none; 909 | user-select: none; 910 | } 911 | .w-slider-arrow-left [class^="w-icon-"], 912 | .w-slider-arrow-right [class^="w-icon-"], 913 | .w-slider-arrow-left [class*=" w-icon-"], 914 | .w-slider-arrow-right [class*=" w-icon-"] { 915 | position: absolute; 916 | } 917 | .w-slider-arrow-left { 918 | z-index: 3; 919 | right: auto; 920 | } 921 | .w-slider-arrow-right { 922 | z-index: 4; 923 | left: auto; 924 | } 925 | .w-icon-slider-left, 926 | .w-icon-slider-right { 927 | top: 0; 928 | right: 0; 929 | bottom: 0; 930 | left: 0; 931 | margin: auto; 932 | width: 1em; 933 | height: 1em; 934 | } 935 | .w-dropdown { 936 | display: inline-block; 937 | position: relative; 938 | text-align: left; 939 | margin-left: auto; 940 | margin-right: auto; 941 | z-index: 900; 942 | } 943 | .w-dropdown-btn, 944 | .w-dropdown-toggle, 945 | .w-dropdown-link { 946 | position: relative; 947 | vertical-align: top; 948 | text-decoration: none; 949 | color: #222222; 950 | padding: 20px; 951 | text-align: left; 952 | margin-left: auto; 953 | margin-right: auto; 954 | white-space: nowrap; 955 | } 956 | .w-dropdown-toggle { 957 | -webkit-user-select: none; 958 | -moz-user-select: none; 959 | -ms-user-select: none; 960 | user-select: none; 961 | display: inline-block; 962 | cursor: pointer; 963 | padding-right: 40px; 964 | } 965 | .w-icon-dropdown-toggle { 966 | position: absolute; 967 | top: 0; 968 | right: 0; 969 | bottom: 0; 970 | margin: auto; 971 | margin-right: 20px; 972 | width: 1em; 973 | height: 1em; 974 | } 975 | .w-dropdown-list { 976 | position: absolute; 977 | background: #dddddd; 978 | display: none; 979 | min-width: 100%; 980 | } 981 | .w-dropdown-list.w--open { 982 | display: block; 983 | } 984 | .w-dropdown-link { 985 | padding: 10px 20px; 986 | display: block; 987 | color: #222222; 988 | } 989 | .w-dropdown-link.w--current { 990 | color: #0082f3; 991 | } 992 | .w-nav[data-collapse="all"] .w-dropdown, 993 | .w-nav[data-collapse="all"] .w-dropdown-toggle { 994 | display: block; 995 | } 996 | .w-nav[data-collapse="all"] .w-dropdown-list { 997 | position: static; 998 | } 999 | @media screen and (max-width: 991px) { 1000 | .w-nav[data-collapse="medium"] .w-dropdown, 1001 | .w-nav[data-collapse="medium"] .w-dropdown-toggle { 1002 | display: block; 1003 | } 1004 | .w-nav[data-collapse="medium"] .w-dropdown-list { 1005 | position: static; 1006 | } 1007 | } 1008 | @media screen and (max-width: 767px) { 1009 | .w-nav[data-collapse="small"] .w-dropdown, 1010 | .w-nav[data-collapse="small"] .w-dropdown-toggle { 1011 | display: block; 1012 | } 1013 | .w-nav[data-collapse="small"] .w-dropdown-list { 1014 | position: static; 1015 | } 1016 | .w-nav-brand { 1017 | padding-left: 10px; 1018 | } 1019 | } 1020 | @media screen and (max-width: 479px) { 1021 | .w-nav[data-collapse="tiny"] .w-dropdown, 1022 | .w-nav[data-collapse="tiny"] .w-dropdown-toggle { 1023 | display: block; 1024 | } 1025 | .w-nav[data-collapse="tiny"] .w-dropdown-list { 1026 | position: static; 1027 | } 1028 | } 1029 | /** 1030 | * ## Note 1031 | * Safari (on both iOS and OS X) does not handle viewport units (vh, vw) well. 1032 | * For example percentage units do not work on descendants of elements that 1033 | * have any dimensions expressed in viewport units. It also doesn’t handle them at 1034 | * all in `calc()`. 1035 | */ 1036 | /** 1037 | * Wrapper around all lightbox elements 1038 | * 1039 | * 1. Since the lightbox can receive focus, IE also gives it an outline. 1040 | * 2. Fixes flickering on Chrome when a transition is in progress 1041 | * underneath the lightbox. 1042 | */ 1043 | .w-lightbox-backdrop { 1044 | color: #000; 1045 | cursor: auto; 1046 | font-family: serif; 1047 | font-size: medium; 1048 | font-style: normal; 1049 | font-variant: normal; 1050 | font-weight: normal; 1051 | letter-spacing: normal; 1052 | line-height: normal; 1053 | list-style: disc; 1054 | text-align: start; 1055 | text-indent: 0; 1056 | text-shadow: none; 1057 | text-transform: none; 1058 | visibility: visible; 1059 | white-space: normal; 1060 | word-break: normal; 1061 | word-spacing: normal; 1062 | word-wrap: normal; 1063 | position: fixed; 1064 | top: 0; 1065 | right: 0; 1066 | bottom: 0; 1067 | left: 0; 1068 | color: #fff; 1069 | font-family: "Helvetica Neue", Helvetica, Ubuntu, "Segoe UI", Verdana, sans-serif; 1070 | font-size: 17px; 1071 | line-height: 1.2; 1072 | font-weight: 300; 1073 | text-align: center; 1074 | background: rgba(0, 0, 0, 0.9); 1075 | z-index: 2000; 1076 | outline: 0; 1077 | /* 1 */ 1078 | opacity: 0; 1079 | -webkit-user-select: none; 1080 | -moz-user-select: none; 1081 | -ms-user-select: none; 1082 | -webkit-tap-highlight-color: transparent; 1083 | -webkit-transform: translate(0, 0); 1084 | /* 2 */ 1085 | } 1086 | /** 1087 | * Neat trick to bind the rubberband effect to our canvas instead of the whole 1088 | * document on iOS. It also prevents a bug that causes the document underneath to scroll. 1089 | */ 1090 | .w-lightbox-backdrop, 1091 | .w-lightbox-container { 1092 | height: 100%; 1093 | overflow: auto; 1094 | -webkit-overflow-scrolling: touch; 1095 | } 1096 | .w-lightbox-content { 1097 | position: relative; 1098 | height: 100vh; 1099 | overflow: hidden; 1100 | } 1101 | .w-lightbox-view { 1102 | position: absolute; 1103 | width: 100vw; 1104 | height: 100vh; 1105 | opacity: 0; 1106 | } 1107 | .w-lightbox-view:before { 1108 | content: ""; 1109 | height: 100vh; 1110 | } 1111 | /* .w-lightbox-content */ 1112 | .w-lightbox-group, 1113 | .w-lightbox-group .w-lightbox-view, 1114 | .w-lightbox-group .w-lightbox-view:before { 1115 | height: 86vh; 1116 | } 1117 | .w-lightbox-frame, 1118 | .w-lightbox-view:before { 1119 | display: inline-block; 1120 | vertical-align: middle; 1121 | } 1122 | /* 1123 | * 1. Remove default margin set by user-agent on the
element. 1124 | */ 1125 | .w-lightbox-figure { 1126 | position: relative; 1127 | margin: 0; 1128 | /* 1 */ 1129 | } 1130 | .w-lightbox-group .w-lightbox-figure { 1131 | cursor: pointer; 1132 | } 1133 | /** 1134 | * IE adds image dimensions as width and height attributes on the IMG tag, 1135 | * but we need both width and height to be set to auto to enable scaling. 1136 | */ 1137 | .w-lightbox-img { 1138 | width: auto; 1139 | height: auto; 1140 | max-width: none; 1141 | } 1142 | /** 1143 | * 1. Reset if style is set by user on "All Images" 1144 | */ 1145 | .w-lightbox-image { 1146 | display: block; 1147 | float: none; 1148 | /* 1 */ 1149 | max-width: 100vw; 1150 | max-height: 100vh; 1151 | } 1152 | .w-lightbox-group .w-lightbox-image { 1153 | max-height: 86vh; 1154 | } 1155 | .w-lightbox-caption { 1156 | position: absolute; 1157 | right: 0; 1158 | bottom: 0; 1159 | left: 0; 1160 | padding: .5em 1em; 1161 | background: rgba(0, 0, 0, 0.4); 1162 | text-align: left; 1163 | text-overflow: ellipsis; 1164 | white-space: nowrap; 1165 | overflow: hidden; 1166 | } 1167 | .w-lightbox-embed { 1168 | position: absolute; 1169 | top: 0; 1170 | right: 0; 1171 | bottom: 0; 1172 | left: 0; 1173 | width: 100%; 1174 | height: 100%; 1175 | } 1176 | .w-lightbox-control { 1177 | position: absolute; 1178 | top: 0; 1179 | width: 4em; 1180 | background-size: 24px; 1181 | background-repeat: no-repeat; 1182 | background-position: center; 1183 | cursor: pointer; 1184 | -webkit-transition: all .3s; 1185 | transition: all .3s; 1186 | } 1187 | .w-lightbox-left { 1188 | display: none; 1189 | bottom: 0; 1190 | left: 0; 1191 | /* */ 1192 | background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ii0yMCAwIDI0IDQwIiB3aWR0aD0iMjQiIGhlaWdodD0iNDAiPjxnIHRyYW5zZm9ybT0icm90YXRlKDQ1KSI+PHBhdGggZD0ibTAgMGg1djIzaDIzdjVoLTI4eiIgb3BhY2l0eT0iLjQiLz48cGF0aCBkPSJtMSAxaDN2MjNoMjN2M2gtMjZ6IiBmaWxsPSIjZmZmIi8+PC9nPjwvc3ZnPg=="); 1193 | } 1194 | .w-lightbox-right { 1195 | display: none; 1196 | right: 0; 1197 | bottom: 0; 1198 | /* */ 1199 | background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ii00IDAgMjQgNDAiIHdpZHRoPSIyNCIgaGVpZ2h0PSI0MCI+PGcgdHJhbnNmb3JtPSJyb3RhdGUoNDUpIj48cGF0aCBkPSJtMC0waDI4djI4aC01di0yM2gtMjN6IiBvcGFjaXR5PSIuNCIvPjxwYXRoIGQ9Im0xIDFoMjZ2MjZoLTN2LTIzaC0yM3oiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"); 1200 | } 1201 | /* 1202 | * Without specifying the with and height inside the SVG, all versions of IE render the icon too small. 1203 | * The bug does not seem to manifest itself if the elements are tall enough such as the above arrows. 1204 | * (http://stackoverflow.com/questions/16092114/background-size-differs-in-internet-explorer) 1205 | */ 1206 | .w-lightbox-close { 1207 | right: 0; 1208 | height: 2.6em; 1209 | /* */ 1210 | background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ii00IDAgMTggMTciIHdpZHRoPSIxOCIgaGVpZ2h0PSIxNyI+PGcgdHJhbnNmb3JtPSJyb3RhdGUoNDUpIj48cGF0aCBkPSJtMCAwaDd2LTdoNXY3aDd2NWgtN3Y3aC01di03aC03eiIgb3BhY2l0eT0iLjQiLz48cGF0aCBkPSJtMSAxaDd2LTdoM3Y3aDd2M2gtN3Y3aC0zdi03aC03eiIgZmlsbD0iI2ZmZiIvPjwvZz48L3N2Zz4="); 1211 | background-size: 18px; 1212 | } 1213 | /** 1214 | * 1. All IE versions add extra space at the bottom without this. 1215 | */ 1216 | .w-lightbox-strip { 1217 | position: absolute; 1218 | bottom: 0; 1219 | left: 0; 1220 | right: 0; 1221 | padding: 0 1vh; 1222 | line-height: 0; 1223 | /* 1 */ 1224 | white-space: nowrap; 1225 | overflow-x: auto; 1226 | overflow-y: hidden; 1227 | } 1228 | /* 1229 | * 1. We use content-box to avoid having to do `width: calc(10vh + 2vw)` 1230 | * which doesn’t work in Safari anyway. 1231 | * 2. Chrome renders images pixelated when switching to GPU. Making sure 1232 | * the parent is also rendered on the GPU (by setting translate3d for 1233 | * example) fixes this behavior. 1234 | */ 1235 | .w-lightbox-item { 1236 | display: inline-block; 1237 | width: 10vh; 1238 | padding: 2vh 1vh; 1239 | box-sizing: content-box; 1240 | /* 1 */ 1241 | cursor: pointer; 1242 | -webkit-transform: translate3d(0, 0, 0); 1243 | /* 2 */ 1244 | } 1245 | .w-lightbox-active { 1246 | opacity: .3; 1247 | } 1248 | .w-lightbox-thumbnail { 1249 | position: relative; 1250 | height: 10vh; 1251 | background: #222; 1252 | overflow: hidden; 1253 | } 1254 | .w-lightbox-thumbnail-image { 1255 | position: absolute; 1256 | top: 0; 1257 | left: 0; 1258 | } 1259 | .w-lightbox-thumbnail .w-lightbox-tall { 1260 | top: 50%; 1261 | width: 100%; 1262 | -webkit-transform: translate(0, -50%); 1263 | -ms-transform: translate(0, -50%); 1264 | transform: translate(0, -50%); 1265 | } 1266 | .w-lightbox-thumbnail .w-lightbox-wide { 1267 | left: 50%; 1268 | height: 100%; 1269 | -webkit-transform: translate(-50%, 0); 1270 | -ms-transform: translate(-50%, 0); 1271 | transform: translate(-50%, 0); 1272 | } 1273 | /* 1274 | * Spinner 1275 | * 1276 | * Absolute pixel values are used to avoid rounding errors that would cause 1277 | * the white spinning element to be misaligned with the track. 1278 | */ 1279 | .w-lightbox-spinner { 1280 | position: absolute; 1281 | top: 50%; 1282 | left: 50%; 1283 | box-sizing: border-box; 1284 | width: 40px; 1285 | height: 40px; 1286 | margin-top: -20px; 1287 | margin-left: -20px; 1288 | border: 5px solid rgba(0, 0, 0, 0.4); 1289 | border-radius: 50%; 1290 | -webkit-animation: spin .8s infinite linear; 1291 | animation: spin .8s infinite linear; 1292 | } 1293 | .w-lightbox-spinner:after { 1294 | content: ""; 1295 | position: absolute; 1296 | top: -4px; 1297 | right: -4px; 1298 | bottom: -4px; 1299 | left: -4px; 1300 | border: 3px solid transparent; 1301 | border-bottom-color: #fff; 1302 | border-radius: 50%; 1303 | } 1304 | /* 1305 | * Utility classes 1306 | */ 1307 | .w-lightbox-hide { 1308 | display: none; 1309 | } 1310 | .w-lightbox-noscroll { 1311 | overflow: hidden; 1312 | } 1313 | @media (min-width: 768px) { 1314 | .w-lightbox-content { 1315 | height: 96vh; 1316 | margin-top: 2vh; 1317 | } 1318 | .w-lightbox-view, 1319 | .w-lightbox-view:before { 1320 | height: 96vh; 1321 | } 1322 | /* .w-lightbox-content */ 1323 | .w-lightbox-group, 1324 | .w-lightbox-group .w-lightbox-view, 1325 | .w-lightbox-group .w-lightbox-view:before { 1326 | height: 84vh; 1327 | } 1328 | .w-lightbox-image { 1329 | max-width: 96vw; 1330 | max-height: 96vh; 1331 | } 1332 | .w-lightbox-group .w-lightbox-image { 1333 | max-width: 82.3vw; 1334 | max-height: 84vh; 1335 | } 1336 | .w-lightbox-left, 1337 | .w-lightbox-right { 1338 | display: block; 1339 | opacity: .5; 1340 | } 1341 | .w-lightbox-close { 1342 | opacity: .8; 1343 | } 1344 | .w-lightbox-control:hover { 1345 | opacity: 1; 1346 | } 1347 | } 1348 | .w-lightbox-inactive, 1349 | .w-lightbox-inactive:hover { 1350 | opacity: 0; 1351 | } 1352 | .w-richtext:before, 1353 | .w-richtext:after { 1354 | content: " "; 1355 | display: table; 1356 | } 1357 | .w-richtext:after { 1358 | clear: both; 1359 | } 1360 | .w-richtext[contenteditable="true"]:before, 1361 | .w-richtext[contenteditable="true"]:after { 1362 | white-space: initial; 1363 | } 1364 | .w-richtext ol, 1365 | .w-richtext ul { 1366 | overflow: hidden; 1367 | } 1368 | .w-richtext .w-richtext-figure-selected.w-richtext-figure-type-video div:before, 1369 | .w-richtext .w-richtext-figure-selected[data-rt-type="video"] div:before { 1370 | outline: 2px solid #2895f7; 1371 | } 1372 | .w-richtext .w-richtext-figure-selected.w-richtext-figure-type-image div, 1373 | .w-richtext .w-richtext-figure-selected[data-rt-type="image"] div { 1374 | outline: 2px solid #2895f7; 1375 | } 1376 | .w-richtext figure.w-richtext-figure-type-video > div:before, 1377 | .w-richtext figure[data-rt-type="video"] > div:before { 1378 | content: ''; 1379 | position: absolute; 1380 | display: none; 1381 | left: 0; 1382 | top: 0; 1383 | right: 0; 1384 | bottom: 0; 1385 | z-index: 1; 1386 | } 1387 | .w-richtext figure { 1388 | position: relative; 1389 | max-width: 60%; 1390 | } 1391 | .w-richtext figure > div:before { 1392 | cursor: default!important; 1393 | } 1394 | .w-richtext figure img { 1395 | width: 100%; 1396 | } 1397 | .w-richtext figure figcaption.w-richtext-figcaption-placeholder { 1398 | opacity: 0.6; 1399 | } 1400 | .w-richtext figure div { 1401 | /* fix incorrectly sized selection border in the data manager */ 1402 | font-size: 0px; 1403 | color: transparent; 1404 | } 1405 | .w-richtext figure.w-richtext-figure-type-image, 1406 | .w-richtext figure[data-rt-type="image"] { 1407 | display: table; 1408 | } 1409 | .w-richtext figure.w-richtext-figure-type-image > div, 1410 | .w-richtext figure[data-rt-type="image"] > div { 1411 | display: inline-block; 1412 | } 1413 | .w-richtext figure.w-richtext-figure-type-image > figcaption, 1414 | .w-richtext figure[data-rt-type="image"] > figcaption { 1415 | display: table-caption; 1416 | caption-side: bottom; 1417 | } 1418 | .w-richtext figure.w-richtext-figure-type-video, 1419 | .w-richtext figure[data-rt-type="video"] { 1420 | width: 60%; 1421 | height: 0; 1422 | } 1423 | .w-richtext figure.w-richtext-figure-type-video iframe, 1424 | .w-richtext figure[data-rt-type="video"] iframe { 1425 | position: absolute; 1426 | top: 0; 1427 | left: 0; 1428 | width: 100%; 1429 | height: 100%; 1430 | } 1431 | .w-richtext figure.w-richtext-figure-type-video > div, 1432 | .w-richtext figure[data-rt-type="video"] > div { 1433 | width: 100%; 1434 | } 1435 | .w-richtext figure.w-richtext-align-center { 1436 | margin-right: auto; 1437 | margin-left: auto; 1438 | clear: both; 1439 | } 1440 | .w-richtext figure.w-richtext-align-center.w-richtext-figure-type-image > div, 1441 | .w-richtext figure.w-richtext-align-center[data-rt-type="image"] > div { 1442 | max-width: 100%; 1443 | } 1444 | .w-richtext figure.w-richtext-align-normal { 1445 | clear: both; 1446 | } 1447 | .w-richtext figure.w-richtext-align-fullwidth { 1448 | width: 100%; 1449 | max-width: 100%; 1450 | text-align: center; 1451 | clear: both; 1452 | display: block; 1453 | margin-right: auto; 1454 | margin-left: auto; 1455 | } 1456 | .w-richtext figure.w-richtext-align-fullwidth > div { 1457 | display: inline-block; 1458 | /* padding-bottom is used for aspect ratios in video figures 1459 | we want the div to inherit that so hover/selection borders in the designer-canvas 1460 | fit right*/ 1461 | padding-bottom: inherit; 1462 | } 1463 | .w-richtext figure.w-richtext-align-fullwidth > figcaption { 1464 | display: block; 1465 | } 1466 | .w-richtext figure.w-richtext-align-floatleft { 1467 | float: left; 1468 | margin-right: 15px; 1469 | clear: none; 1470 | } 1471 | .w-richtext figure.w-richtext-align-floatright { 1472 | float: right; 1473 | margin-left: 15px; 1474 | clear: none; 1475 | } 1476 | .w-nav { 1477 | position: relative; 1478 | background: #dddddd; 1479 | z-index: 1000; 1480 | } 1481 | .w-nav:before, 1482 | .w-nav:after { 1483 | content: " "; 1484 | display: table; 1485 | } 1486 | .w-nav:after { 1487 | clear: both; 1488 | } 1489 | .w-nav-brand { 1490 | position: relative; 1491 | float: left; 1492 | text-decoration: none; 1493 | color: #333333; 1494 | } 1495 | .w-nav-link { 1496 | position: relative; 1497 | display: inline-block; 1498 | vertical-align: top; 1499 | text-decoration: none; 1500 | color: #222222; 1501 | padding: 20px; 1502 | text-align: left; 1503 | margin-left: auto; 1504 | margin-right: auto; 1505 | } 1506 | .w-nav-link.w--current { 1507 | color: #0082f3; 1508 | } 1509 | .w-nav-menu { 1510 | position: relative; 1511 | float: right; 1512 | } 1513 | .w--nav-menu-open { 1514 | display: block !important; 1515 | position: absolute; 1516 | top: 100%; 1517 | left: 0; 1518 | right: 0; 1519 | background: #C8C8C8; 1520 | text-align: center; 1521 | overflow: visible; 1522 | min-width: 200px; 1523 | } 1524 | .w--nav-link-open { 1525 | display: block; 1526 | position: relative; 1527 | } 1528 | .w-nav-overlay { 1529 | position: absolute; 1530 | overflow: hidden; 1531 | display: none; 1532 | top: 100%; 1533 | left: 0; 1534 | right: 0; 1535 | width: 100%; 1536 | } 1537 | .w-nav-overlay .w--nav-menu-open { 1538 | top: 0; 1539 | } 1540 | .w-nav[data-animation="over-left"] .w-nav-overlay { 1541 | width: auto; 1542 | } 1543 | .w-nav[data-animation="over-left"] .w-nav-overlay, 1544 | .w-nav[data-animation="over-left"] .w--nav-menu-open { 1545 | right: auto; 1546 | z-index: 1; 1547 | top: 0; 1548 | } 1549 | .w-nav[data-animation="over-right"] .w-nav-overlay { 1550 | width: auto; 1551 | } 1552 | .w-nav[data-animation="over-right"] .w-nav-overlay, 1553 | .w-nav[data-animation="over-right"] .w--nav-menu-open { 1554 | left: auto; 1555 | z-index: 1; 1556 | top: 0; 1557 | } 1558 | .w-nav-button { 1559 | position: relative; 1560 | float: right; 1561 | padding: 18px; 1562 | font-size: 24px; 1563 | display: none; 1564 | cursor: pointer; 1565 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 1566 | tap-highlight-color: rgba(0, 0, 0, 0); 1567 | -webkit-user-select: none; 1568 | -moz-user-select: none; 1569 | -ms-user-select: none; 1570 | user-select: none; 1571 | } 1572 | .w-nav-button.w--open { 1573 | background-color: #C8C8C8; 1574 | color: white; 1575 | } 1576 | .w-nav[data-collapse="all"] .w-nav-menu { 1577 | display: none; 1578 | } 1579 | .w-nav[data-collapse="all"] .w-nav-button { 1580 | display: block; 1581 | } 1582 | @media screen and (max-width: 991px) { 1583 | .w-nav[data-collapse="medium"] .w-nav-menu { 1584 | display: none; 1585 | } 1586 | .w-nav[data-collapse="medium"] .w-nav-button { 1587 | display: block; 1588 | } 1589 | } 1590 | @media screen and (max-width: 767px) { 1591 | .w-nav[data-collapse="small"] .w-nav-menu { 1592 | display: none; 1593 | } 1594 | .w-nav[data-collapse="small"] .w-nav-button { 1595 | display: block; 1596 | } 1597 | .w-nav-brand { 1598 | padding-left: 10px; 1599 | } 1600 | } 1601 | @media screen and (max-width: 479px) { 1602 | .w-nav[data-collapse="tiny"] .w-nav-menu { 1603 | display: none; 1604 | } 1605 | .w-nav[data-collapse="tiny"] .w-nav-button { 1606 | display: block; 1607 | } 1608 | } 1609 | .w-tabs { 1610 | position: relative; 1611 | } 1612 | .w-tabs:before, 1613 | .w-tabs:after { 1614 | content: " "; 1615 | display: table; 1616 | } 1617 | .w-tabs:after { 1618 | clear: both; 1619 | } 1620 | .w-tab-menu { 1621 | position: relative; 1622 | } 1623 | .w-tab-link { 1624 | position: relative; 1625 | display: inline-block; 1626 | vertical-align: top; 1627 | text-decoration: none; 1628 | padding: 9px 30px; 1629 | text-align: left; 1630 | cursor: pointer; 1631 | color: #222222; 1632 | background-color: #dddddd; 1633 | } 1634 | .w-tab-link.w--current { 1635 | background-color: #C8C8C8; 1636 | } 1637 | .w-tab-content { 1638 | position: relative; 1639 | display: block; 1640 | overflow: hidden; 1641 | } 1642 | .w-tab-pane { 1643 | position: relative; 1644 | display: none; 1645 | } 1646 | .w--tab-active { 1647 | display: block; 1648 | } 1649 | @media screen and (max-width: 479px) { 1650 | .w-tab-link { 1651 | display: block; 1652 | } 1653 | } 1654 | .w-ix-emptyfix:after { 1655 | content: ""; 1656 | } 1657 | @keyframes spin { 1658 | 0% { 1659 | transform: rotate(0deg); 1660 | } 1661 | 100% { 1662 | transform: rotate(360deg); 1663 | } 1664 | } 1665 | .w-dyn-empty { 1666 | padding: 10px; 1667 | background-color: #dddddd; 1668 | } 1669 | .w-dyn-bind-empty { 1670 | display: none !important; 1671 | } 1672 | .w-condition-invisible { 1673 | display: none !important; 1674 | } 1675 | -------------------------------------------------------------------------------- /Flask_Starter_Code/Static/images/UV9qmUi-p-500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jflick58/TeachPythonWithMinecraft/aa1dbfb72eb701b92652484ac8e1bed8a64170a9/Flask_Starter_Code/Static/images/UV9qmUi-p-500.png -------------------------------------------------------------------------------- /Flask_Starter_Code/Static/images/UV9qmUi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jflick58/TeachPythonWithMinecraft/aa1dbfb72eb701b92652484ac8e1bed8a64170a9/Flask_Starter_Code/Static/images/UV9qmUi.png -------------------------------------------------------------------------------- /Flask_Starter_Code/Static/images/fans-black-p-1080x606.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jflick58/TeachPythonWithMinecraft/aa1dbfb72eb701b92652484ac8e1bed8a64170a9/Flask_Starter_Code/Static/images/fans-black-p-1080x606.jpeg -------------------------------------------------------------------------------- /Flask_Starter_Code/Static/images/fans-black-p-1600x898.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jflick58/TeachPythonWithMinecraft/aa1dbfb72eb701b92652484ac8e1bed8a64170a9/Flask_Starter_Code/Static/images/fans-black-p-1600x898.jpeg -------------------------------------------------------------------------------- /Flask_Starter_Code/Static/images/fans-black-p-500x281.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jflick58/TeachPythonWithMinecraft/aa1dbfb72eb701b92652484ac8e1bed8a64170a9/Flask_Starter_Code/Static/images/fans-black-p-500x281.jpeg -------------------------------------------------------------------------------- /Flask_Starter_Code/Static/images/fans-black-p-800x449.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jflick58/TeachPythonWithMinecraft/aa1dbfb72eb701b92652484ac8e1bed8a64170a9/Flask_Starter_Code/Static/images/fans-black-p-800x449.jpeg -------------------------------------------------------------------------------- /Flask_Starter_Code/Static/images/fans-black.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jflick58/TeachPythonWithMinecraft/aa1dbfb72eb701b92652484ac8e1bed8a64170a9/Flask_Starter_Code/Static/images/fans-black.jpg -------------------------------------------------------------------------------- /Flask_Starter_Code/Static/js/webflow.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Webflow: Front-end site library 3 | * @license MIT 4 | * Inline scripts may access the api using an async handler: 5 | * var Webflow = Webflow || []; 6 | * Webflow.push(readyFunction); 7 | */ 8 | !function(t){function e(i){if(n[i])return n[i].exports;var r=n[i]={i:i,l:!1,exports:{}};return t[i].call(r.exports,r,r.exports,e),r.l=!0,r.exports}var n={};e.m=t,e.c=n,e.d=function(t,n,i){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:i})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=2)}([function(t,e,n){function i(t){u.env()&&(v(t.design)&&d.on("__wf_design",t.design),v(t.preview)&&d.on("__wf_preview",t.preview)),v(t.destroy)&&d.on("__wf_destroy",t.destroy),t.ready&&v(t.ready)&&function(t){if(b)return void t.ready();if(m.contains(l,t.ready))return;l.push(t.ready)}(t)}function r(t){v(t.design)&&d.off("__wf_design",t.design),v(t.preview)&&d.off("__wf_preview",t.preview),v(t.destroy)&&d.off("__wf_destroy",t.destroy),t.ready&&v(t.ready)&&function(t){l=m.filter(l,function(e){return e!==t.ready})}(t)}function o(t,e){var n=[],i={};return i.up=m.throttle(function(t){m.each(n,function(e){e(t)})}),t&&e&&t.on(e,i.up),i.on=function(t){"function"==typeof t&&(m.contains(n,t)||n.push(t))},i.off=function(t){n=arguments.length?m.filter(n,function(e){return e!==t}):[]},i}function a(t){v(t)&&t()}function s(){z&&(z.reject(),d.off("load",z.resolve)),z=new h.Deferred,d.on("load",z.resolve)}var u={},c={},l=[],f=window.Webflow||[],h=window.jQuery,d=h(window),p=h(document),v=h.isFunction,m=u._=n(4),w=n(1)&&h.tram,b=!1,g=!1;w.config.hideBackface=!1,w.config.keepInherited=!0,u.define=function(t,e,n){c[t]&&r(c[t]);var o=c[t]=e(h,m,n)||{};return i(o),o},u.require=function(t){return c[t]},u.push=function(t){b?v(t)&&t():f.push(t)},u.env=function(t){var e=window.__wf_design,n=void 0!==e;return t?"design"===t?n&&e:"preview"===t?n&&!e:"slug"===t?n&&window.__wf_slug:"editor"===t?window.WebflowEditor:"test"===t?window.__wf_test:"frame"===t?window!==window.top:void 0:n};var y=navigator.userAgent.toLowerCase(),x=u.env.touch="ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch,k=u.env.chrome=/chrome/.test(y)&&/Google/.test(navigator.vendor)&&parseInt(y.match(/chrome\/(\d+)\./)[1],10),_=u.env.ios=/(ipod|iphone|ipad)/.test(y);u.env.safari=/safari/.test(y)&&!k&&!_;var E;x&&p.on("touchstart mousedown",function(t){E=t.target}),u.validClick=x?function(t){return t===E||h.contains(t,E)}:function(){return!0};var T="resize.webflow orientationchange.webflow load.webflow";u.resize=o(d,T),u.scroll=o(d,"scroll.webflow resize.webflow orientationchange.webflow load.webflow"),u.redraw=o(),u.location=function(t){window.location=t},u.env()&&(u.location=function(){}),u.ready=function(){b=!0,g?(g=!1,m.each(c,i)):m.each(l,a),m.each(f,a),u.resize.up()};var z;u.load=function(t){z.then(t)},u.destroy=function(t){t=t||{},g=!0,d.triggerHandler("__wf_destroy"),null!=t.domready&&(b=t.domready),m.each(c,r),u.resize.off(),u.scroll.off(),u.redraw.off(),l=[],f=[],"pending"===z.state()&&s()},h(u.ready),s(),t.exports=window.Webflow=u},function(t,e){var n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};window.tram=function(t){function e(t,e){return(new S.Bare).init(t,e)}function i(t){return t.replace(/[A-Z]/g,function(t){return"-"+t.toLowerCase()})}function r(t){var e=parseInt(t.slice(1),16);return[e>>16&255,e>>8&255,255&e]}function o(t,e,n){return"#"+(1<<24|t<<16|e<<8|n).toString(16).slice(1)}function a(){}function s(t,e,n){if(void 0!==e&&(n=e),void 0===t)return n;var i=n;return W.test(t)||!Z.test(t)?i=parseInt(t,10):Z.test(t)&&(i=1e3*parseFloat(t)),0>i&&(i=0),i==i?i:n}function u(t){I.debug&&window&&window.console.warn(t)}var c=function(t,e,i){function r(t){return"object"==(void 0===t?"undefined":n(t))}function o(t){return"function"==typeof t}function a(){}function s(n,u){function c(){var t=new l;return o(t.init)&&t.init.apply(t,arguments),t}function l(){}u===i&&(u=n,n=Object),c.Bare=l;var f,h=a[t]=n[t],d=l[t]=c[t]=new a;return d.constructor=c,c.mixin=function(e){return l[t]=c[t]=s(c,e)[t],c},c.open=function(t){if(f={},o(t)?f=t.call(c,d,h,c,n):r(t)&&(f=t),r(f))for(var i in f)e.call(f,i)&&(d[i]=f[i]);return o(d.init)||(d.init=n),c},c.open(u)}return s}("prototype",{}.hasOwnProperty),l={ease:["ease",function(t,e,n,i){var r=(t/=i)*t,o=r*t;return e+n*(-2.75*o*r+11*r*r+-15.5*o+8*r+.25*t)}],"ease-in":["ease-in",function(t,e,n,i){var r=(t/=i)*t,o=r*t;return e+n*(-1*o*r+3*r*r+-3*o+2*r)}],"ease-out":["ease-out",function(t,e,n,i){var r=(t/=i)*t,o=r*t;return e+n*(.3*o*r+-1.6*r*r+2.2*o+-1.8*r+1.9*t)}],"ease-in-out":["ease-in-out",function(t,e,n,i){var r=(t/=i)*t,o=r*t;return e+n*(2*o*r+-5*r*r+2*o+2*r)}],linear:["linear",function(t,e,n,i){return n*t/i+e}],"ease-in-quad":["cubic-bezier(0.550, 0.085, 0.680, 0.530)",function(t,e,n,i){return n*(t/=i)*t+e}],"ease-out-quad":["cubic-bezier(0.250, 0.460, 0.450, 0.940)",function(t,e,n,i){return-n*(t/=i)*(t-2)+e}],"ease-in-out-quad":["cubic-bezier(0.455, 0.030, 0.515, 0.955)",function(t,e,n,i){return(t/=i/2)<1?n/2*t*t+e:-n/2*(--t*(t-2)-1)+e}],"ease-in-cubic":["cubic-bezier(0.550, 0.055, 0.675, 0.190)",function(t,e,n,i){return n*(t/=i)*t*t+e}],"ease-out-cubic":["cubic-bezier(0.215, 0.610, 0.355, 1)",function(t,e,n,i){return n*((t=t/i-1)*t*t+1)+e}],"ease-in-out-cubic":["cubic-bezier(0.645, 0.045, 0.355, 1)",function(t,e,n,i){return(t/=i/2)<1?n/2*t*t*t+e:n/2*((t-=2)*t*t+2)+e}],"ease-in-quart":["cubic-bezier(0.895, 0.030, 0.685, 0.220)",function(t,e,n,i){return n*(t/=i)*t*t*t+e}],"ease-out-quart":["cubic-bezier(0.165, 0.840, 0.440, 1)",function(t,e,n,i){return-n*((t=t/i-1)*t*t*t-1)+e}],"ease-in-out-quart":["cubic-bezier(0.770, 0, 0.175, 1)",function(t,e,n,i){return(t/=i/2)<1?n/2*t*t*t*t+e:-n/2*((t-=2)*t*t*t-2)+e}],"ease-in-quint":["cubic-bezier(0.755, 0.050, 0.855, 0.060)",function(t,e,n,i){return n*(t/=i)*t*t*t*t+e}],"ease-out-quint":["cubic-bezier(0.230, 1, 0.320, 1)",function(t,e,n,i){return n*((t=t/i-1)*t*t*t*t+1)+e}],"ease-in-out-quint":["cubic-bezier(0.860, 0, 0.070, 1)",function(t,e,n,i){return(t/=i/2)<1?n/2*t*t*t*t*t+e:n/2*((t-=2)*t*t*t*t+2)+e}],"ease-in-sine":["cubic-bezier(0.470, 0, 0.745, 0.715)",function(t,e,n,i){return-n*Math.cos(t/i*(Math.PI/2))+n+e}],"ease-out-sine":["cubic-bezier(0.390, 0.575, 0.565, 1)",function(t,e,n,i){return n*Math.sin(t/i*(Math.PI/2))+e}],"ease-in-out-sine":["cubic-bezier(0.445, 0.050, 0.550, 0.950)",function(t,e,n,i){return-n/2*(Math.cos(Math.PI*t/i)-1)+e}],"ease-in-expo":["cubic-bezier(0.950, 0.050, 0.795, 0.035)",function(t,e,n,i){return 0===t?e:n*Math.pow(2,10*(t/i-1))+e}],"ease-out-expo":["cubic-bezier(0.190, 1, 0.220, 1)",function(t,e,n,i){return t===i?e+n:n*(1-Math.pow(2,-10*t/i))+e}],"ease-in-out-expo":["cubic-bezier(1, 0, 0, 1)",function(t,e,n,i){return 0===t?e:t===i?e+n:(t/=i/2)<1?n/2*Math.pow(2,10*(t-1))+e:n/2*(2-Math.pow(2,-10*--t))+e}],"ease-in-circ":["cubic-bezier(0.600, 0.040, 0.980, 0.335)",function(t,e,n,i){return-n*(Math.sqrt(1-(t/=i)*t)-1)+e}],"ease-out-circ":["cubic-bezier(0.075, 0.820, 0.165, 1)",function(t,e,n,i){return n*Math.sqrt(1-(t=t/i-1)*t)+e}],"ease-in-out-circ":["cubic-bezier(0.785, 0.135, 0.150, 0.860)",function(t,e,n,i){return(t/=i/2)<1?-n/2*(Math.sqrt(1-t*t)-1)+e:n/2*(Math.sqrt(1-(t-=2)*t)+1)+e}],"ease-in-back":["cubic-bezier(0.600, -0.280, 0.735, 0.045)",function(t,e,n,i,r){return void 0===r&&(r=1.70158),n*(t/=i)*t*((r+1)*t-r)+e}],"ease-out-back":["cubic-bezier(0.175, 0.885, 0.320, 1.275)",function(t,e,n,i,r){return void 0===r&&(r=1.70158),n*((t=t/i-1)*t*((r+1)*t+r)+1)+e}],"ease-in-out-back":["cubic-bezier(0.680, -0.550, 0.265, 1.550)",function(t,e,n,i,r){return void 0===r&&(r=1.70158),(t/=i/2)<1?n/2*t*t*((1+(r*=1.525))*t-r)+e:n/2*((t-=2)*t*((1+(r*=1.525))*t+r)+2)+e}]},f={"ease-in-back":"cubic-bezier(0.600, 0, 0.735, 0.045)","ease-out-back":"cubic-bezier(0.175, 0.885, 0.320, 1)","ease-in-out-back":"cubic-bezier(0.680, 0, 0.265, 1)"},h=document,d=window,p="bkwld-tram",v=/[\-\.0-9]/g,m=/[A-Z]/,w=/^(rgb|#)/,b=/(em|cm|mm|in|pt|pc|px)$/,g=/(em|cm|mm|in|pt|pc|px|%)$/,y=/(deg|rad|turn)$/,x=/(all|none) 0s ease 0s/,k=/^(width|height)$/,_=" ",E=h.createElement("a"),T=["Webkit","Moz","O","ms"],z=["-webkit-","-moz-","-o-","-ms-"],j=function(t){if(t in E.style)return{dom:t,css:t};var e,n,i="",r=t.split("-");for(e=0;eu&&(u=t.span),t.stop(),t.animate(e)},function(t){"wait"in t&&(u=s(t.wait,0))}),h.call(this),u>0&&(this.timer=new X({duration:u,context:this}),this.active=!0,e&&(this.timer.complete=a));var p=this,v=!1,m={};$(function(){d.call(p,t,function(t){t.active&&(v=!0,m[t.name]=t.nextStyle)}),v&&p.$el.css(m)})}}}function a(){if(this.timer&&this.timer.destroy(),this.active=!1,this.queue.length){var t=this.queue.shift();o.call(this,t.options,!0,t.args)}}function c(t){this.timer&&this.timer.destroy(),this.queue=[],this.active=!1;var e;"string"==typeof t?(e={},e[t]=1):e="object"==(void 0===t?"undefined":n(t))&&null!=t?t:this.props,d.call(this,e,v),h.call(this)}function l(){c.call(this),this.el.style.display="none"}function f(){this.el.offsetHeight}function h(){var t,e,n=[];this.upstream&&n.push(this.upstream);for(t in this.props)(e=this.props[t]).active&&n.push(e.string);n=n.join(","),this.style!==n&&(this.style=n,this.el.style[M.transition.dom]=n)}function d(t,e,n){var o,a,s,u,c=e!==v,l={};for(o in t)s=t[o],o in U?(l.transform||(l.transform={}),l.transform[o]=s):(m.test(o)&&(o=i(o)),o in G?l[o]=s:(u||(u={}),u[o]=s));for(o in l){if(s=l[o],!(a=this.props[o])){if(!c)continue;a=r.call(this,o)}e.call(this,a,s)}n&&u&&n.call(this,u)}function v(t){t.stop()}function w(t,e){t.set(e)}function b(t){this.$el.css(t)}function g(t,n){e[t]=function(){return this.children?function(t,e){var n,i=this.children.length;for(n=0;i>n;n++)t.apply(this.children[n],e);return this}.call(this,n,arguments):(this.el&&n.apply(this,arguments),this)}}e.init=function(e){if(this.$el=t(e),this.el=this.$el[0],this.props={},this.queue=[],this.style="",this.active=!1,I.keepInherited&&!I.fallback){var n=H(this.el,"transition");n&&!x.test(n)&&(this.upstream=n)}M.backface&&I.hideBackface&&C(this.el,M.backface.css,"hidden")},g("add",r),g("start",o),g("wait",function(t){t=s(t,0),this.active?this.queue.push({options:t}):(this.timer=new X({duration:t,context:this,complete:a}),this.active=!0)}),g("then",function(t){return this.active?(this.queue.push({options:t,args:arguments}),void(this.timer.complete=a)):u("No active transition timer. Use start() or wait() before then().")}),g("next",a),g("stop",c),g("set",function(t){c.call(this,t),d.call(this,t,w,b)}),g("show",function(t){"string"!=typeof t&&(t="block"),this.el.style.display=t}),g("hide",l),g("redraw",f),g("destroy",function(){c.call(this),t.removeData(this.el,p),this.$el=this.el=null})}),S=c(L,function(e){function n(e,n){var i=t.data(e,p)||t.data(e,p,new L.Bare);return i.el||i.init(e),n?i.start(n):i}e.init=function(e,i){var r=t(e);if(!r.length)return this;if(1===r.length)return n(r[0],i);var o=[];return r.each(function(t,e){o.push(n(e,i))}),this.children=o,this}}),D=c(function(t){function e(){var t=this.get();this.update("auto");var e=this.get();return this.update(t),e}var i=500,r="ease",a=0;t.init=function(t,e,n,o){this.$el=t,this.el=t[0];var u=e[0];n[2]&&(u=n[2]),Y[u]&&(u=Y[u]),this.name=u,this.type=n[1],this.duration=s(e[1],this.duration,i),this.ease=function(t,e,n){return void 0!==e&&(n=e),t in l?t:n}(e[2],this.ease,r),this.delay=s(e[3],this.delay,a),this.span=this.duration+this.delay,this.active=!1,this.nextStyle=null,this.auto=k.test(this.name),this.unit=o.unit||this.unit||I.defaultUnit,this.angle=o.angle||this.angle||I.defaultAngle,I.fallback||o.fallback?this.animate=this.fallback:(this.animate=this.transition,this.string=this.name+_+this.duration+"ms"+("ease"!=this.ease?_+l[this.ease][0]:"")+(this.delay?_+this.delay+"ms":""))},t.set=function(t){t=this.convert(t,this.type),this.update(t),this.redraw()},t.transition=function(t){this.active=!0,t=this.convert(t,this.type),this.auto&&("auto"==this.el.style[this.name]&&(this.update(this.get()),this.redraw()),"auto"==t&&(t=e.call(this))),this.nextStyle=t},t.fallback=function(t){var n=this.el.style[this.name]||this.convert(this.get(),this.type);t=this.convert(t,this.type),this.auto&&("auto"==n&&(n=this.convert(this.get(),this.type)),"auto"==t&&(t=e.call(this))),this.tween=new N({from:n,to:t,duration:this.duration,delay:this.delay,ease:this.ease,update:this.update,context:this})},t.get=function(){return H(this.el,this.name)},t.update=function(t){C(this.el,this.name,t)},t.stop=function(){(this.active||this.nextStyle)&&(this.active=!1,this.nextStyle=null,C(this.el,this.name,this.get()));var t=this.tween;t&&t.context&&t.destroy()},t.convert=function(t,e){if("auto"==t&&this.auto)return t;var i,r="number"==typeof t,a="string"==typeof t;switch(e){case"number":if(r)return t;if(a&&""===t.replace(v,""))return+t;i="number(unitless)";break;case w:if(a){if(""===t&&this.original)return this.original;if(e.test(t))return"#"==t.charAt(0)&&7==t.length?t:function(t){var e=/rgba?\((\d+),\s*(\d+),\s*(\d+)/.exec(t);return(e?o(e[1],e[2],e[3]):t).replace(/#(\w)(\w)(\w)$/,"#$1$1$2$2$3$3")}(t)}i="hex or rgb string";break;case b:if(r)return t+this.unit;if(a&&e.test(t))return t;i="number(px) or string(unit)";break;case g:if(r)return t+this.unit;if(a&&e.test(t))return t;i="number(px) or string(unit or %)";break;case y:if(r)return t+this.angle;if(a&&e.test(t))return t;i="number(deg) or string(angle)";break;case"unitless":if(r)return t;if(a&&g.test(t))return t;i="number(unitless) or string(unit or %)"}return function(t,e){u("Type warning: Expected: ["+t+"] Got: ["+(void 0===e?"undefined":n(e))+"] "+e)}(i,t),t},t.redraw=function(){this.el.offsetHeight}}),F=c(D,function(t,e){t.init=function(){e.init.apply(this,arguments),this.original||(this.original=this.convert(this.get(),w))}}),R=c(D,function(t,e){t.init=function(){e.init.apply(this,arguments),this.animate=this.fallback},t.get=function(){return this.$el[this.name]()},t.update=function(t){this.$el[this.name](t)}}),P=c(D,function(t,e){function n(t,e){var n,i,r,o,a;for(n in t)r=(o=U[n])[0],i=o[1]||n,a=this.convert(t[n],r),e.call(this,i,a,r)}t.init=function(){e.init.apply(this,arguments),this.current||(this.current={},U.perspective&&I.perspective&&(this.current.perspective=I.perspective,C(this.el,this.name,this.style(this.current)),this.redraw()))},t.set=function(t){n.call(this,t,function(t,e){this.current[t]=e}),C(this.el,this.name,this.style(this.current)),this.redraw()},t.transition=function(t){var e=this.values(t);this.tween=new B({current:this.current,values:e,duration:this.duration,delay:this.delay,ease:this.ease});var n,i={};for(n in this.current)i[n]=n in e?e[n]:this.current[n];this.active=!0,this.nextStyle=this.style(i)},t.fallback=function(t){var e=this.values(t);this.tween=new B({current:this.current,values:e,duration:this.duration,delay:this.delay,ease:this.ease,update:this.update,context:this})},t.update=function(){C(this.el,this.name,this.style(this.current))},t.style=function(t){var e,n="";for(e in t)n+=e+"("+t[e]+") ";return n},t.values=function(t){var e,i={};return n.call(this,t,function(t,n,r){i[t]=n,void 0===this.current[t]&&(e=0,~t.indexOf("scale")&&(e=1),this.current[t]=this.convert(e,r))}),i}}),N=c(function(e){function n(){var t,e,i,r=s.length;if(r)for($(n),e=O(),t=r;t--;)(i=s[t])&&i.render(e)}var i={ease:l.ease[1],from:0,to:1};e.init=function(t){this.duration=t.duration||0,this.delay=t.delay||0;var e=t.ease||i.ease;l[e]&&(e=l[e][1]),"function"!=typeof e&&(e=i.ease),this.ease=e,this.update=t.update||a,this.complete=t.complete||a,this.context=t.context||this,this.name=t.name;var n=t.from,r=t.to;void 0===n&&(n=i.from),void 0===r&&(r=i.to),this.unit=t.unit||"","number"==typeof n&&"number"==typeof r?(this.begin=n,this.change=r-n):this.format(r,n),this.value=this.begin+this.unit,this.start=O(),!1!==t.autoplay&&this.play()},e.play=function(){this.active||(this.start||(this.start=O()),this.active=!0,function(t){1===s.push(t)&&$(n)}(this))},e.stop=function(){this.active&&(this.active=!1,function(e){var n,i=t.inArray(e,s);i>=0&&(n=s.slice(i+1),s.length=i,n.length&&(s=s.concat(n)))}(this))},e.render=function(t){var e,n=t-this.start;if(this.delay){if(n<=this.delay)return;n-=this.delay}if(n').attr("href","https://webflow.com?utm_campaign=brandjs"),n=t("").attr("src","https://d1otoma47x30pg.cloudfront.net/img/webflow-badge-icon.60efbf6ec9.svg").css({marginRight:"8px",width:"16px"}),i=t("").attr("src","https://d1otoma47x30pg.cloudfront.net/img/webflow-badge-text.6faa6a38cd.svg");return e.append(n,i),e[0]}(),e(),setTimeout(e,500))},r})},function(t,e,n){var i=window.$,r=n(1)&&i.tram;/*! 9 | * Webflow._ (aka) Underscore.js 1.6.0 (custom build) 10 | * _.each 11 | * _.map 12 | * _.find 13 | * _.filter 14 | * _.any 15 | * _.contains 16 | * _.delay 17 | * _.defer 18 | * _.throttle (webflow) 19 | * _.debounce 20 | * _.keys 21 | * _.has 22 | * _.now 23 | * 24 | * http://underscorejs.org 25 | * (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 26 | * Underscore may be freely distributed under the MIT license. 27 | * @license MIT 28 | */ 29 | t.exports=function(){var t={};t.VERSION="1.6.0-Webflow";var e={},n=Array.prototype,i=Object.prototype,o=Function.prototype,a=(n.push,n.slice),s=(n.concat,i.toString,i.hasOwnProperty),u=n.forEach,c=n.map,l=(n.reduce,n.reduceRight,n.filter),f=(n.every,n.some),h=n.indexOf,d=(n.lastIndexOf,Array.isArray,Object.keys),p=(o.bind,t.each=t.forEach=function(n,i,r){if(null==n)return n;if(u&&n.forEach===u)n.forEach(i,r);else if(n.length===+n.length){for(var o=0,a=n.length;o/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var m=/(.)^/,w={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},b=/\\|'|\r|\n|\u2028|\u2029/g,g=function(t){return"\\"+w[t]};return t.template=function(e,n,i){!n&&i&&(n=i),n=t.defaults({},n,t.templateSettings);var r=RegExp([(n.escape||m).source,(n.interpolate||m).source,(n.evaluate||m).source].join("|")+"|$","g"),o=0,a="__p+='";e.replace(r,function(t,n,i,r,s){return a+=e.slice(o,s).replace(b,g),o=s+t.length,n?a+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'":i?a+="'+\n((__t=("+i+"))==null?'':__t)+\n'":r&&(a+="';\n"+r+"\n__p+='"),t}),a+="';\n",n.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{var s=new Function(n.variable||"obj","_",a)}catch(t){throw t.source=a,t}var u=function(e){return s.call(this,e,t)},c=n.variable||"obj";return u.source="function("+c+"){\n"+a+"}",u},t}()},function(t,e,n){var i=n(0);i.define("forms",t.exports=function(t,e){function r(e,n){var i=t(n),r=t.data(n,g);r||(r=t.data(n,g,{form:i})),o(r);var a=i.closest("div.w-form");r.done=a.find("> .w-form-done"),r.fail=a.find("> .w-form-fail");var s=r.action=i.attr("action");r.handler=null,r.redirect=i.attr("data-redirect"),E.test(s)?r.handler=c:s||(p?r.handler=u:T())}function o(t){var e=t.btn=t.form.find(':input[type="submit"]');t.wait=t.btn.attr("data-wait")||null,t.success=!1,e.prop("disabled",!1),t.label&&e.val(t.label)}function a(t){var e=t.btn,n=t.wait;e.prop("disabled",!0),n&&(t.label=e.val(),e.val(n))}function s(e,n){var i=null;return n=n||{},e.find(':input:not([type="submit"])').each(function(r,o){var a=t(o),s=a.attr("type"),u=a.attr("data-name")||a.attr("name")||"Field "+(r+1),c=a.val();if("checkbox"===s&&(c=a.is(":checked")),"radio"===s){if(null===n[u]||"string"==typeof n[u])return;c=e.find('input[name="'+a.attr("name")+'"]:checked').val()||null}"string"==typeof c&&(c=t.trim(c)),n[u]=c,i=i||function(t,e,n,i){var r=null;"password"===e?r="Passwords cannot be submitted.":t.attr("required")&&(i?(y.test(n)||y.test(t.attr("type")))&&(x.test(i)||(r="Please enter a valid email address for: "+n)):r="Please fill out the required field: "+n);return r}(a,s,u,c)}),i}function u(e){o(e);var n=e.form,r={name:n.attr("data-name")||n.attr("name")||"Untitled Form",source:w.href,test:i.env(),fields:{},dolphin:/pass[\s-_]?(word|code)|secret|login|credentials/i.test(n.html())};f(e);var u=s(n,r.fields);if(u)return k(u);if(a(e),p){var c="https://webflow.com/api/v1/form/"+p;b&&c.indexOf("https://webflow.com")>=0&&(c=c.replace("https://webflow.com","http://formdata.webflow.com")),t.ajax({url:c,type:"POST",data:r,dataType:"json",crossDomain:!0}).done(function(){e.success=!0,l(e)}).fail(function(){l(e)})}else l(e)}function c(n){o(n);var i=n.form,r={};if(!/^https/.test(w.href)||/^https/.test(n.action)){f(n);var u=s(i,r);if(u)return k(u);a(n);var c;e.each(r,function(t,e){y.test(e)&&(r.EMAIL=t),/^((full[ _-]?)?name)$/i.test(e)&&(c=t),/^(first[ _-]?name)$/i.test(e)&&(r.FNAME=t),/^(last[ _-]?name)$/i.test(e)&&(r.LNAME=t)}),c&&!r.FNAME&&(c=c.split(" "),r.FNAME=c[0],r.LNAME=r.LNAME||c[1]);var h=n.action.replace("/post?","/post-json?")+"&c=?",d=h.indexOf("u=")+2;d=h.substring(d,h.indexOf("&",d));var p=h.indexOf("id=")+3;p=h.substring(p,h.indexOf("&",p)),r["b_"+d+"_"+p]="",t.ajax({url:h,data:r,dataType:"jsonp"}).done(function(t){n.success="success"===t.result||/already/.test(t.msg),n.success||console.info("MailChimp error: "+t.msg),l(n)}).fail(function(){l(n)})}else i.attr("method","post")}function l(t){var e=t.form,n=t.redirect,r=t.success;r&&n?i.location(n):(t.done.toggle(r),t.fail.toggle(!r),e.toggle(!r),o(t))}function f(t){t.evt&&t.evt.preventDefault(),t.evt=null}var h={};n(6);var d,p,v,m=t(document),w=window.location,b=window.XDomainRequest&&!window.atob,g=".w-form",y=/e(-)?mail/i,x=/^\S+@\S+$/,k=window.alert,_=i.env(),E=/list-manage[1-9]?.com/i,T=e.debounce(function(){k("Oops! This page has improperly configured forms. Please contact your website administrator to fix this issue.")},100);return h.ready=h.design=h.preview=function(){p=t("html").attr("data-wf-site"),(d=t(g+" form")).length&&d.each(r),_||v||(v=!0,m.on("submit",g+" form",function(e){var n=t.data(this,g);n.handler&&(n.evt=e,n.handler(n))}))},h})},function(t,e){/*! 30 | * jQuery-ajaxTransport-XDomainRequest - v1.0.3 31 | * 2014-12-16 WEBFLOW - Removed UMD wrapper 32 | * https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest 33 | * Copyright (c) 2014 Jason Moon (@JSONMOON) 34 | * @license MIT (/blob/master/LICENSE.txt) 35 | */ 36 | t.exports=function(t){if(!t.support.cors&&t.ajaxTransport&&window.XDomainRequest){var e=/^https?:\/\//i,n=/^get|post$/i,i=new RegExp("^"+location.protocol,"i");t.ajaxTransport("* text html xml json",function(r,o,a){if(r.crossDomain&&r.async&&n.test(r.type)&&e.test(r.url)&&i.test(r.url)){var s=null;return{send:function(e,n){var i="",a=(o.dataType||"").toLowerCase();s=new XDomainRequest,/^\d+$/.test(o.timeout)&&(s.timeout=o.timeout),s.ontimeout=function(){n(500,"timeout")},s.onload=function(){var e="Content-Length: "+s.responseText.length+"\r\nContent-Type: "+s.contentType,i={code:200,message:"success"},r={text:s.responseText};try{if("html"===a||/text\/html/i.test(s.contentType))r.html=s.responseText;else if("json"===a||"text"!==a&&/\/json/i.test(s.contentType))try{r.json=t.parseJSON(s.responseText)}catch(t){i.code=500,i.message="parseerror"}else if("xml"===a||"text"!==a&&/\/xml/i.test(s.contentType)){var o=new ActiveXObject("Microsoft.XMLDOM");o.async=!1;try{o.loadXML(s.responseText)}catch(t){o=void 0}if(!o||!o.documentElement||o.getElementsByTagName("parsererror").length)throw i.code=500,i.message="parseerror","Invalid XML: "+s.responseText;r.xml=o}}catch(t){throw t}finally{n(i.code,i.message,r,e)}},s.onprogress=function(){},s.onerror=function(){n(500,"error",{text:s.responseText})},o.data&&(i="string"===t.type(o.data)?o.data:t.param(o.data)),s.open(r.type,r.url),s.send(i)},abort:function(){s&&s.abort()}}}})}}(window.jQuery)},function(t,e,n){var i=n(0);i.define("links",t.exports=function(t,e){function n(){var t=c.scrollTop(),n=c.height();e.each(a,function(e){var i=e.link,o=e.sec,a=o.offset().top,s=o.outerHeight(),u=.5*n,c=o.is(":visible")&&a+s-u>=t&&a+u<=t+n;e.active!==c&&(e.active=c,r(i,d,c))})}function r(t,e,n){var i=t.hasClass(e);n&&i||(n||i)&&(n?t.addClass(e):t.removeClass(e))}var o,a,s,u={},c=t(window),l=i.env(),f=window.location,h=document.createElement("a"),d="w--current",p=/^#[\w:.-]+$/,v=/index\.(html|php)$/,m=/\/$/;return u.ready=u.design=u.preview=function(){o=l&&i.env("design"),s=i.env("slug")||f.pathname||"",i.scroll.off(n),a=[];for(var e=document.links,u=0;u=0)){var i=t(e);if(0===n.indexOf("#")&&p.test(n)){var u=t(n);u.length&&a.push({link:i,sec:u,active:!1})}else if("#"!==n&&""!==n){var c=h.href===f.href||n===s||v.test(n)&&m.test(s);r(i,d,c)}}}(e[u]);a.length&&(i.scroll.on(n),n())},u})},function(t,e,n){var i=n(0);i.define("scroll",t.exports=function(t){function e(e,n){if(s.test(e)){var u=t("#"+e);if(u.length){if(n&&(n.preventDefault(),n.stopPropagation()),o.hash!==e&&a&&a.pushState&&(!i.env.chrome||"file:"!==o.protocol)){(a.state&&a.state.hash)!==e&&a.pushState({hash:e},"","#"+e)}var c=i.env("editor")?".w-editor-body":"body",l=t("header, "+c+" > .header, "+c+" > .w-nav:not([data-no-scroll])"),f="fixed"===l.css("position")?l.outerHeight():0;r.setTimeout(function(){!function(e,n){var i=t(r).scrollTop(),o=e.offset().top-n;if("mid"===e.data("scroll")){var a=t(r).height()-n,s=e.outerHeight();s0)&&(u=e)}),Date.now||(Date.now=function(){return(new Date).getTime()});var c=Date.now(),l=r.requestAnimationFrame||r.mozRequestAnimationFrame||r.webkitRequestAnimationFrame||function(t){r.setTimeout(t,15)},f=(472.143*Math.log(Math.abs(i-o)+125)-2e3)*u;!function t(){var e=Date.now()-c;r.scroll(0,function(t,e,n,i){if(n>i)return e;return t+(e-t)*function(t){return t<.5?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1}(n/i)}(i,o,e,f)),e<=f&&l(t)}()}(u,f)},n?0:300)}}}var n=t(document),r=window,o=r.location,a=function(){try{return Boolean(r.frameElement)}catch(t){return!0}}()?null:r.history,s=/^[a-zA-Z0-9][\w:.-]*$/;return{ready:function(){o.hash&&e(o.hash.substring(1));var r=o.href.split("#")[0];n.on("click","a",function(n){if(!(i.env("design")||window.$.mobile&&t(n.currentTarget).hasClass("ui-link")))if("#"!==this.getAttribute("href")){var o=this.href.split("#"),a=o[0]===r?o[1]:null;a&&e(a,n)}else n.preventDefault()})}}})},function(t,e,n){n(0).define("touch",t.exports=function(t){function e(e,n,i){var r=t.Event(e,{originalEvent:n});t(n.target).trigger(r,i)}var n={},i=!document.addEventListener,r=window.getSelection;return i&&(t.event.special.tap={bindType:"click",delegateType:"click"}),n.init=function(n){return i?null:(n="string"==typeof n?t(n).get(0):n)?new function(t){function n(t){var e=t.touches;e&&e.length>1||(l=!0,f=!1,e?(h=!0,s=e[0].clientX,u=e[0].clientY):(s=t.clientX,u=t.clientY),c=s)}function i(t){if(l){if(h&&"mousemove"===t.type)return t.preventDefault(),void t.stopPropagation();var n=t.touches,i=n?n[0].clientX:t.clientX,o=n?n[0].clientY:t.clientY,p=i-c;c=i,Math.abs(p)>d&&r&&""===String(r())&&(e("swipe",t,{direction:p>0?"right":"left"}),a()),(Math.abs(i-s)>10||Math.abs(o-u)>10)&&(f=!0)}}function o(t){if(l){if(l=!1,h&&"mouseup"===t.type)return t.preventDefault(),t.stopPropagation(),void(h=!1);f||e("tap",t)}}function a(){l=!1}var s,u,c,l=!1,f=!1,h=!1,d=Math.min(Math.round(.04*window.innerWidth),40);t.addEventListener("touchstart",n,!1),t.addEventListener("touchmove",i,!1),t.addEventListener("touchend",o,!1),t.addEventListener("touchcancel",a,!1),t.addEventListener("mousedown",n,!1),t.addEventListener("mousemove",i,!1),t.addEventListener("mouseup",o,!1),t.addEventListener("mouseout",a,!1),this.destroy=function(){t.removeEventListener("touchstart",n,!1),t.removeEventListener("touchmove",i,!1),t.removeEventListener("touchend",o,!1),t.removeEventListener("touchcancel",a,!1),t.removeEventListener("mousedown",n,!1),t.removeEventListener("mousemove",i,!1),t.removeEventListener("mouseup",o,!1),t.removeEventListener("mouseout",a,!1),t=null}}(n):null},n.instance=n.init(document),n})}]); -------------------------------------------------------------------------------- /Flask_Starter_Code/Templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Justin Flick's Cool Project 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 |

PYTHON MINECRAFT CONTROLLER

23 |
Learn Python with Minecraft
24 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Flask_Starter_Code/minecraft_controller.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, render_template 2 | #from mcpi.minecraft import Minecraft 3 | 4 | app = Flask(__name__) 5 | 6 | @app.route('/', methods=['GET']) 7 | def home(): 8 | return render_template('index.html') 9 | 10 | @app.route('/tree/', methods=['POST, GET']) 11 | def tree(): 12 | return render_template('index.html') 13 | 14 | #add house 15 | 16 | #add moat 17 | 18 | #add custom 19 | 20 | 21 | if __name__ == '__main__': 22 | app.run(debug=False, port=5000) 23 | -------------------------------------------------------------------------------- /Images/controller_screenshot.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jflick58/TeachPythonWithMinecraft/aa1dbfb72eb701b92652484ac8e1bed8a64170a9/Images/controller_screenshot.PNG -------------------------------------------------------------------------------- /Images/lava.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jflick58/TeachPythonWithMinecraft/aa1dbfb72eb701b92652484ac8e1bed8a64170a9/Images/lava.jpg -------------------------------------------------------------------------------- /Images/leaves.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jflick58/TeachPythonWithMinecraft/aa1dbfb72eb701b92652484ac8e1bed8a64170a9/Images/leaves.png -------------------------------------------------------------------------------- /Images/water.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jflick58/TeachPythonWithMinecraft/aa1dbfb72eb701b92652484ac8e1bed8a64170a9/Images/water.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Justin Flick 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Lessons/Lesson1-Variables.md: -------------------------------------------------------------------------------- 1 | # Variables 2 | 3 | ----- 4 | 5 | 6 | ##### Example 1 - Display a message 7 | 8 | Our first example of using variables will be to display a mesage in the game. Create a new script and save it as 'variables_message'. 9 | 10 | When starting a new script always remember to add the import, without this your script will not work. 11 | ```python 12 | from mcpi.minecraft import Minecraft 13 | ``` 14 | On a new line, write the following code: 15 | 16 | 17 | ```python 18 | mc.postToChat("Hello World") 19 | ``` 20 | 21 | This code will output the message within the brackets. 22 | 23 | ![finished](http://s23.postimg.org/5kh0j3ttn/145889050226849.gif) 24 | ```python 25 | from mcpi.minecraft import Minecraft 26 | mc.postToChat("Hello World") 27 | ``` 28 | Now run your script and you should see your message appear. It should look similar to the image below. 29 | 30 | ![message](http://s21.postimg.org/jjt8va6vr/unspecified_1_2.png) 31 | 32 | Instead of writing the message directly into the code, let's use a variable. 33 | 34 | Edit your code so it looks like: 35 | 36 | ``` 37 | from mcpi.minecraft import Minecraft 38 | message="Hello World" 39 | mc.postToChat(message) 40 | ``` 41 | This makes a variable called message. This variable has the text "Hello World". 42 | 43 | Now run your script and you will see the message appear in the game. 44 | 45 | When finished, save and close this script. 46 | 47 | ------- 48 | ***Questions*** 49 | 50 | 1) Create a new variable called myName that contains your name as a string and output it in the game. **Create this is a new script and save it as 'variables_question1'** 51 | 52 | ![piggy](http://i.imgur.com/cZ4tibd.gif) 53 | 54 | 55 | 2) Create a new variable called myMessage and create your own message. Display your message in the game. **Create this as a new script and save it as 'variables_question2'** 56 | 57 | ------ 58 | #### Example 2- Finding Your Position 59 | For our next example you will find your position in the game. 60 | 61 | Notice you can see your position in the top left corner of the screen. We want to find the positon using code rather than this. 62 | ![pos](http://s11.postimg.org/lpi683ytv/poscorner_1.png) 63 | 64 | Create a new script and save it as 'variables_findposition' 65 | 66 | In the game your position uses co-ordinates. In minecraft there are x,y and z co-ordinates. 67 | 68 | When you move left or right this will change the x co-ordinate. 69 | 70 | When you move higher or lower this will change the y co-ordinate. 71 | 72 | When you move forward or backwards this will change the z co-ordinate. 73 | 74 | ![graph](http://s23.postimg.org/acdqigk23/new_graph.png) 75 | 76 | So to find your position you need to find these 3 co-ordinates. 77 | 78 | We can create a variable to hold all 3 co-ordinates or create 3 seperate variables that will each hold one co-ordinate. 79 | 80 | First we will write code to store all co-ordinates in one variable. 81 | 82 | Write the following code : 83 | 84 | ```python 85 | from mcpi.minecraft import Minecraft 86 | position=mc.player.getPos() 87 | ``` 88 | Now you have created a variable called 'position' that stores all 3 co-ordinates. These are found by the code 'mc.player.getPos()'. 89 | 90 | Next we will create 3 variables each storing one co-ordinate. Edit your code to it looks like: 91 | 92 | 93 | ```python 94 | from mcpi.minecraft import Minecraft 95 | positionX,positionY,positionZ=mc.player.getPos() 96 | ``` 97 | Now three variables have been created, holding their corresponding co-ordinate 98 | 99 | Save and close the script 100 | 101 | ----- 102 | **Questions** 103 | 104 | 3) Using mc.postToChat(), display each co-ordinate in the game. 105 | **Create this in a new script and save it as 'variables_question3'** 106 | 107 | After you have done this save and close the script 108 | 109 | ----- 110 | #### Example 3- Changing Position (Teleport) 111 | 112 | As well as knowing our position, we can also change it. 113 | 114 | Create a new script and save it as 'variables_teleport'. 115 | 116 | Look at the code below: 117 | ```python 118 | mc.player.setPos(x,y,z) 119 | ``` 120 | With this you need to supply the x,y and z co-ordinate to change position in the game. Lets create these as variables. On a new line write the following: 121 | 122 | ```python 123 | x=20 124 | y=64 125 | z=30 126 | ``` 127 | You have now made the co-ordinates that you want to teleport to. 128 | 129 | Now to use these to change position, on a new line write 130 | ``` 131 | mc.playerSetPos(x,y,z) 132 | ``` 133 | 134 | 135 | 136 | ![finished](http://s23.postimg.org/5kh0j3ttn/145889050226849.gif) 137 | ```python 138 | from mcpi.minecraft import Minecraft 139 | x=20 140 | y=64 141 | z=30 142 | mc.playerSetPos(x,y,z) 143 | ``` 144 | 145 | Now run your script and see your character move ! 146 | 147 | Save and close the script. 148 | 149 | ----- 150 | **Questions** 151 | 152 | 4) Try moving your character by choosing your own co-ordinates (be careful with the y co-ordinate, if it’s too low you may teleport underground. **Create this in a new script and save it as 'variables_question4'** 153 | 154 | ![pig2](http://s23.postimg.org/ndtwrtl6z/pig2fin.gif) 155 | 156 | ------ 157 | 158 | #### Example 4- Placing A Block 159 | 160 | 161 | 162 | We will create a block in front of our character, to do this we need to use what we learnt earlier to find our position. 163 | 164 | Create a new script and save it as 'variables_placeblock'. 165 | 166 | On a new line create three variables called 'positionX','positionY' and 'positionZ', with their co-ordinates. So type: 167 | ```python 168 | from mcpi.minecraft import Minecraft 169 | positionX,positionY,positionZ=mc.player.getPos() 170 | ``` 171 | 172 | Now we know our position within the game, you can write some code to place a block in front of your character. 173 | 174 | Look at the following code: 175 | ```python 176 | mc.setBlock(x,y,z,block) 177 | ``` 178 | For the code above, we need to supply four differne values. The first three are an x,y and z co-ordinate (this is to choose where to place a block). 179 | 180 | The final value that we need is a block ID (see the blockID reference page). 181 | 182 | Let's choose a stone block to use. This has an ID of 1. We can make this a variable. 183 | 184 | On a new line write: 185 | 186 | ```python 187 | stone=1 188 | ``` 189 | You have now created a variable called stone with the ID 190 | 191 | You now have everything you need to place a block in front of your character. To do this we need to increase the z co-ordinate by one (so it appears in front). 192 | 193 | On a new line write: 194 | ```python 195 | mc.setBlock(x,y,z+1,stone) 196 | ``` 197 | ![finished](http://s23.postimg.org/5kh0j3ttn/145889050226849.gif) 198 | 199 | ```python 200 | from mcpi.minecraft import Minecraft 201 | positionX,positionY,positionZ=mc.player.getPos() 202 | stone=1 203 | mc.setBlock(x,y,z+1,stone) 204 | ``` 205 | 206 | Run your script and a block should appear in front of your character, looking similar to the image below 207 | 208 | ![Map](http://s7.postimg.org/doa0kfewr/placeblock.png) 209 | 210 | ----- 211 | **Questions** 212 | 213 | 5) Place a cobblestone block 6 spaces in front of your character.**Create this as a new script and save it as 'variables_question5'**. 214 | 215 | 6) Choose a block and place it 3 spaces behind your character. **Create this as a new script and save it as 'variables_question6'**. 216 | 217 | 7) Choose a block and place it 2 spaces to the left of your character. **Create this as a new script and save it as 'variables_question7'** 218 | 219 | ![pig3](http://i.imgur.com/hz2JDgj.gif) 220 | 221 | 222 | #### Example 5- Place many blocks 223 | 224 | Before we go further we will write some code that will replace everything with a flat level of grass blocks. 225 | 226 | Create a new script and save it as 'flatgrass'. 227 | 228 | Everything above this flat level will be removed. To do this and place more than one block we will use the code: 229 | ```python 230 | mc.setBlocks(xstart,ystart,zstart,xend,yend,zend,block) 231 | ``` 232 | This code needs 7 values. 233 | 234 | The variables 'xstart','ystart','zstart' are co-ordinates where we will start placing blocks. 235 | 236 | The values 'xend','yend','zend' are co-ordinates where we will stop placing blocks (blocks will be placed inbetween here). 237 | 238 | As we have seen before, the final value is a block ID. 239 | 240 | Write the following code: 241 | ```python 242 | from mcpi.minecraft import Minecraft 243 | grass=2 244 | air=0 245 | mc.setBlocks(-128,-64,-128,128,0,128,grass) 246 | mc.setBlocks(-128,0,-128,64,128,air) 247 | ``` 248 | ![Map](http://s14.postimg.org/ekyny1ehd/map.png) 249 | 250 | Now run your script, it should look like the image below (it may take a minute): 251 | 252 | ![Grass](http://s2.postimg.org/xht62kkzd/grass.png) 253 | 254 | Save and close the script. 255 | 256 | ![pig7](http://s28.postimg.org/5ideiwkcd/piggyhintfin.gif) 257 | -------------------------------------------------------------------------------- /Lessons/Lesson2-If Statements.md: -------------------------------------------------------------------------------- 1 | # If-Statements 2 | ---- 3 | 4 | 5 | # Example 1 6 | 7 | To show how we can use if-statements, we will write code so that something will happen when your character is at a certain position. 8 | 9 | Write the following code: 10 | ```python 11 | from mcpi.minecraft import Minecraft 12 | positionX,positionY,positionY=mc.player.getPos() 13 | if positionX>20 14 | mc.player.setPos(0,64,0) 15 | ``` 16 | In this code, an if-statement has been made. Firstly you find your position, then if the x co-ordinate is more than 20, the code in the if-statement will run. In this example that code will change your position to the middle of the map. 17 | 18 | ![test](http://s27.postimg.org/tlmcimpgz/145889192934902.gif) 19 | 20 | ---- 21 | ***Questions*** 22 | 23 | 1) Create an if-statement that will teleport your character to (20,64,0) when your z co-ordinate is greater than 23. **Create this in a new script and save it as 'ifstatement_question1'** 24 | 25 | 2) Create an if-statement that will display a message saying 'you've gone too far' when your x co-ordinate is greater than 50. **Create this as a new script and save it as 'ifstatement_question2'** 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Lessons/Lesson3-Loops.md: -------------------------------------------------------------------------------- 1 | # Loops 2 | ----- 3 | 4 | 5 | # Example 1- Keep placing blocks in front 6 | 7 | Lets take a look at an example of a 'for-loop'. This loop will keep placing blocks in front of your character. 8 | 9 | Each block will be one space further when the loop runs. 10 | 11 | Create a new script and save it as 'loops_blocksinfront'. 12 | 13 | Write the following code: 14 | 15 | ```python 16 | from mcpi.minecraft import Minecraft 17 | positionX,positionY,positionZ=mc.player.getPos() 18 | stone=1 19 | for x in range(0, 5): 20 | mc.setBlock(positionZ,positionY,positionZ+x,stone) 21 | ``` 22 | In the above code ```for x in range(0,5)``` makes the loop. 23 | 24 | To choose the length of a loop, a variable is created to count how many times it has run. 25 | 26 | For this, it is variable 'x'. This variable starts with a value of zero and when it has a value of 5, the loop will stop (the value of 'x' increases by 1, everytime the loop runs). 27 | 28 | In total, this loop will run six times, as the value starts at zero and ends at five. 29 | 30 | We can use the loop variable in our code. Notice it has been used with the z co-ordinate. Everytime the loop runs the variable will be added to the z co-ordinate so it becomes further infront of your character. 31 | 32 | 33 | Run your script and it should look like the image below: 34 | 35 | ![front](http://s27.postimg.org/be5velxgz/infront_2.png) 36 | 37 | The same thing can be done with a 'while loop'. Edit your code to use a 'while loop'. 38 | 39 | ![finished](http://s23.postimg.org/5kh0j3ttn/145889050226849.gif) 40 | ```python 41 | from mcpi.minecraft import Minecraft 42 | positionX,positionY,positionZ=mc.player.getPos() 43 | stone=1 44 | x=0 45 | while (x<5): 46 | mc.setBlock(positionZ,positionY,positionZ+x,stone) 47 | x++ 48 | 49 | ```````` 50 | 51 | This while loop will run as long as x is less than 5. Once it is 5 or more the loop will stop. At the end of each loop x is increased by 1. 52 | 53 | Save and close your script 54 | 55 | ----- 56 | ***Questions*** 57 | 58 | **After each question run the flatgrass script so there is more space in the game** 59 | 60 | 61 | 1) Write code using a for loop to place 10 Gravel blocks in front of your character. **Create this in a new script and save it as 'loops_question1'** 62 | 63 | 64 | 2) Write code using a while loop to place 7 Sand blocks to the right of your chacter. **Create this is a new script and save it as 'loops_question2'**. 65 | 66 | ![pig3](http://i.imgur.com/hz2JDgj.gif) 67 | ----- 68 | # Example 2- Create a cube 69 | 70 | In this section we will create a cube using `mc.setblocks` and a for-loop. 71 | We will create the first layer of a cube in front of our character, then repeat this with a loop. 72 | 73 | Create a new script and save it as 'loops_cube'. 74 | Write the following code: 75 | ```python 76 | from mcpi.minecraft import Minecraft 77 | positionX,positionY,positionZ=mc.player.getPos() 78 | length=5 79 | width=5 80 | stone=1 81 | mc.setBlocks(xposition,yposition,zposition+1,x+length,y,z+width,stone) 82 | ``` 83 | This will create the first layer of a cube in front of your character. As you can see, we have chosen the length and width. 84 | 85 | Run your script and it should look like the image below: 86 | 87 | ![Cube](http://s22.postimg.org/7clngq8dt/firstlayer_2.png 88 | ) 89 | We want to add more layers so it becomes taller and looks like a proper cube. To do this, we can use a 'for-loop' to repeat the code. 90 | 91 | ![finished](http://s23.postimg.org/5kh0j3ttn/145889050226849.gif) 92 | ```python 93 | from mcpi.minecraft import Minecraft 94 | xposition,yposition,zposition=mc.player.getPos() 95 | length=6 96 | height=5 97 | width=6 98 | stone=1 99 | for x in range(0, height): 100 | mc.setBlocks(xposition,yposition,zposition+1,xposition+length,yposition+x,zposi 101 | tion+width,stone 102 | ``` 103 | This loop will run 6 times making a cube with length=6, width=6 and height=6. 104 | 105 | Everytime it runs, the cube will become one block taller(as the loop variable is added to the y co-ordinate). 106 | 107 | Run your script. It should produce a 6x6x6 cube and should look like the image below: 108 | ![Cube](http://s13.postimg.org/5udnadj6v/cubeloop2.png 109 | ) 110 | 111 | 112 | ------ 113 | ***Questions*** 114 | 115 | **After each question run the flatgrass script so there is more space in the game** 116 | 117 | 3) Using a 'for-loop', create a cube 1 space in front of your character made of brick with: length=3, height=3, width=3. 118 | **Create this in a new script and save it as 'loops_question3'** 119 | 120 | 4) Using a 'for-loop', create a cube 3 spaces in front of your character made of glass with: length=4,height=7,width=4. **Create this in a new script and save it as 'loops_question4'** 121 | 122 | 5) Using a 'while loop', create a cube 2 spaces behind your characrer made of grass, make your own length, width and height. **Create this in a new script and save it as 'loops_question5'** 123 | -------------------------------------------------------------------------------- /Lessons/Lesson4-Functions.md: -------------------------------------------------------------------------------- 1 | # Functions 2 | ---- 3 | 4 | 5 | To make our code easier to use, let's look at functions. These work by first making our code in a function , and then by calling it. 6 | 7 | When making a function we need to use the ```def``` keyword. 8 | 9 | Let's turn our flat grass code into a function. 10 | 11 | Open your flatgrass script and change the code to: 12 | 13 | ``` 14 | from mcpi.minecraft import Minecraft 15 | def reset(): 16 | grass=2 17 | air=0 18 | mc.setBlocks(-128,-64,-128,128,0,128,grass) 19 | mc.setBlocks(-128,0,-128,128,64,128,air) 20 | ``` 21 | When we run this, the code will not execute because we need to call the function, so below type: 22 | ``` 23 | reset() 24 | ``` 25 | ![finished](http://s23.postimg.org/5kh0j3ttn/145889050226849.gif) 26 | ``` 27 | from mcpi.minecraft import Minecraft 28 | def reset(): 29 | grass=2 30 | air=0 31 | mc.setBlocks(-128,-64,-128,128,0,128,grass) 32 | mc.setBlocks(-128,0,-128,128,64,128,air) 33 | 34 | reset() 35 | ``` 36 | When this runs, the code will execute and your world will reset. Save and close this script. 37 | 38 | Lets take a look at a more advanced function. This time we will create a function using our code that places a block. 39 | 40 | Create a new script and save it as functions_placeblock. 41 | 42 | Write the following code: 43 | ``` 44 | from mcpi.minecraft import Minecraft 45 | def placeBlock (x,y,z,block) : 46 | mc.setBlock(x,y,z,block) 47 | ``` 48 | Now, for this function we need to give 4 values when we run it. So to run the function that creates a glass block at position x=20,y=64,z=13, on a new line write: 49 | ``` 50 | placeBlock(20,64,13,20) 51 | ``` 52 | ![finished](http://s23.postimg.org/5kh0j3ttn/145889050226849.gif) 53 | ``` 54 | from mcpi.minecraft import Minecraft 55 | def placeBlock (x,y,z,block) : 56 | mc.setBlock(x,y,z,block) 57 | 58 | placeBlock(20,64,13,20) 59 | ``` 60 | Now run your script and notice that at this position, a glass block has been created (use your teleport script if you can't see it). 61 | 62 | ---- 63 | ***Questions*** 64 | 65 | 1) Using your 'variables_message' script, create a function to disply a message. The function should be called 'displayMessage' and require one value called 'message'. **Create this as a new script and save it as 'functions_question1'.** 66 | 67 | 2) Usig your 'variables_teleport' script, create a function called 'teleport', that requires 3 values (x,y and z co-ordinates). **Create this as a new script, and save it as 'functions_question2'**. 68 | -------------------------------------------------------------------------------- /Lessons/Lesson5-Bringing It All Together with Flask.md: -------------------------------------------------------------------------------- 1 | # Bringing it all together 2 | 3 | **We will combine what we have learnt about variables, functions and loops, to create some things in the game** 4 | 5 | ----- 6 | ##### Make a tree 7 | As the flatgrass script got rid of all the trees, let's build some! 8 | 9 | Again we will use ```mc.setBlocks```. 10 | 11 | We can create a function with 2 values for trunk height and leaf height 12 | 13 | Create a new script and save it as 'structures_tree'. 14 | 15 | Write the following code: 16 | ``` 17 | def Tree (trunkHeight,leavesHeight): 18 | x,y,z=mc.player.getPos() 19 | wood=17 20 | leaves=18 21 | mc.setBlocks(x+1,y,z+1,x+1.y+trunkHeight,z+1,wood) 22 | mc.setBlocks(x-1,y+trunkHeight,z-1,x+3,y+leavesHeight,z+3,leaves) 23 | ``` 24 | Create a tree with trunk height = 6 and leaves height = 4. 25 | 26 | So add the code 27 | ```python 28 | Tree(6,4) 29 | ``` 30 | ![finished](http://s23.postimg.org/5kh0j3ttn/145889050226849.gif) 31 | ``` 32 | def Tree (trunkHeight,leavesHeight): 33 | x,y,z=mc.player.getPos() 34 | wood=17 35 | leaves=18 36 | mc.setBlocks(x+1,y,z+1,x+1.y+trunkHeight,z+1,wood) 37 | mc.setBlocks(x-1,y+trunkHeight,z-1,x+3,y+leavesHeight,z+3,leaves) 38 | 39 | Tree(6,4) 40 | ``` 41 | Run your script, it should look like the image below: 42 | 43 | ![Tree](http://s11.postimg.org/opihb6ccz/T4y_OVpg.png) 44 | 45 | Save the script. 46 | 47 | ----- 48 | ### Make a house 49 | 50 | This next section, we will write code to create a house. Lets split this into code for building walls and code for making a roof 51 | 52 | **Make walls** 53 | 54 | To create walls we will use ```mc.setBlocks``` 55 | 56 | Lets write our code using a function. The code will create 4 walls at once 57 | 58 | Write the following code: 59 | ``` 60 | def Walls(length,width,height,block): 61 | x,y,z=mc.player.getPos() 62 | mc.setBlocks(x+1,y,z+1,x+length,y+height,z+1,block) 63 | mc.setBlocks(x+length,y,z+1,x+length,y+height,z+width,block) 64 | mc.setBlocks(x+length,y,z+width,x+1,y+height,z+width,block) 65 | mc.setBlocks(x+1,y,z+1,x+1,y+height,z+width,block) 66 | ``` 67 | 68 | See the diagram below to help understand the code 69 | 70 | ![Walls](http://s10.postimg.org/vlocy0c7t/walldiagram.png) 71 | 72 | To add a door on wall 4 add the following code to your function 73 | ``` 74 | mc.setBlocks(x+1,y,z+width/2,x+1,y+1,z+width/2+1,0) 75 | ``` 76 | 77 | The diagram below shows the addition of the door 78 | 79 | ![WallsDoor](http://s21.postimg.org/69tox6bvb/walldoordiagram.png) 80 | 81 | Now run the function we have just created with length =6, width=4, height=4 and block = Wooden Planks. 82 | 83 | ![finished](http://s23.postimg.org/5kh0j3ttn/145889050226849.gif) 84 | ``` 85 | from mcpi.minecraft import Minecraft 86 | def Walls(length,width,height,block): 87 | x,y,z=mc.player.getPos() #find current position 88 | mc.setBlocks(x+1,y,z+1,x+length,y+height,z+1,block) 89 | mc.setBlocks(x+length,y,z+1,x+length,y+height,z+width,block) 90 | mc.setBlocks(x+length,y,z+width,x+1,y+height,z+width,block) 91 | mc.setBlocks(x+1,y,z+1,x+1,y+height,z+width,block) 92 | mc.setBlocks(x+1,y,z+width/2,x+1,y+1,z+width/2+1,0) 93 | 94 | Walls(6,4,4,5) 95 | ``` 96 | 97 | Run your script, it should look like the image below: 98 | 99 | ![WallsDoor](http://s23.postimg.org/slaeigziz/Capture.png) 100 | 101 | We also need to add a floor to our house. Add the following code to the walls function 102 | ``` 103 | mc.setBlocks(x+1,y-1,z+1,x+length,y-1,z+width,block) 104 | ``` 105 | ![finished](http://s23.postimg.org/5kh0j3ttn/145889050226849.gif) 106 | ``` 107 | from mcpi.minecraft import Minecraft 108 | def Walls(length,width,height,block): 109 | x,y,z=mc.player.getPos() #find current position 110 | mc.setBlocks(x+1,y,z+1,x+length,y+height,z+1,block) 111 | mc.setBlocks(x+length,y,z+1,x+length,y+height,z+width,block) 112 | mc.setBlocks(x+length,y,z+width,x+1,y+height,z+width,block) 113 | mc.setBlocks(x+1,y,z+1,x+1,y+height,z+width,block) 114 | mc.setBlocks(x+1,y,z+width/2,x+1,y+1,z+width/2+1,0) 115 | mc.setBlocks(x+1,y-1,z+1,x+length,y-1,z+width,block) 116 | 117 | Walls(6,4,4,5) 118 | ``` 119 | Now move to an empty space in the game and run the scro[t again. It should look like the image below: 120 | 121 | ![Floor](http://s17.postimg.org/rmhenoofj/XFa_YBni.png) 122 | 123 | --- 124 | ***Questions*** 125 | 126 | **Between questions run the flatgrass script so you have more space** 127 | 128 | 1) Run the script and create walls with length 4, width 4 and height 3 made from Cobblestone. **Create this as a new script and save it as 'walls_question1'** 129 | 130 | 2) Run the script again to create walls with length 5, width 4 and height 4 made from Glass. **Create this as a new script and save it as 'walls_question2'** 131 | 132 | ---- 133 | 134 | 135 | **Creating a roof** 136 | 137 | We now need to create a new function to create a roof, add the following function to your script: 138 | ``` 139 | 140 | def Roof(length, startheight,width,block,total height): 141 | x,y,z=mc.player.getPos() 142 | for xheight in range(0,length/2): 143 | mc.setBlocks(x+1,startheight+xheight,z+1,x+length,startheight+xheight,z+ 144 | width,block) 145 | x+=1 146 | length-=2 147 | z+=1 148 | width-=2 149 | ``` 150 | This code uses a loop to build the roof. It builds it layer by layer, gradually getting smaller. 151 | 152 | We can use both the roof and wall functions to build a house 153 | ``` 154 | Wall(8,6,4,5) 155 | Roof(8,4,6,1,3) 156 | ``` 157 | ![finished](http://s23.postimg.org/5kh0j3ttn/145889050226849.gif) 158 | ```python 159 | def Walls(length,width,height,block): 160 | x,y,z=mc.player.getPos() #find current position 161 | mc.setBlocks(x+1,y,z+1,x+length,y+height,z+1,block) 162 | mc.setBlocks(x+length,y,z+1,x+length,y+height,z+width,block) 163 | mc.setBlocks(x+length,y,z+width,x+1,y+height,z+width,block) 164 | mc.setBlocks(x+1,y,z+1,x+1,y+height,z+width,block) 165 | mc.setBlocks(x+1,y,z+width/2,x+1,y+1,z+width/2+1,0) 166 | mc.setBlocks(x+1,y-1,z+1,x+length,y-1,z+width,block) 167 | 168 | def Roof(length, startheight,width,block,total height): 169 | x,y,z=mc.player.getPos() 170 | for xheight in range(0,length/2): 171 | mc.setBlocks(x+1,startheight+xheight,z+1,x+length,startheight+xheight,z+ 172 | width,block) 173 | x+=1 174 | length-=2 175 | z+=1 176 | width-=2 177 | 178 | Wall(8,6,4,5) 179 | Roof(8,4,6,1,3) 180 | ``` 181 | 182 | With these functions, it's important to specify the same length, width and height/start height. 183 | 184 | When it runs it should look like the image below: 185 | 186 | ![House](http://s22.postimg.org/3phqz8jkh/house.png) 187 | 188 | 189 | 190 | **Adding a moat** 191 | 192 | Let's build upon our code to build a house, by adding a moat around the outside. 193 | 194 | Add the following function to your script: 195 | ``` 196 | def Moat(length,width): 197 | water=8 198 | mc.setBlocks(x-1,y-1,z-1,x+length+2,y-1,z+width+2,water) 199 | ``` 200 | Remember to use the same length and width as the walls and roof function. 201 | 202 | ``` 203 | Moat(8,4) 204 | Wall(8,6,4,5) 205 | Roof(8,4,6,1,3) 206 | ``` 207 | ![finished](http://s23.postimg.org/5kh0j3ttn/145889050226849.gif) 208 | ```python 209 | from mcpi.minecraft import Minecraft 210 | def Walls(length,width,height,block): 211 | x,y,z=mc.player.getPos() #find current position 212 | mc.setBlocks(x+1,y,z+1,x+length,y+height,z+1,block) 213 | mc.setBlocks(x+length,y,z+1,x+length,y+height,z+width,block) 214 | mc.setBlocks(x+length,y,z+width,x+1,y+height,z+width,block) 215 | mc.setBlocks(x+1,y,z+1,x+1,y+height,z+width,block) 216 | mc.setBlocks(x+1,y,z+width/2,x+1,y+1,z+width/2+1,0) 217 | mc.setBlocks(x+1,y-1,z+1,x+length,y-1,z+width,block) 218 | 219 | def Roof(length, startheight,width,block,total height): 220 | x,y,z=mc.player.getPos() 221 | for xheight in range(0,length/2): 222 | mc.setBlocks(x+1,startheight+xheight,z+1,x+length,startheight+xheight,z+ 223 | width,block) 224 | x+=1 225 | length-=2 226 | z+=1 227 | width-=2 228 | 229 | def Moat(length,width): 230 | water=8 231 | mc.setBlocks(x-1,y-1,z-1,x+length+2,y-1,z+width+2,water) 232 | 233 | Moat(8,4) 234 | Wall(8,6,4,5) 235 | Roof(8,4,6,1,3) 236 | ``` 237 | 238 | Now run this and it should look like the image below 239 | ![Moat](http://i.imgur.com/748gwAb.png) 240 | 241 | ----- 242 | ***Connecting to Flask*** 243 | 244 | Flask is a simple Python framework for interacting with web sites and HTTP requests. 245 | 246 | Open "minecraft_controller.py" which is located inside the "Flask_Starter_Code" file. 247 | 248 | Look for the block of code that looks like this: 249 | ```python 250 | @app.route('/tree/', methods=['GET']) 251 | def tree(): 252 | return render_template('index.html') 253 | ``` 254 | 255 | This an example of how Flask connects Python to a web page. ```@app.route('/tree/', methods=['GET'])``` defines the URL that triggers your Python code to do something. For example, once we run Flask, if you navigate to ```127.0.0.1/tree/```, you will trigger your script to create a tree. 256 | 257 | ```def tree()``` defines our Tree function within our Flask application. ```return render_template('index.html')``` defines our response. In Flask, rendering a template is how we show a website. 258 | 259 | Let's make ```tree()``` actually do something. At the top of the script, add ```from structures_tree import Tree``` 260 | 261 | Add the following code below ```def tree()``` 262 | 263 | ``` 264 | Tree(6,4) 265 | ``` 266 | 267 | ![finished](http://s23.postimg.org/5kh0j3ttn/145889050226849.gif) 268 | ``` 269 | @app.route('/tree/', methods=['GET']) 270 | def tree(): 271 | Tree(6,4) 272 | return render_template('index.html') 273 | ``` 274 | 275 | Save your script and run it. Navigate to 127.0.0.1:5000 in your browser. 276 | 277 | You should see this: 278 | 279 | ![screenshot](https://github.com/Jflick58/TeachPythonWithMinecraft/blob/master/Images/controller_screenshot.PNG) 280 | 281 | Click the tree button. You should see a tree appear in front of you in the game! 282 | 283 | 284 | ***Questions*** 285 | 286 | **Between questions, run your 'flatgrass' script so you have more space**. 287 | 288 | 289 | 1) Build the following structure: 290 | 291 | 292 | ![house1](http://i.imgur.com/7kuhTgL.gif?1) 293 | 294 | 295 | **Create in a new script and save as 'structures_question1'** 296 | 297 | 2) Build the following structure: 298 | 299 | ![house2](http://i.imgur.com/CSDaOYx.gif?) 300 | 301 | **Create in a new script and save as 'structures_question2'** 302 | 303 | 3) Build the following structure: 304 | 305 | ![house3](http://i.imgur.com/L2OKrlP.gif?1) 306 | 307 | **Create in a new script and save as 'structures_question3'** 308 | 309 | 310 | 4) Add the following: 311 | 312 | Write an ```app.route(url, method)``` that creates a house. 313 | 314 | **Save in mincecraft_controller.py** 315 | 316 | 5) Add the following: 317 | 318 | Write an ```app.route(url, method)``` that creates a moat. 319 | 320 | **Save in mincecraft_controller.py** 321 | 322 | 6) Add the following: 323 | 324 | Write an ```app.route(url, method)``` that creates a custom structure of your choosing! 325 | 326 | **Save in mincecraft_controller.py** 327 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TeachPythonWithMinecraft 2 | Teaching Python programming and concepts using the Python Minecraft API for the Raspberry Pi version of Minecraft. 3 | 4 | ![alt text](https://www.evcomputing.com/wp-content/uploads/2016/05/minecraft-python.png) 5 | 6 | ## Background 7 | This is the repo for the Florin High School (Sacramento, CA) Python workshop at KPMG. In this workshop, you'll learn Python programming and programming concepts by writing methods to control in-game Minecraft activites, and then you will connect those actions to a Flask-based website to act as a controller. We distributed Rapsberry Pi to the students for them to take with them after the workshop. If you don't have a rapsberry pi, you can emulate one on any Mac, Windows or Linux computer by following the instructions in [this link.](https://azeria-labs.com/emulate-raspberry-pi-with-qemu/) 8 | 9 | You'll learn: 10 | 11 | - Basic version control with Github 12 | - Python Virtual Environments 13 | - Dependency Management 14 | - Variables 15 | - If Statements 16 | - Loops 17 | - Functions 18 | - Backend Web Development concepts 19 | 20 | __All this culminating in a Flask-based Web controller for Minecraft Pi!__ 21 | 22 | ![Controller](https://github.com/Jflick58/TeachPythonWithMinecraft/blob/master/Images/controller_screenshot.PNG) 23 | 24 | ## How to use this repo 25 | 1. Login to github with your account 26 | 27 | 2. Click the "Star" button in the upper right hand corner. 28 | 29 | 3. Click the "Fork" button 30 | 31 | 4. Wait while Github copies the repo to your account 32 | 33 | 5. Click the "Clone/Download" button and download the repo as a zip file to your machine 34 | 35 | 6. Unzip the repo. Open a command prompt and `CD` to the location you extracted the repo to. 36 | 37 | 7. Type `virtualenv venv` and hit enter. 38 | 39 | 8. Wait while the virtual environment is activated. Then, type `source venv/bin/activate` and hit enter. 40 | 41 | 9. You should see (venv) on the left side of your command prompt. Type `pip3 install -r requirements.txt` and hit enter 42 | 43 | 10. You are ready to start learning Python with Minecraft! Bonus: You finished your first lesson on version control, virtual environments, and dependency management! __Good Job!__ 44 | 45 | 11. Follow the lessons in the Lessons Folder. 46 | 47 | ## Useful Information 48 | 49 | ##### Create a script 50 | 51 | Once the Pi has loaded and you are at the desktop screen, click on 52 | Menu then Programming and choose Python IDE3 53 | 54 | Click file and select click script. To save, go to file then click save as. 55 | 56 | We need to add an import for our script that will allow us to control Minecraft, type this code into the first line of your script 57 | 58 | ```python 59 | from mcpi.minecraft import Minecraft 60 | 61 | mc = Minecraft.create() 62 | ``` 63 | **This import will need to be entered for every script you create** 64 | 65 | You can move to a new line in a script by pressing enter 66 | 67 | A script can be run by pressing f5 or going to the run option on the top menu bar 68 | 69 | ##### Load Minecraft 70 | Go to menu, go to games and click Minecraft. Bring this window alongside your Python script window so it is easier to use. You can move between the game and scripts by pressing the tab button. 71 | 72 | In Minecraft click 'Create new world'. When this loads it will look something like the image below. Everyone’s will look different when it first loads. 73 | ![Start](http://s8.postimg.org/8prlw8b1h/start.png) 74 | 75 | ##### Moving around the game 76 | 77 | To move around the game, you can use the arrow keys and use the space button to jump. 78 | 79 | ##### Hints 80 | 81 | Look out for Pete the pig. For some questions he'll give hints on how to do them. 82 | 83 | ![pig](http://i.imgur.com/de99x5z.gif) 84 | 85 | ##### What if something goes wrong ? 86 | 87 | If you get an error saying 'Syntax error' double check you have typed everything correctly and try running your script again. 88 | 89 | ### Targeted Curriculum 90 | ##### Key Stage 2 91 | 92 | • Design, write and debug programs that accomplish specific goals, including controlling or simulating physical systems; solve problems by decomposing them into smaller parts. 93 | 94 | • Use sequence, selection, and repetition in programs; work with variables and various forms of input and output. 95 | 96 | ##### Key Stage 3 97 | 98 | • Use 2 or more programming languages, at least one of which is textual, to solve a variety of computational problems; make appropriate use of data structures, design and develop modular programs that use procedures or functions. 99 | 100 | ### Useful Block ID's 101 | 102 | |Block |ID | Picture | Block |ID | Picture 103 | | ------------- |:-------------:|:-----:|:--------:|:---------:|------:| 104 | | Air | 0 | |Wood Planks|5|![Woodplank](http://s2.postimg.org/5jw81562d/Oak_Wood_Planks.png) 105 | | Stone | 1 | ![Stone](http://s16.postimg.org/8dg24cetd/Stone.png) |Bedrock|7|![Bedrock](http://s11.postimg.org/lkdwx47gf/Bedrock.png) 106 | | Grass | 2 | ![Grass](http://s23.postimg.org/ubtw3m0nb/Grass.png) |Sand|12|![Sand](http://s21.postimg.org/tkun3jj03/Sand.png) 107 | |Dirt | 3| ![Dirt](http://s24.postimg.org/deit4k2ht/dirt.png)|Gravel|13|![Gravel](http://s17.postimg.org/fj8gcdvp7/Gravel_Pre_12w21a.png) 108 | |Cobblestone| 4| ![Cobble](http://s13.postimg.org/uey7u78s3/Cobblestone.png)|Glass|20|![Glass](http://s14.postimg.org/ig3w5w3m5/Glass.png) 109 | |Leaves|18|![Leaves](https://github.com/Jflick58/TeachPythonWithMinecraft/blob/master/Images/leaves.png)|Lava|11|![Lava](https://github.com/Jflick58/TeachPythonWithMinecraft/blob/master/Images/lava.jpg) 110 | |Water|9|![Water](https://github.com/Jflick58/TeachPythonWithMinecraft/blob/master/Images/water.png) 111 | 112 | ## Credits 113 | 114 | - Github user [jeremycook94](https://github.com/jeremycook94/Project) for creating most of the lesson plans. 115 | - [EV Computing](https://www.evcomputing.com/classdescriptions/minecraft-programming-with-python) for the readme image. 116 | - [The Raspberry Pi Foundation](https://projects.raspberrypi.org/en/projects/getting-started-with-minecraft-pi) for their work on Rapsberry Pi, and the Raspbian image that contains the Python and Minecraft distributions used in this workshop. 117 | - KPMG cowowrkers Matt Kwong, Andrew Suarez-Lopez, and Frank Wright 118 | 119 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | click==6.7 3 | Flask==0.12.2 4 | itsdangerous==0.24 5 | Jinja2==2.10 6 | MarkupSafe==1.0 7 | Werkzeug==0.14.1 8 | >>>>>>> cfc69230c8cb09eae8376a9e54fbd64ed7db2584 9 | --------------------------------------------------------------------------------