├── LICENSE ├── README.md ├── css ├── bootstrap.min.css ├── images │ ├── layers-2x.png │ ├── layers.png │ ├── marker-icon-2x.png │ ├── marker-icon.png │ ├── marker-shadow.png │ ├── ui-icons_444444_256x240.png │ ├── ui-icons_555555_256x240.png │ └── ui-icons_777777_256x240.png ├── jquery-ui.css ├── leaflet.css └── predictor.css ├── favicon.ico ├── images ├── arrow.png ├── balloon-sm.png ├── balloon.png ├── csv.gif ├── drag_handle.png ├── kml.png ├── marker-sm-black.png ├── marker-sm-red.png ├── pop-marker.png ├── target-1-sm.png ├── target-1.png ├── target-10.png ├── target-11.png ├── target-12.png ├── target-13.png ├── target-14.png ├── target-15.png ├── target-16.png ├── target-17.png ├── target-18.png ├── target-2.png ├── target-3.png ├── target-4.png ├── target-5.png ├── target-6.png ├── target-7.png ├── target-8-sm.png ├── target-8.png ├── target-9.png ├── target-blue.png ├── target-red.png ├── target-yellow.png └── tipsy.gif ├── index.html ├── js ├── Leaflet.Control.Custom.js ├── calc │ └── calc.js ├── colour-map.js ├── jquery-3.3.1.min.js ├── jquery-ui.min.js ├── jquery.form.js ├── jquery.jookie.js ├── jquery.tipsy.js ├── leaflet.js ├── moment.js └── pred │ ├── pred-config.js │ ├── pred-cookie.js │ ├── pred-event.js │ ├── pred-map.js │ ├── pred-new.js │ ├── pred-ui.js │ └── pred.js ├── sites.json └── test.py /README.md: -------------------------------------------------------------------------------- 1 | # CUSF Landing Predictor - Tawhiri / Leaflet Version 2 | 3 | Cambridge University Spaceflight landing predictor - a web-based tool for predicting the flight path and landing location of latex meteorological sounding balloons. 4 | 5 | This fork of the [original predictor](https://github.com/jonsowman/cusf-standalone-predictor) contains a continuation of the original CUSF predictor, which utilises the [Tawhiri API](https://github.com/projecthorus/tawhiri/), and also uses Leaflet for mapping instead of Google Maps. 6 | 7 | A live version of the predictor intended for non-commercial use is available at http://predict.sondehub.org/ , hosted by the [Sondehub project](https://github.com/projecthorus/sondehub-infra/wiki). 8 | 9 | If hosting this yourself, please note that it uses the Sondehub-hosted instance of Tawhiri. Please [contact us](https://github.com/projecthorus/sondehub-infra/wiki#contacts) to discuss fair usage of this API. 10 | 11 | ## License 12 | 13 | This work is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or any later version. This work is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. 14 | 15 | ## Credits & Acknowledgments 16 | Credit as detailed in individual files, but notably: 17 | 18 | * Rich Wareham - The new predictor and the hourly predictor system 19 | * Fergus Noble, Ed Moore and many others 20 | * Adam Grieg 21 | * Jon Sowman 22 | 23 | Work to switch the predictor across to Tawhiri, and addition of other features by: 24 | * Mark Jessop - 25 | 26 | -------------------------------------------------------------------------------- /css/images/layers-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/css/images/layers-2x.png -------------------------------------------------------------------------------- /css/images/layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/css/images/layers.png -------------------------------------------------------------------------------- /css/images/marker-icon-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/css/images/marker-icon-2x.png -------------------------------------------------------------------------------- /css/images/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/css/images/marker-icon.png -------------------------------------------------------------------------------- /css/images/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/css/images/marker-shadow.png -------------------------------------------------------------------------------- /css/images/ui-icons_444444_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/css/images/ui-icons_444444_256x240.png -------------------------------------------------------------------------------- /css/images/ui-icons_555555_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/css/images/ui-icons_555555_256x240.png -------------------------------------------------------------------------------- /css/images/ui-icons_777777_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/css/images/ui-icons_777777_256x240.png -------------------------------------------------------------------------------- /css/leaflet.css: -------------------------------------------------------------------------------- 1 | /* required styles */ 2 | 3 | .leaflet-pane, 4 | .leaflet-tile, 5 | .leaflet-marker-icon, 6 | .leaflet-marker-shadow, 7 | .leaflet-tile-container, 8 | .leaflet-pane > svg, 9 | .leaflet-pane > canvas, 10 | .leaflet-zoom-box, 11 | .leaflet-image-layer, 12 | .leaflet-layer { 13 | position: absolute; 14 | left: 0; 15 | top: 0; 16 | } 17 | .leaflet-container { 18 | overflow: hidden; 19 | } 20 | .leaflet-tile, 21 | .leaflet-marker-icon, 22 | .leaflet-marker-shadow { 23 | -webkit-user-select: none; 24 | -moz-user-select: none; 25 | user-select: none; 26 | -webkit-user-drag: none; 27 | } 28 | /* Safari renders non-retina tile on retina better with this, but Chrome is worse */ 29 | .leaflet-safari .leaflet-tile { 30 | image-rendering: -webkit-optimize-contrast; 31 | } 32 | /* hack that prevents hw layers "stretching" when loading new tiles */ 33 | .leaflet-safari .leaflet-tile-container { 34 | width: 1600px; 35 | height: 1600px; 36 | -webkit-transform-origin: 0 0; 37 | } 38 | .leaflet-marker-icon, 39 | .leaflet-marker-shadow { 40 | display: block; 41 | } 42 | /* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */ 43 | /* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */ 44 | .leaflet-container .leaflet-overlay-pane svg, 45 | .leaflet-container .leaflet-marker-pane img, 46 | .leaflet-container .leaflet-shadow-pane img, 47 | .leaflet-container .leaflet-tile-pane img, 48 | .leaflet-container img.leaflet-image-layer { 49 | max-width: none !important; 50 | max-height: none !important; 51 | } 52 | 53 | .leaflet-container.leaflet-touch-zoom { 54 | -ms-touch-action: pan-x pan-y; 55 | touch-action: pan-x pan-y; 56 | } 57 | .leaflet-container.leaflet-touch-drag { 58 | -ms-touch-action: pinch-zoom; 59 | /* Fallback for FF which doesn't support pinch-zoom */ 60 | touch-action: none; 61 | touch-action: pinch-zoom; 62 | } 63 | .leaflet-container.leaflet-touch-drag.leaflet-touch-zoom { 64 | -ms-touch-action: none; 65 | touch-action: none; 66 | } 67 | .leaflet-container { 68 | -webkit-tap-highlight-color: transparent; 69 | } 70 | .leaflet-container a { 71 | -webkit-tap-highlight-color: rgba(51, 181, 229, 0.4); 72 | } 73 | .leaflet-tile { 74 | filter: inherit; 75 | visibility: hidden; 76 | } 77 | .leaflet-tile-loaded { 78 | visibility: inherit; 79 | } 80 | .leaflet-zoom-box { 81 | width: 0; 82 | height: 0; 83 | -moz-box-sizing: border-box; 84 | box-sizing: border-box; 85 | z-index: 800; 86 | } 87 | /* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */ 88 | .leaflet-overlay-pane svg { 89 | -moz-user-select: none; 90 | } 91 | 92 | .leaflet-pane { z-index: 400; } 93 | 94 | .leaflet-tile-pane { z-index: 200; } 95 | .leaflet-overlay-pane { z-index: 400; } 96 | .leaflet-shadow-pane { z-index: 500; } 97 | .leaflet-marker-pane { z-index: 600; } 98 | .leaflet-tooltip-pane { z-index: 650; } 99 | .leaflet-popup-pane { z-index: 700; } 100 | 101 | .leaflet-map-pane canvas { z-index: 100; } 102 | .leaflet-map-pane svg { z-index: 200; } 103 | 104 | .leaflet-vml-shape { 105 | width: 1px; 106 | height: 1px; 107 | } 108 | .lvml { 109 | behavior: url(#default#VML); 110 | display: inline-block; 111 | position: absolute; 112 | } 113 | 114 | 115 | /* control positioning */ 116 | 117 | .leaflet-control { 118 | position: relative; 119 | z-index: 800; 120 | pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ 121 | pointer-events: auto; 122 | } 123 | .leaflet-top, 124 | .leaflet-bottom { 125 | position: absolute; 126 | z-index: 1000; 127 | pointer-events: none; 128 | } 129 | .leaflet-top { 130 | top: 0; 131 | } 132 | .leaflet-right { 133 | right: 0; 134 | } 135 | .leaflet-bottom { 136 | bottom: 0; 137 | } 138 | .leaflet-left { 139 | left: 0; 140 | } 141 | .leaflet-control { 142 | float: left; 143 | clear: both; 144 | } 145 | .leaflet-right .leaflet-control { 146 | float: right; 147 | } 148 | .leaflet-top .leaflet-control { 149 | margin-top: 10px; 150 | } 151 | .leaflet-bottom .leaflet-control { 152 | margin-bottom: 10px; 153 | } 154 | .leaflet-left .leaflet-control { 155 | margin-left: 10px; 156 | } 157 | .leaflet-right .leaflet-control { 158 | margin-right: 10px; 159 | } 160 | 161 | 162 | /* zoom and fade animations */ 163 | 164 | .leaflet-fade-anim .leaflet-tile { 165 | will-change: opacity; 166 | } 167 | .leaflet-fade-anim .leaflet-popup { 168 | opacity: 0; 169 | -webkit-transition: opacity 0.2s linear; 170 | -moz-transition: opacity 0.2s linear; 171 | -o-transition: opacity 0.2s linear; 172 | transition: opacity 0.2s linear; 173 | } 174 | .leaflet-fade-anim .leaflet-map-pane .leaflet-popup { 175 | opacity: 1; 176 | } 177 | .leaflet-zoom-animated { 178 | -webkit-transform-origin: 0 0; 179 | -ms-transform-origin: 0 0; 180 | transform-origin: 0 0; 181 | } 182 | .leaflet-zoom-anim .leaflet-zoom-animated { 183 | will-change: transform; 184 | } 185 | .leaflet-zoom-anim .leaflet-zoom-animated { 186 | -webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1); 187 | -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1); 188 | -o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1); 189 | transition: transform 0.25s cubic-bezier(0,0,0.25,1); 190 | } 191 | .leaflet-zoom-anim .leaflet-tile, 192 | .leaflet-pan-anim .leaflet-tile { 193 | -webkit-transition: none; 194 | -moz-transition: none; 195 | -o-transition: none; 196 | transition: none; 197 | } 198 | 199 | .leaflet-zoom-anim .leaflet-zoom-hide { 200 | visibility: hidden; 201 | } 202 | 203 | 204 | /* cursors */ 205 | 206 | .leaflet-interactive { 207 | cursor: pointer; 208 | } 209 | .leaflet-grab { 210 | cursor: -webkit-grab; 211 | cursor: -moz-grab; 212 | } 213 | .leaflet-crosshair, 214 | .leaflet-crosshair .leaflet-interactive { 215 | cursor: crosshair; 216 | } 217 | .leaflet-popup-pane, 218 | .leaflet-control { 219 | cursor: auto; 220 | } 221 | .leaflet-dragging .leaflet-grab, 222 | .leaflet-dragging .leaflet-grab .leaflet-interactive, 223 | .leaflet-dragging .leaflet-marker-draggable { 224 | cursor: move; 225 | cursor: -webkit-grabbing; 226 | cursor: -moz-grabbing; 227 | } 228 | 229 | /* marker & overlays interactivity */ 230 | .leaflet-marker-icon, 231 | .leaflet-marker-shadow, 232 | .leaflet-image-layer, 233 | .leaflet-pane > svg path, 234 | .leaflet-tile-container { 235 | pointer-events: none; 236 | } 237 | 238 | .leaflet-marker-icon.leaflet-interactive, 239 | .leaflet-image-layer.leaflet-interactive, 240 | .leaflet-pane > svg path.leaflet-interactive { 241 | pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ 242 | pointer-events: auto; 243 | } 244 | 245 | /* visual tweaks */ 246 | 247 | .leaflet-container { 248 | background: #ddd; 249 | outline: 0; 250 | } 251 | .leaflet-container a { 252 | color: #0078A8; 253 | } 254 | .leaflet-container a.leaflet-active { 255 | outline: 2px solid orange; 256 | } 257 | .leaflet-zoom-box { 258 | border: 2px dotted #38f; 259 | background: rgba(255,255,255,0.5); 260 | } 261 | 262 | 263 | /* general typography */ 264 | .leaflet-container { 265 | font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif; 266 | } 267 | 268 | 269 | /* general toolbar styles */ 270 | 271 | .leaflet-bar { 272 | box-shadow: 0 1px 5px rgba(0,0,0,0.65); 273 | border-radius: 4px; 274 | } 275 | .leaflet-bar a, 276 | .leaflet-bar a:hover { 277 | background-color: #fff; 278 | border-bottom: 1px solid #ccc; 279 | width: 26px; 280 | height: 26px; 281 | line-height: 26px; 282 | display: block; 283 | text-align: center; 284 | text-decoration: none; 285 | color: black; 286 | } 287 | .leaflet-bar a, 288 | .leaflet-control-layers-toggle { 289 | background-position: 50% 50%; 290 | background-repeat: no-repeat; 291 | display: block; 292 | } 293 | .leaflet-bar a:hover { 294 | background-color: #f4f4f4; 295 | } 296 | .leaflet-bar a:first-child { 297 | border-top-left-radius: 4px; 298 | border-top-right-radius: 4px; 299 | } 300 | .leaflet-bar a:last-child { 301 | border-bottom-left-radius: 4px; 302 | border-bottom-right-radius: 4px; 303 | border-bottom: none; 304 | } 305 | .leaflet-bar a.leaflet-disabled { 306 | cursor: default; 307 | background-color: #f4f4f4; 308 | color: #bbb; 309 | } 310 | 311 | .leaflet-touch .leaflet-bar a { 312 | width: 30px; 313 | height: 30px; 314 | line-height: 30px; 315 | } 316 | .leaflet-touch .leaflet-bar a:first-child { 317 | border-top-left-radius: 2px; 318 | border-top-right-radius: 2px; 319 | } 320 | .leaflet-touch .leaflet-bar a:last-child { 321 | border-bottom-left-radius: 2px; 322 | border-bottom-right-radius: 2px; 323 | } 324 | 325 | /* zoom control */ 326 | 327 | .leaflet-control-zoom-in, 328 | .leaflet-control-zoom-out { 329 | font: bold 18px 'Lucida Console', Monaco, monospace; 330 | text-indent: 1px; 331 | } 332 | 333 | .leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out { 334 | font-size: 22px; 335 | } 336 | 337 | 338 | /* layers control */ 339 | 340 | .leaflet-control-layers { 341 | box-shadow: 0 1px 5px rgba(0,0,0,0.4); 342 | background: #fff; 343 | border-radius: 5px; 344 | } 345 | .leaflet-control-layers-toggle { 346 | background-image: url(images/layers.png); 347 | width: 36px; 348 | height: 36px; 349 | } 350 | .leaflet-retina .leaflet-control-layers-toggle { 351 | background-image: url(images/layers-2x.png); 352 | background-size: 26px 26px; 353 | } 354 | .leaflet-touch .leaflet-control-layers-toggle { 355 | width: 44px; 356 | height: 44px; 357 | } 358 | .leaflet-control-layers .leaflet-control-layers-list, 359 | .leaflet-control-layers-expanded .leaflet-control-layers-toggle { 360 | display: none; 361 | } 362 | .leaflet-control-layers-expanded .leaflet-control-layers-list { 363 | display: block; 364 | position: relative; 365 | } 366 | .leaflet-control-layers-expanded { 367 | padding: 6px 10px 6px 6px; 368 | color: #333; 369 | background: #fff; 370 | } 371 | .leaflet-control-layers-scrollbar { 372 | overflow-y: scroll; 373 | overflow-x: hidden; 374 | padding-right: 5px; 375 | } 376 | .leaflet-control-layers-selector { 377 | margin-top: 2px; 378 | position: relative; 379 | top: 1px; 380 | } 381 | .leaflet-control-layers label { 382 | display: block; 383 | } 384 | .leaflet-control-layers-separator { 385 | height: 0; 386 | border-top: 1px solid #ddd; 387 | margin: 5px -10px 5px -6px; 388 | } 389 | 390 | /* Default icon URLs */ 391 | .leaflet-default-icon-path { 392 | background-image: url(images/marker-icon.png); 393 | } 394 | 395 | 396 | /* attribution and scale controls */ 397 | 398 | .leaflet-container .leaflet-control-attribution { 399 | background: #fff; 400 | background: rgba(255, 255, 255, 0.7); 401 | margin: 0; 402 | } 403 | .leaflet-control-attribution, 404 | .leaflet-control-scale-line { 405 | padding: 0 5px; 406 | color: #333; 407 | } 408 | .leaflet-control-attribution a { 409 | text-decoration: none; 410 | } 411 | .leaflet-control-attribution a:hover { 412 | text-decoration: underline; 413 | } 414 | .leaflet-container .leaflet-control-attribution, 415 | .leaflet-container .leaflet-control-scale { 416 | font-size: 11px; 417 | } 418 | .leaflet-left .leaflet-control-scale { 419 | margin-left: 5px; 420 | } 421 | .leaflet-bottom .leaflet-control-scale { 422 | margin-bottom: 5px; 423 | } 424 | .leaflet-control-scale-line { 425 | border: 2px solid #777; 426 | border-top: none; 427 | line-height: 1.1; 428 | padding: 2px 5px 1px; 429 | font-size: 11px; 430 | white-space: nowrap; 431 | overflow: hidden; 432 | -moz-box-sizing: border-box; 433 | box-sizing: border-box; 434 | 435 | background: #fff; 436 | background: rgba(255, 255, 255, 0.5); 437 | } 438 | .leaflet-control-scale-line:not(:first-child) { 439 | border-top: 2px solid #777; 440 | border-bottom: none; 441 | margin-top: -2px; 442 | } 443 | .leaflet-control-scale-line:not(:first-child):not(:last-child) { 444 | border-bottom: 2px solid #777; 445 | } 446 | 447 | .leaflet-touch .leaflet-control-attribution, 448 | .leaflet-touch .leaflet-control-layers, 449 | .leaflet-touch .leaflet-bar { 450 | box-shadow: none; 451 | } 452 | .leaflet-touch .leaflet-control-layers, 453 | .leaflet-touch .leaflet-bar { 454 | border: 2px solid rgba(0,0,0,0.2); 455 | background-clip: padding-box; 456 | } 457 | 458 | 459 | /* popup */ 460 | 461 | .leaflet-popup { 462 | position: absolute; 463 | text-align: center; 464 | margin-bottom: 20px; 465 | } 466 | .leaflet-popup-content-wrapper { 467 | padding: 1px; 468 | text-align: left; 469 | border-radius: 12px; 470 | } 471 | .leaflet-popup-content { 472 | margin: 13px 19px; 473 | line-height: 1.4; 474 | } 475 | .leaflet-popup-content p { 476 | margin: 18px 0; 477 | } 478 | .leaflet-popup-tip-container { 479 | width: 40px; 480 | height: 20px; 481 | position: absolute; 482 | left: 50%; 483 | margin-left: -20px; 484 | overflow: hidden; 485 | pointer-events: none; 486 | } 487 | .leaflet-popup-tip { 488 | width: 17px; 489 | height: 17px; 490 | padding: 1px; 491 | 492 | margin: -10px auto 0; 493 | 494 | -webkit-transform: rotate(45deg); 495 | -moz-transform: rotate(45deg); 496 | -ms-transform: rotate(45deg); 497 | -o-transform: rotate(45deg); 498 | transform: rotate(45deg); 499 | } 500 | .leaflet-popup-content-wrapper, 501 | .leaflet-popup-tip { 502 | background: white; 503 | color: #333; 504 | box-shadow: 0 3px 14px rgba(0,0,0,0.4); 505 | } 506 | .leaflet-container a.leaflet-popup-close-button { 507 | position: absolute; 508 | top: 0; 509 | right: 0; 510 | padding: 4px 4px 0 0; 511 | border: none; 512 | text-align: center; 513 | width: 18px; 514 | height: 14px; 515 | font: 16px/14px Tahoma, Verdana, sans-serif; 516 | color: #c3c3c3; 517 | text-decoration: none; 518 | font-weight: bold; 519 | background: transparent; 520 | } 521 | .leaflet-container a.leaflet-popup-close-button:hover { 522 | color: #999; 523 | } 524 | .leaflet-popup-scrolled { 525 | overflow: auto; 526 | border-bottom: 1px solid #ddd; 527 | border-top: 1px solid #ddd; 528 | } 529 | 530 | .leaflet-oldie .leaflet-popup-content-wrapper { 531 | zoom: 1; 532 | } 533 | .leaflet-oldie .leaflet-popup-tip { 534 | width: 24px; 535 | margin: 0 auto; 536 | 537 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; 538 | filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); 539 | } 540 | .leaflet-oldie .leaflet-popup-tip-container { 541 | margin-top: -1px; 542 | } 543 | 544 | .leaflet-oldie .leaflet-control-zoom, 545 | .leaflet-oldie .leaflet-control-layers, 546 | .leaflet-oldie .leaflet-popup-content-wrapper, 547 | .leaflet-oldie .leaflet-popup-tip { 548 | border: 1px solid #999; 549 | } 550 | 551 | 552 | /* div icon */ 553 | 554 | .leaflet-div-icon { 555 | background: #fff; 556 | border: 1px solid #666; 557 | } 558 | 559 | 560 | /* Tooltip */ 561 | /* Base styles for the element that has a tooltip */ 562 | .leaflet-tooltip { 563 | position: absolute; 564 | padding: 6px; 565 | background-color: #fff; 566 | border: 1px solid #fff; 567 | border-radius: 3px; 568 | color: #222; 569 | white-space: nowrap; 570 | -webkit-user-select: none; 571 | -moz-user-select: none; 572 | -ms-user-select: none; 573 | user-select: none; 574 | pointer-events: none; 575 | box-shadow: 0 1px 3px rgba(0,0,0,0.4); 576 | } 577 | .leaflet-tooltip.leaflet-clickable { 578 | cursor: pointer; 579 | pointer-events: auto; 580 | } 581 | .leaflet-tooltip-top:before, 582 | .leaflet-tooltip-bottom:before, 583 | .leaflet-tooltip-left:before, 584 | .leaflet-tooltip-right:before { 585 | position: absolute; 586 | pointer-events: none; 587 | border: 6px solid transparent; 588 | background: transparent; 589 | content: ""; 590 | } 591 | 592 | /* Directions */ 593 | 594 | .leaflet-tooltip-bottom { 595 | margin-top: 6px; 596 | } 597 | .leaflet-tooltip-top { 598 | margin-top: -6px; 599 | } 600 | .leaflet-tooltip-bottom:before, 601 | .leaflet-tooltip-top:before { 602 | left: 50%; 603 | margin-left: -6px; 604 | } 605 | .leaflet-tooltip-top:before { 606 | bottom: 0; 607 | margin-bottom: -12px; 608 | border-top-color: #fff; 609 | } 610 | .leaflet-tooltip-bottom:before { 611 | top: 0; 612 | margin-top: -12px; 613 | margin-left: -6px; 614 | border-bottom-color: #fff; 615 | } 616 | .leaflet-tooltip-left { 617 | margin-left: -6px; 618 | } 619 | .leaflet-tooltip-right { 620 | margin-left: 6px; 621 | } 622 | .leaflet-tooltip-left:before, 623 | .leaflet-tooltip-right:before { 624 | top: 50%; 625 | margin-top: -6px; 626 | } 627 | .leaflet-tooltip-left:before { 628 | right: 0; 629 | margin-right: -12px; 630 | border-left-color: #fff; 631 | } 632 | .leaflet-tooltip-right:before { 633 | left: 0; 634 | margin-left: -12px; 635 | border-right-color: #fff; 636 | } 637 | -------------------------------------------------------------------------------- /css/predictor.css: -------------------------------------------------------------------------------- 1 | /* 2 | * CUSF Landing Prediction Version 2 3 | * http://www.cuspaceflight.co.uk 4 | * 5 | * Jon Sowman 2010 6 | * jon@hexoc.com 7 | * http://www.hexoc.com 8 | * 9 | * http://github.com/jonsowman/cusf-standalone-predictor 10 | * 11 | */ 12 | 13 | /* Basic font-size and family. */ 14 | html { 15 | font-family: sans-serif; 16 | font-size: 12px; 17 | } 18 | 19 | body { 20 | margin: 0; padding: 0; 21 | background-color: #000000; 22 | } 23 | 24 | a { text-decoration: underline; color: #333; cursor: pointer; } 25 | 26 | /* The whoppping map in the centre */ 27 | html, body, #map_canvas { 28 | height: 100%; 29 | width: 100vw; 30 | z-index: 1; 31 | } 32 | 33 | .box{ z-index: 1000 !important ;} 34 | 35 | #status_message{ 36 | position: absolute; 37 | left: 50%; 38 | top: 50%; 39 | width: 400px; 40 | height: 60px; 41 | margin-left: -200px; 42 | margin-top: -50px; 43 | padding: 1em; 44 | text-align: center; 45 | display: none; 46 | } 47 | 48 | #error_window { 49 | position: absolute; 50 | left: 50%; 51 | top: 50%; 52 | width: 400px; 53 | margin-left: -200px; 54 | margin-top: -50px; 55 | padding: 1em; 56 | text-align: center; 57 | display: none; 58 | } 59 | 60 | #debuginfo { 61 | white-space: pre; 62 | } 63 | 64 | #burst-calc-wrapper { 65 | position: absolute; 66 | left: 50%; 67 | top: 50%; 68 | width: 400px; 69 | margin-left: -200px; 70 | margin-top: -200px; 71 | padding: 1em; 72 | text-align: center; 73 | display: none; 74 | } 75 | 76 | #notam-settings-wrapper { 77 | position: absolute; 78 | left: 50%; 79 | top: 50%; 80 | width: 400px; 81 | margin-left: -200px; 82 | margin-top: -200px; 83 | padding: 1em; 84 | text-align: center; 85 | display: none; 86 | } 87 | 88 | /* 89 | #burst-calc { 90 | display: none; 91 | padding: 5px; 92 | text-align: center; 93 | } 94 | */ 95 | 96 | #burst-calc-constants { 97 | display: none; 98 | } 99 | 100 | #location_save { 101 | position: absolute; 102 | left: 50%; 103 | top: 50%; 104 | width: 300px; 105 | margin-left: -150px; 106 | margin-top: -120px; 107 | padding: 1em; 108 | text-align: center; 109 | display: none; 110 | } 111 | 112 | #location_save_local { 113 | position: absolute; 114 | left: 50%; 115 | top: 50%; 116 | width: 300px; 117 | margin-left: -150px; 118 | margin-top: -120px; 119 | padding: 1em; 120 | text-align: center; 121 | display: none; 122 | } 123 | 124 | .box { 125 | position: absolute; 126 | background-color: white; 127 | border: 1px solid #0070a3; 128 | padding: 0.5em; 129 | } 130 | 131 | .box { 132 | background-attachment:initial; 133 | background-clip:initial; 134 | background-color:rgb(255, 255, 255); 135 | background-color:rgba(255, 255, 255, 0.746094); 136 | background-image:initial; 137 | background-origin:initial; 138 | background-position:initial initial; 139 | background-repeat:initial initial; 140 | } 141 | 142 | .box * { 143 | font-size: 12px; 144 | } 145 | 146 | .box table { 147 | margin: 0.25em auto; 148 | white-space: nowrap; 149 | } 150 | 151 | .box h1 { 152 | text-align: center; 153 | margin: 0em 0em 0.5em 0em; 154 | } 155 | 156 | .box p { 157 | margin: 0 auto; 158 | margin-bottom: 0.25em; 159 | width: 25em; 160 | } 161 | 162 | #trail_table { 163 | right: 0; bottom: 0; 164 | border-right: none; 165 | border-bottom: none; 166 | display: none; 167 | } 168 | 169 | #scenario_template { 170 | width: 400px; 171 | left: 0; bottom: 0; 172 | border-left: none; 173 | border-bottom: none; 174 | display: none; 175 | } 176 | 177 | #scenario_template_scroller { 178 | max-height: 400px; 179 | overflow: scroll; 180 | } 181 | 182 | #input_form { 183 | overflow: hidden; 184 | width: 400px; 185 | padding: 5px 5px 0px 5px; 186 | bottom: 0; right: 0; 187 | max-height: 500px; 188 | } 189 | 190 | #launch-card { 191 | width: 100%; 192 | padding: 5px; 193 | } 194 | 195 | #launch-card tr { 196 | width: 50%; 197 | } 198 | 199 | #scenario_info { 200 | position: absolute; 201 | top: 25px; 202 | right: 0px; 203 | width: 400px; 204 | text-align:center; 205 | padding: 5px; 206 | line-height: 130%; 207 | } 208 | 209 | /* about window is a jqueryui dialog */ 210 | #about_window { 211 | display: none; 212 | } 213 | 214 | /* the vehicle_button buttons from spacenear */ 215 | .control_buttons { 216 | border: solid #aed0ea 1px; 217 | background-color: #deedf7; 218 | padding: 3px; 219 | margin-top: 1em; 220 | color: #888; 221 | -webkit-user-select:none; 222 | -moz-user-select:none; 223 | cursor: default; 224 | line-height: 220%; 225 | font-size: 10px; 226 | } 227 | 228 | .control_button { 229 | font-weight: bold; 230 | color: #5c9dc2; 231 | cursor: pointer; 232 | text-decoration: none; 233 | } 234 | 235 | a.control_button:hover { 236 | color: #0070a3; 237 | } 238 | 239 | img.handle { 240 | position: relative; 241 | float:left; 242 | top:0px; 243 | left:0px; 244 | z-index:100; 245 | } 246 | 247 | td.right-td { 248 | text-align: right; 249 | } 250 | 251 | td.spacer { 252 | width: 1em; 253 | } 254 | 255 | table#trails { 256 | border-collapse: collapse; 257 | } 258 | 259 | table#trails td, table#trails th { 260 | border: 1px solid #6666ff; 261 | padding: 0.1em 0.5em; 262 | text-align: center; 263 | } 264 | 265 | table#trails th { 266 | background-color: #6666ff; 267 | color: white; 268 | } 269 | 270 | 271 | .tipsy { padding: 5px; font-size: 10px; opacity: 0.8; filter: alpha(opacity=80); background-repeat: no-repeat; background-image: url(../images/tipsy.gif); } 272 | .tipsy-inner { padding: 5px 8px 4px 8px; background-color: black; color: white; max-width: 200px; text-align: center; } 273 | .tipsy-inner { -moz-border-radius:3px; -webkit-border-radius:3px; } 274 | .tipsy-north { background-position: top center; } 275 | .tipsy-south { background-position: bottom center; } 276 | .tipsy-east { background-position: right center; } 277 | .tipsy-west { background-position: left center; } 278 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/favicon.ico -------------------------------------------------------------------------------- /images/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/arrow.png -------------------------------------------------------------------------------- /images/balloon-sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/balloon-sm.png -------------------------------------------------------------------------------- /images/balloon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/balloon.png -------------------------------------------------------------------------------- /images/csv.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/csv.gif -------------------------------------------------------------------------------- /images/drag_handle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/drag_handle.png -------------------------------------------------------------------------------- /images/kml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/kml.png -------------------------------------------------------------------------------- /images/marker-sm-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/marker-sm-black.png -------------------------------------------------------------------------------- /images/marker-sm-red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/marker-sm-red.png -------------------------------------------------------------------------------- /images/pop-marker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/pop-marker.png -------------------------------------------------------------------------------- /images/target-1-sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-1-sm.png -------------------------------------------------------------------------------- /images/target-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-1.png -------------------------------------------------------------------------------- /images/target-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-10.png -------------------------------------------------------------------------------- /images/target-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-11.png -------------------------------------------------------------------------------- /images/target-12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-12.png -------------------------------------------------------------------------------- /images/target-13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-13.png -------------------------------------------------------------------------------- /images/target-14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-14.png -------------------------------------------------------------------------------- /images/target-15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-15.png -------------------------------------------------------------------------------- /images/target-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-16.png -------------------------------------------------------------------------------- /images/target-17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-17.png -------------------------------------------------------------------------------- /images/target-18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-18.png -------------------------------------------------------------------------------- /images/target-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-2.png -------------------------------------------------------------------------------- /images/target-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-3.png -------------------------------------------------------------------------------- /images/target-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-4.png -------------------------------------------------------------------------------- /images/target-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-5.png -------------------------------------------------------------------------------- /images/target-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-6.png -------------------------------------------------------------------------------- /images/target-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-7.png -------------------------------------------------------------------------------- /images/target-8-sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-8-sm.png -------------------------------------------------------------------------------- /images/target-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-8.png -------------------------------------------------------------------------------- /images/target-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-9.png -------------------------------------------------------------------------------- /images/target-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-blue.png -------------------------------------------------------------------------------- /images/target-red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-red.png -------------------------------------------------------------------------------- /images/target-yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/target-yellow.png -------------------------------------------------------------------------------- /images/tipsy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projecthorus/leaflet_predictor/640f60d4c7b2484fc6b18386fbb7763ecad5dddd/images/tipsy.gif -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CUSF / SondeHub Predictor 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 | 35 | 36 |
37 |
38 |

Debug Window

39 | No Messages 40 |
41 |
42 | 43 | 44 |
45 |
46 | Toggle Debug 47 |
48 | 49 | 50 |
51 | Nothing here! 52 |

53 | Close 54 |
55 | 56 | 57 |
58 | 59 |

Scenario Information

60 | Current mouse position: 61 | Lat: ? 62 | Lon: ? 63 |
64 | 71 | 75 | 82 |
83 | 84 | Show Debug | 85 | Hide Launch Card | 86 | About 87 | 88 |
89 | Non-Commercial Use Only. Please read the 'About' page. 90 |
91 | The Tawhiri engine is currently experiencing some performance issues. Please be patient! 92 |
93 | 94 | 95 |
96 | 97 |

Save Launch Location


98 |
99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 |
Latitude:
Longitude:
Altitude:
Site Name:
112 |

113 | Close this window 114 |
115 | 116 | 117 |
118 | 119 | Saved Locations
120 | ? 121 |
122 | Close this window 123 |
124 | 125 | 126 |
127 |

Cambridge University Spaceflight Landing Predictor - Leaflet Version (github)

128 |

A tool to predict the flight path and landing location of latex sounding balloons.

129 |

Written by Jon Sowman, Adam Greig and Daniel Richman for CUSF. 130 | Credit also to Rich Wareham for work on the predictor. Some parts of code taken from old landing prediction software, credit to Rob Anderson, Fergus Noble and Ed Moore.

131 |

Work to switch to Leaflet mapping and to use the Tawhiri API by Mark Jessop, for the SondeHub project. 132 | The Sondehub instance of the Tawhiri API is available for use in non-commercial applications. 133 |

134 |

This predictor uses data from the NOAA GFS models.

135 |

No guarantee is given for the accuracy, precision or reliability of the data produced by this software, and you use it entirely at your own risk. For more information, see #highaltitude on libera.chat

136 |

This predictor is intended for non-commercial use only. If you are using this predictor in a commercial setting, please read this page.

137 |

138 | Copyright 2013 Cambridge University Space Flight 139 |

140 |

Burst Calculator

141 |

Burst Calculator Web Page

142 |

Usage

143 |

144 | This calculator is designed to help you find how much gas to put into a high altitude balloon 145 | to achieve a desired burst altitude or ascent rate. You have to know the payload mass (including 146 | parachute) and balloon mass. 147 |

148 |

149 | Usage is very straightforward: enter the payload mass into the first box, select the balloon 150 | mass from the second box, and type in either a desired burst altitude in meters or ascent rate 151 | in meters per second in the relevent box. Pressing enter or clicking away from the box you are 152 | typing into will run the calculations, displaying the results in the box at the bottom. 153 |

154 |

155 | The 'Constants' box can be used to adjust constants used by the calculator. These include 156 | selecting a type of gas (or entering a custom gas density), adjusting modelling parameters 157 | or entering a custom burst diameter or drag coefficient for your balloon. Click the tick box 158 | next to the burst diameter or drag coefficient boxes to use a custom value, otherwise the 159 | appropriate value for your selected balloon will be used. 160 |

161 |

About

162 |

163 | Written by Adam Greig for CUSF in March 2010. Maths derived from `burst1a` spreadsheet by 164 | Steve Randall. Balloon information from Kaymont Totex sounding balloon data. 165 |

166 |

167 | No guarantee is given for the accuracy of any data included or produced by this program, use 168 | at your own risk. 169 |

170 |

171 | Copyright 2010 Cambridge University Space Flight 172 |

173 | 174 |
175 | 176 | 177 |
178 | 179 |
180 | Burst Calculator 181 |
182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 194 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 245 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 274 | 275 | 276 | 278 | 279 | 280 |
Payload Mass (g)ANDBalloon Mass (g)
191 | 193 | 195 | 226 |
  
THEN
Target Burst Altitude (m)ORTarget Ascent Rate (m/s)
243 | 244 | 246 | 247 | 248 |
  
Burst Altitude:33000 mAscent Rate:2.33 m/s
Time to Burst:238 minNeck Lift:1733 g
Launch Volume:2.66 273 | m32660 L93.9 277 | ft3
281 |
282 | 284 | 286 | 288 |
289 | 290 | 291 |
292 |
Constants

293 |
294 | For advanced use only! You can probably leave these alone. 295 |

296 |
297 |
304 |
305 |
306 |
307 | 308 |
309 |
310 |
311 |
312 |
313 |
314 | 315 | 316 |
317 |
318 | 319 |
320 |
321 | 323 |
324 |
325 | 326 | 327 |
328 | 329 |
330 | Advanced NOTAM & Airspace Settings 331 |

332 | NB This is not yet functional !!! 333 | 334 | 335 |
336 |
NOTAM details
Show NOTAMs
Airspace Details
Show Default airspace
Show class A airspace
Show class D airspace
Show class E airspace
Show class G airspace
Show prohibited airspace
Show restricted airspace
Show MATZs
Show danger areas
Show offshore/NOTAMed danger areas
Show hazards (HIRTA/AIAA etc)
337 | 338 | 339 | 340 | 342 |

343 |
344 | 345 | 346 |
347 | 348 |
349 | 350 | 351 | 357 | 361 | 362 | 363 | 364 | 370 | 371 | 372 | 377 | 384 | 385 | 386 | 387 | 391 | 392 | 393 | 394 | 398 | 417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 434 | 435 | 436 | 441 | 442 | 443 | 446 | 447 | 448 | 456 | 457 | 458 | 466 | 467 | 468 | 469 | 471 | 472 |
Launch Site: 352 | 353 | Custom 355 | 356 | 358 | 360 |
Latitude/Longitude: 365 |  /  367 | 369 |
373 | 375 | Set With Map 376 | 378 | 379 | 381 | Save Location 382 | 383 |
Launch altitude (m): 388 | 390 |
Launch Time (UTC): 395 | : 396 | 397 |
Launch Date: 399 | 400 | 415 | 416 |
419 | Ascent Rate (m/s): 420 |
Burst/Float Altitude (m):
Flight Profile:
437 | 439 | Use Burst Calculator 440 |
444 | Descent Rate (m/s): 445 |
Prediction Type (info):
470 |
473 |
474 | 475 |
476 | 477 | -------------------------------------------------------------------------------- /js/Leaflet.Control.Custom.js: -------------------------------------------------------------------------------- 1 | (function (window, document, undefined) { 2 | L.Control.Custom = L.Control.extend({ 3 | version: '1.0.1', 4 | options: { 5 | position: 'topright', 6 | id: '', 7 | title: '', 8 | classes: '', 9 | content: '', 10 | style: {}, 11 | datas: {}, 12 | events: {}, 13 | }, 14 | container: null, 15 | onAdd: function (map) { 16 | this.container = L.DomUtil.create('div'); 17 | this.container.id = this.options.id; 18 | this.container.title = this.options.title; 19 | this.container.className = this.options.classes; 20 | this.container.innerHTML = this.options.content; 21 | 22 | for (var option in this.options.style) 23 | { 24 | this.container.style[option] = this.options.style[option]; 25 | } 26 | 27 | for (var data in this.options.datas) 28 | { 29 | this.container.dataset[data] = this.options.datas[data]; 30 | } 31 | 32 | 33 | /* Prevent click events propagation to map */ 34 | L.DomEvent.disableClickPropagation(this.container); 35 | 36 | /* Prevent right click event propagation to map */ 37 | L.DomEvent.on(this.container, 'contextmenu', function (ev) 38 | { 39 | L.DomEvent.stopPropagation(ev); 40 | }); 41 | 42 | /* Prevent scroll events propagation to map when cursor on the div */ 43 | L.DomEvent.disableScrollPropagation(this.container); 44 | 45 | for (var event in this.options.events) 46 | { 47 | L.DomEvent.on(this.container, event, this.options.events[event], this.container); 48 | } 49 | 50 | return this.container; 51 | }, 52 | 53 | onRemove: function (map) { 54 | for (var event in this.options.events) 55 | { 56 | L.DomEvent.off(this.container, event, this.options.events[event], this.container); 57 | } 58 | }, 59 | }); 60 | 61 | L.control.custom = function (options) { 62 | return new L.Control.Custom(options); 63 | }; 64 | 65 | }(window, document)); -------------------------------------------------------------------------------- /js/calc/calc.js: -------------------------------------------------------------------------------- 1 | function get_value(id) { 2 | return parseFloat(document.getElementById(id).value); 3 | } 4 | 5 | function clear_errors() { 6 | var ids = ['mp', 'tar', 'tba', 'rho_g', 'rho_a', 'adm', 'bd', 'cd', 7 | 'bd_c', 'cd_c']; 8 | 9 | for(var i in ids) { 10 | document.getElementById(ids[i]).style.backgroundColor = ''; 11 | } 12 | 13 | var ids = ['mp_w', 'mb_w', 'tar_w', 'tba_w']; 14 | for(i in ids) { 15 | document.getElementById(ids[i]).innerHTML = ' '; 16 | } 17 | } 18 | 19 | function show_error(id) { 20 | document.getElementById(id).style.backgroundColor = '#f99'; 21 | } 22 | 23 | function set_error(id, error) { 24 | show_error(id); 25 | document.getElementById(id+"_w").innerHTML = error; 26 | } 27 | 28 | function sanity_check_inputs(mb, mp, mp_set, tar, tba, tar_set, tba_set) { 29 | if(tar_set && tba_set) { 30 | set_error('tar', "Can't specify both!"); 31 | set_error('tba', "Can't specify both!"); 32 | return 1; 33 | } else if(!tar_set && !tba_set) { 34 | set_error('tar', "Must specify at least one!"); 35 | set_error('tba', "Must specify at least one!"); 36 | return 1; 37 | } 38 | 39 | if(tar_set && tar < 0) { 40 | set_error('tar', "Can't be negative!"); 41 | return 1; 42 | } else if(tar_set && tar > 10) { 43 | set_error('tar', "Too large! (> 10m/s)"); 44 | return 1; 45 | } 46 | 47 | if(tba_set && tba < 10000) { 48 | set_error('tba', "Too low! (< 10km)"); 49 | return 1; 50 | } else if(tba_set && tba > 40000) { 51 | set_error('tba', "Too high! (> 40km)"); 52 | return 1; 53 | } 54 | 55 | if(!mp_set) { 56 | set_error('mp', "Mass required!"); 57 | return 1; 58 | } else if(mp < 20) { 59 | set_error('mp', "Too small! (< 20g)"); 60 | return 1; 61 | } else if(mp > 20000) { 62 | set_error('mp', "Too large! (> 20kg)"); 63 | return 1; 64 | } 65 | 66 | return 0; 67 | 68 | } 69 | 70 | function sanity_check_constants(rho_g, rho_a, adm, ga, bd, cd) { 71 | if(!rho_a || rho_a < 0) { 72 | show_error('rho_a'); 73 | return 1; 74 | } 75 | if(!rho_g || rho_g < 0 || rho_g > rho_a) { 76 | show_error('rho_g'); 77 | return 1; 78 | } 79 | if(!adm || adm < 0) { 80 | show_error('adm'); 81 | return 1; 82 | } 83 | if(!ga || ga < 0) { 84 | show_error('ga'); 85 | return 1; 86 | } 87 | if(!cd || cd < 0 || cd > 1) { 88 | show_error('cd'); 89 | return 1; 90 | } 91 | if(!bd || bd < 0) { 92 | show_error('bd'); 93 | return 1; 94 | } 95 | 96 | return 0; 97 | } 98 | 99 | function find_rho_g() { 100 | var gas = document.getElementById('gas').value; 101 | var rho_g; 102 | 103 | switch(gas) { 104 | case 'he': 105 | rho_g = 0.1786; 106 | document.getElementById('rho_g').value = rho_g; 107 | document.getElementById('rho_g').disabled = "disabled"; 108 | break; 109 | case 'h': 110 | rho_g = 0.0899; 111 | document.getElementById('rho_g').value = rho_g; 112 | document.getElementById('rho_g').disabled = "disabled"; 113 | break; 114 | case 'ch4': 115 | rho_g = 0.6672; 116 | document.getElementById('rho_g').value = rho_g; 117 | document.getElementById('rho_g').disabled = "disabled"; 118 | break; 119 | default: 120 | document.getElementById('rho_g').disabled = ""; 121 | rho_g = get_value('rho_g'); 122 | break; 123 | } 124 | 125 | return rho_g; 126 | } 127 | 128 | function find_bd(mb) { 129 | var bds = new Array(); 130 | 131 | // From Kaymont Totex Sounding Balloon Data 132 | bds["k50"] = 0.88; 133 | bds["k100"] = 1.96; 134 | bds["k150"] = 2.52; 135 | bds["k200"] = 3.00; 136 | bds["k300"] = 3.78; 137 | bds["k350"] = 4.12; 138 | //bds["k450"] = 4.72; // Discontinued? 139 | //bds["k500"] = 4.99; // Discontinued? 140 | bds["k600"] = 6.02; 141 | //bds["k700"] = 6.53; // Discontinued? 142 | bds["k800"] = 7.00; 143 | bds["k1000"] = 7.86; 144 | bds["k1200"] = 8.63; 145 | bds["k1500"] = 9.44; 146 | bds["k1600"] = 9.71; 147 | bds["k1800"] = 9.98; 148 | bds["k2000"] = 10.54; 149 | bds["k3000"] = 13.00; 150 | bds["k4000"] = 15.06; 151 | // Updated 2024-11 from https://www.hwoyee.com/weather-balloon-meteorological-balloon-for-weather-sounding-wind-or-cloud-detection-near-space-researchesgiant-round-balloons-huge-balloons-product/ 152 | bds["h100"] = 2.00; 153 | bds["h200"] = 2.97; 154 | bds["h300"] = 4.30; 155 | bds["h350"] = 4.80; 156 | bds["h500"] = 5.80; 157 | bds["h600"] = 6.50; 158 | bds["h750"] = 6.90; 159 | bds["h800"] = 7.00; 160 | bds["h1000"] = 8.00; 161 | bds["h1200"] = 9.10; 162 | bds["h1600"] = 10.00; 163 | // These two are fudged a little 164 | bds["h2000"] = 11.00; 165 | bds["h3000"] = 12.00; 166 | // PAWAN data from 167 | // https://sites.google.com/site/balloonnewswebstore/1200g-balloon-data 168 | bds["p1200"] = 8.0; 169 | 170 | 171 | var bd_c = document.getElementById('bd_c').checked; 172 | var bd; 173 | 174 | if(bd_c) { 175 | bd = get_value('bd'); 176 | document.getElementById('bd').disabled = ""; 177 | } else { 178 | bd = bds[mb]; 179 | document.getElementById('bd').disabled = "disabled"; 180 | document.getElementById('bd').value = bd; 181 | } 182 | 183 | return bd; 184 | } 185 | 186 | function find_cd(mb) { 187 | var cds = new Array(); 188 | 189 | // From Kaymont Totex Sounding Balloon Data 190 | cds["k50"] = 0.25; 191 | cds["k100"] = 0.25; 192 | cds["k150"] = 0.25; 193 | cds["k200"] = 0.25; 194 | cds["k300"] = 0.25; 195 | cds["k350"] = 0.25; 196 | cds["k450"] = 0.25; 197 | cds["k500"] = 0.25; 198 | cds["k600"] = 0.30; 199 | cds["k700"] = 0.30; 200 | cds["k800"] = 0.30; 201 | cds["k1000"] = 0.30; 202 | cds["k1200"] = 0.25; 203 | cds["k1500"] = 0.25; 204 | cds["k1600"] = 0.25; 205 | cds["k1800"] = 0.25; 206 | cds["k2000"] = 0.25; 207 | cds["k3000"] = 0.25; 208 | cds["k4000"] = 0.25; 209 | // Hwoyee data just guesswork 210 | cds["h200"] = 0.25; 211 | cds["h300"] = 0.25; 212 | cds["h350"] = 0.25; 213 | cds["h400"] = 0.25; 214 | cds["h500"] = 0.25; 215 | cds["h600"] = 0.30; 216 | cds["h750"] = 0.30; 217 | cds["h800"] = 0.30; 218 | cds["h950"] = 0.30; 219 | cds["h1000"] = 0.30; 220 | cds["h1200"] = 0.25; 221 | cds["h1500"] = 0.25; 222 | cds["h1600"] = 0.25; 223 | cds["h2000"] = 0.25; 224 | cds["h3000"] = 0.25; 225 | // PAWAN data also guesswork 226 | cds["p1200"] = 0.25; 227 | 228 | var cd_c = document.getElementById('cd_c').checked; 229 | var cd; 230 | 231 | if(cd_c) { 232 | cd = get_value('cd'); 233 | document.getElementById('cd').disabled = ""; 234 | } else { 235 | cd = cds[mb]; 236 | document.getElementById('cd').disabled = "disabled"; 237 | document.getElementById('cd').value = cd; 238 | } 239 | 240 | return cd; 241 | } 242 | 243 | function calc_update() { 244 | // Reset error status 245 | clear_errors(); 246 | 247 | // Get input values and check them 248 | var mb = document.getElementById('mb').value; 249 | var mp = get_value('mp'); 250 | var tar = get_value('tar'); 251 | var tba = get_value('tba'); 252 | var mp_set = 0; 253 | var tar_set = 0; 254 | var tba_set = 0; 255 | 256 | if(document.getElementById('mp').value) 257 | mp_set = 1; 258 | if(document.getElementById('tar').value) 259 | tar_set = 1; 260 | if(document.getElementById('tba').value) 261 | tba_set = 1; 262 | 263 | if(sanity_check_inputs(mb, mp, mp_set, tar, tba, tar_set, tba_set)) 264 | return; 265 | 266 | // Get constants and check them 267 | var rho_g = find_rho_g(); 268 | var rho_a = get_value('rho_a'); 269 | var adm = get_value('adm'); 270 | var ga = get_value('ga'); 271 | var bd = find_bd(mb); 272 | var cd = find_cd(mb); 273 | 274 | if(sanity_check_constants(rho_g, rho_a, adm, ga, bd, cd)) 275 | return; 276 | 277 | // Do some maths 278 | mb = parseFloat(mb.substr(1)) / 1000.0; 279 | mp = mp / 1000.0; 280 | 281 | var ascent_rate = 0; 282 | var burst_altitude = 0; 283 | var time_to_burst = 0; 284 | var neck_lift = 0; 285 | var launch_radius = 0; 286 | var launch_volume = 0; 287 | 288 | var burst_volume = (4.0/3.0) * Math.PI * Math.pow(bd / 2.0, 3); 289 | 290 | if(tba_set) { 291 | launch_volume = burst_volume * Math.exp((-tba) / adm); 292 | launch_radius = Math.pow((3*launch_volume)/(4*Math.PI), (1/3)); 293 | } else if(tar_set) { 294 | var a = ga * (rho_a - rho_g) * (4.0 / 3.0) * Math.PI; 295 | var b = -0.5 * Math.pow(tar, 2) * cd * rho_a * Math.PI; 296 | var c = 0; 297 | var d = - (mp + mb) * ga; 298 | 299 | var f = (((3*c)/a) - (Math.pow(b, 2) / Math.pow(a,2)) / 3.0); 300 | var g = ( 301 | ((2*Math.pow(b,3))/Math.pow(a,3)) - 302 | ((9*b*c)/(Math.pow(a,2))) + ((27*d)/a) / 27.0 303 | ); 304 | var h = (Math.pow(g,2) / 4.0) + (Math.pow(f,3) / 27.0); 305 | 306 | if(h>0) { 307 | // One real root. This is what should happen. 308 | var R = (-0.5 * g) + Math.sqrt(h); 309 | var S = Math.pow(R, 1.0/3.0); 310 | var T = (-0.5 * g) - Math.sqrt(h); 311 | var U = Math.pow(T, 1.0/3.0); 312 | launch_radius = (S+U) - (b/(3*a)); 313 | } else if(f==0 && g==0 && h==0) { 314 | // Three real and equal roots 315 | // Will this ever even happen? 316 | launch_radius = -1 * Math.pow(d/a, 1.0/3.0); 317 | } else if(h <= 0) { 318 | // Three real and different roots 319 | // What the hell do we do?! 320 | // It needs trig! fffff 321 | var i = Math.sqrt((Math.pow(g,2)/4.0) - h); 322 | var j = Math.pow(i, 1.0/3.0); 323 | var k = Math.acos(-g / (2*i)); 324 | var L = -1 * j; 325 | var M = Math.cos(K/3.0); 326 | var N = Math.sqrt(3) * Math.sin(K/3.0); 327 | var P = (b/(3*a)) * -1; 328 | var r1 = 2*j*Math.cos(k/3.0) - (b/(3*a)); 329 | var r2 = L * (M + N) + P; 330 | var r3 = L * (M - N) + P; 331 | 332 | alert("Three possible solutions found: " 333 | + r1 + ", " + r2 + ", " + r3); 334 | 335 | if(r1 > 0) { 336 | launch_radius = r1; 337 | } else if(r2 > 0) { 338 | launch_radius = r2; 339 | } else if(r3 > 0) { 340 | launch_radius = r3; 341 | } 342 | } else { 343 | // No real roots 344 | } 345 | } 346 | 347 | var launch_area = Math.PI * Math.pow(launch_radius, 2); 348 | var launch_volume = (4.0/3.0) * Math.PI * Math.pow(launch_radius, 3); 349 | var density_difference = rho_a - rho_g; 350 | var gross_lift = launch_volume * density_difference; 351 | neck_lift = (gross_lift - mb) * 1000; 352 | var total_mass = mp + mb; 353 | var free_lift = (gross_lift - total_mass) * ga; 354 | ascent_rate = Math.sqrt(free_lift / (0.5 * cd * launch_area * rho_a)); 355 | var volume_ratio = launch_volume / burst_volume; 356 | burst_altitude = -(adm) * Math.log(volume_ratio); 357 | time_to_burst = (burst_altitude / ascent_rate) / 60.0; 358 | 359 | if(isNaN(ascent_rate)) { 360 | set_error('tba', "Altitude unreachable
for this configuration."); 361 | return; 362 | } 363 | 364 | ascent_rate = ascent_rate.toFixed(2); 365 | burst_altitude = burst_altitude.toFixed(); 366 | time_to_burst = time_to_burst.toFixed(); 367 | neck_lift = neck_lift.toFixed(); 368 | launch_litres = (launch_volume * 1000).toFixed(); 369 | launch_cf = (launch_volume * 35.31).toFixed(1); 370 | launch_volume = launch_volume.toFixed(2); 371 | 372 | document.getElementById('ar').innerHTML = ascent_rate; 373 | document.getElementById('ba').innerHTML = burst_altitude; 374 | document.getElementById('ttb').innerHTML = time_to_burst; 375 | document.getElementById('nl').innerHTML = neck_lift; 376 | document.getElementById('lv_m3').innerHTML = launch_volume; 377 | document.getElementById('lv_l').innerHTML = launch_litres; 378 | document.getElementById('lv_cf').innerHTML = launch_cf; 379 | } 380 | 381 | function calc_init() { 382 | 383 | var ids = ['mb', 'mp', 'tar', 'tba', 'gas', 'rho_g', 'rho_a', 'adm', 'bd', 'cd', 'bd_c', 'cd_c']; 384 | for(var i in ids) { 385 | document.getElementById(ids[i]).onchange = calc_update; 386 | } 387 | calc_update(); 388 | } 389 | -------------------------------------------------------------------------------- /js/colour-map.js: -------------------------------------------------------------------------------- 1 | const cm_data = {"turbo": {"interpolate": true, "colors": [[0.19, 0.0718, 0.2322], [0.1948, 0.0834, 0.2615], [0.1996, 0.095, 0.2902], [0.2042, 0.1065, 0.3184], [0.2086, 0.118, 0.3461], [0.2129, 0.1295, 0.3731], [0.2171, 0.1409, 0.3996], [0.2211, 0.1522, 0.4256], [0.225, 0.1635, 0.451], [0.2288, 0.1748, 0.4758], [0.2324, 0.186, 0.5], [0.2358, 0.1972, 0.5237], [0.2392, 0.2083, 0.5469], [0.2423, 0.2194, 0.5694], [0.2454, 0.2304, 0.5914], [0.2483, 0.2414, 0.6129], [0.2511, 0.2524, 0.6337], [0.2537, 0.2633, 0.6541], [0.2562, 0.2741, 0.6738], [0.2585, 0.2849, 0.693], [0.2607, 0.2957, 0.7116], [0.2628, 0.3064, 0.7297], [0.2647, 0.3171, 0.7472], [0.2665, 0.3277, 0.7641], [0.2682, 0.3382, 0.7805], [0.2697, 0.3488, 0.7963], [0.271, 0.3593, 0.8116], [0.2723, 0.3697, 0.8262], [0.2733, 0.3801, 0.8404], [0.2743, 0.3904, 0.8539], [0.2751, 0.4007, 0.8669], [0.2758, 0.411, 0.8794], [0.2763, 0.4212, 0.8912], [0.2767, 0.4313, 0.9025], [0.2769, 0.4414, 0.9133], [0.277, 0.4515, 0.9235], [0.277, 0.4615, 0.9331], [0.2768, 0.4715, 0.9421], [0.2765, 0.4814, 0.9506], [0.276, 0.4913, 0.9586], [0.2754, 0.5012, 0.9659], [0.2747, 0.5109, 0.9728], [0.2738, 0.5207, 0.979], [0.2727, 0.5304, 0.9846], [0.2711, 0.5402, 0.9893], [0.2688, 0.55, 0.993], [0.2659, 0.5598, 0.9958], [0.2625, 0.5697, 0.9977], [0.2586, 0.5796, 0.9988], [0.2542, 0.5895, 0.999], [0.2495, 0.5994, 0.9984], [0.2443, 0.6094, 0.997], [0.2387, 0.6193, 0.9948], [0.2329, 0.6292, 0.992], [0.2268, 0.6391, 0.9885], [0.2204, 0.649, 0.9844], [0.2138, 0.6589, 0.9796], [0.2071, 0.6687, 0.9742], [0.2002, 0.6784, 0.9683], [0.1933, 0.6881, 0.9619], [0.1862, 0.6978, 0.955], [0.1792, 0.7073, 0.9476], [0.1722, 0.7168, 0.9398], [0.1653, 0.7262, 0.9316], [0.1584, 0.7355, 0.923], [0.1517, 0.7447, 0.9142], [0.1452, 0.7538, 0.905], [0.1389, 0.7628, 0.8955], [0.1328, 0.7716, 0.8858], [0.127, 0.7804, 0.8759], [0.1215, 0.789, 0.8658], [0.1164, 0.7974, 0.8556], [0.1117, 0.8057, 0.8452], [0.1074, 0.8138, 0.8348], [0.1036, 0.8218, 0.8244], [0.1003, 0.8296, 0.8139], [0.0975, 0.8371, 0.8034], [0.0953, 0.8446, 0.793], [0.0938, 0.8518, 0.7826], [0.0929, 0.8588, 0.7724], [0.0927, 0.8655, 0.7623], [0.0932, 0.8721, 0.7524], [0.0945, 0.8784, 0.7426], [0.0966, 0.8845, 0.7332], [0.0996, 0.8904, 0.7239], [0.1034, 0.896, 0.715], [0.1082, 0.9014, 0.706], [0.1137, 0.9067, 0.6965], [0.1201, 0.9119, 0.6866], [0.1273, 0.917, 0.6763], [0.1353, 0.922, 0.6656], [0.1439, 0.9268, 0.6545], [0.1532, 0.9315, 0.6431], [0.1632, 0.9361, 0.6314], [0.1738, 0.9405, 0.6194], [0.1849, 0.9448, 0.6071], [0.1966, 0.949, 0.5947], [0.2088, 0.953, 0.582], [0.2214, 0.9569, 0.5691], [0.2345, 0.9606, 0.5561], [0.248, 0.9642, 0.543], [0.2618, 0.9676, 0.5298], [0.276, 0.9709, 0.5165], [0.2904, 0.974, 0.5032], [0.3051, 0.977, 0.4899], [0.3201, 0.9797, 0.4765], [0.3352, 0.9823, 0.4632], [0.3504, 0.9848, 0.45], [0.3658, 0.987, 0.4369], [0.3813, 0.9891, 0.4239], [0.3968, 0.991, 0.411], [0.4123, 0.9927, 0.3983], [0.4278, 0.9942, 0.3858], [0.4432, 0.9955, 0.3734], [0.4585, 0.9966, 0.3614], [0.4738, 0.9976, 0.3496], [0.4888, 0.9983, 0.3382], [0.5036, 0.9988, 0.327], [0.5182, 0.9991, 0.3162], [0.5326, 0.9992, 0.3058], [0.5466, 0.9991, 0.2958], [0.5603, 0.9987, 0.2862], [0.5736, 0.9982, 0.2771], [0.5865, 0.9974, 0.2685], [0.5989, 0.9964, 0.2604], [0.6109, 0.9951, 0.2528], [0.6223, 0.9937, 0.2458], [0.6332, 0.992, 0.2394], [0.6436, 0.99, 0.2336], [0.6539, 0.9878, 0.2284], [0.6643, 0.9852, 0.2237], [0.6746, 0.9825, 0.2196], [0.6849, 0.9794, 0.216], [0.6952, 0.9761, 0.2129], [0.7055, 0.9726, 0.2103], [0.7158, 0.9688, 0.2082], [0.726, 0.9647, 0.2064], [0.7361, 0.9604, 0.205], [0.7462, 0.9559, 0.2041], [0.7562, 0.9512, 0.2034], [0.7661, 0.9463, 0.2031], [0.7759, 0.9411, 0.2031], [0.7856, 0.9358, 0.2034], [0.7952, 0.9302, 0.2039], [0.8047, 0.9245, 0.2046], [0.8141, 0.9186, 0.2055], [0.8233, 0.9125, 0.2066], [0.8324, 0.9063, 0.2079], [0.8413, 0.8999, 0.2093], [0.8501, 0.8933, 0.2107], [0.8587, 0.8866, 0.2123], [0.8671, 0.8797, 0.2139], [0.8753, 0.8727, 0.2156], [0.8833, 0.8655, 0.2172], [0.8911, 0.8583, 0.2188], [0.8987, 0.8509, 0.2204], [0.906, 0.8434, 0.2219], [0.9132, 0.8358, 0.2233], [0.92, 0.8281, 0.2246], [0.9267, 0.8202, 0.2257], [0.933, 0.8124, 0.2267], [0.9391, 0.8044, 0.2274], [0.9449, 0.7963, 0.228], [0.9504, 0.7882, 0.2283], [0.9556, 0.78, 0.2284], [0.9605, 0.7718, 0.2281], [0.9651, 0.7635, 0.2275], [0.9693, 0.7552, 0.2266], [0.9732, 0.7468, 0.2254], [0.9768, 0.7384, 0.2237], [0.98, 0.73, 0.2216], [0.9829, 0.7214, 0.2192], [0.9855, 0.7125, 0.2165], [0.9878, 0.7033, 0.2136], [0.9899, 0.6938, 0.2104], [0.9916, 0.6841, 0.2071], [0.9931, 0.6741, 0.2035], [0.9944, 0.6639, 0.1997], [0.9954, 0.6534, 0.1958], [0.9961, 0.6428, 0.1916], [0.9965, 0.6319, 0.1874], [0.9968, 0.6209, 0.183], [0.9967, 0.6098, 0.1784], [0.9964, 0.5985, 0.1738], [0.9959, 0.587, 0.169], [0.9952, 0.5755, 0.1641], [0.9942, 0.5639, 0.1592], [0.993, 0.5521, 0.1542], [0.9915, 0.5404, 0.1491], [0.9899, 0.5285, 0.144], [0.988, 0.5167, 0.1388], [0.9859, 0.5048, 0.1337], [0.9836, 0.4929, 0.1285], [0.9811, 0.481, 0.1233], [0.9784, 0.4692, 0.1182], [0.9754, 0.4574, 0.113], [0.9723, 0.4456, 0.108], [0.969, 0.434, 0.1029], [0.9656, 0.4224, 0.098], [0.9619, 0.4109, 0.0931], [0.958, 0.3996, 0.0883], [0.954, 0.3884, 0.0836], [0.9498, 0.3773, 0.079], [0.9454, 0.3664, 0.0746], [0.9408, 0.3557, 0.0703], [0.9361, 0.3451, 0.0662], [0.9312, 0.3348, 0.0622], [0.9262, 0.3247, 0.0584], [0.921, 0.3149, 0.0548], [0.9157, 0.3053, 0.0513], [0.9102, 0.296, 0.0481], [0.9046, 0.287, 0.0452], [0.8989, 0.2782, 0.0424], [0.893, 0.2698, 0.0399], [0.8869, 0.2615, 0.0375], [0.8807, 0.2533, 0.0352], [0.8742, 0.2453, 0.033], [0.8676, 0.2373, 0.0308], [0.8608, 0.2294, 0.0288], [0.8538, 0.2217, 0.0268], [0.8466, 0.2141, 0.0249], [0.8393, 0.2065, 0.023], [0.8317, 0.1991, 0.0213], [0.824, 0.1918, 0.0197], [0.8161, 0.1846, 0.0181], [0.808, 0.1775, 0.0166], [0.7997, 0.1706, 0.0152], [0.7912, 0.1637, 0.0139], [0.7826, 0.1569, 0.0126], [0.7738, 0.1503, 0.0115], [0.7648, 0.1437, 0.0104], [0.7556, 0.1373, 0.0094], [0.7462, 0.131, 0.0085], [0.7366, 0.1248, 0.0077], [0.7269, 0.1187, 0.007], [0.7169, 0.1127, 0.0063], [0.7068, 0.1068, 0.0057], [0.6965, 0.101, 0.0052], [0.686, 0.0954, 0.0048], [0.6754, 0.0898, 0.0045], [0.6645, 0.0844, 0.0042], [0.6534, 0.079, 0.0041], [0.6422, 0.0738, 0.004], [0.6308, 0.0687, 0.004], [0.6192, 0.0637, 0.0041], [0.6075, 0.0588, 0.0043], [0.5955, 0.054, 0.0045], [0.5834, 0.0493, 0.0049], [0.571, 0.0447, 0.0053], [0.5585, 0.0403, 0.0058], [0.5458, 0.0359, 0.0064], [0.533, 0.0317, 0.007], [0.5199, 0.0276, 0.0078], [0.5066, 0.0235, 0.0086], [0.4932, 0.0196, 0.0096], [0.4796, 0.0158, 0.0106]]}, "viridis": {"interpolate": true, "colors": [[0.267, 0.0049, 0.3294], [0.2685, 0.0096, 0.3354], [0.2699, 0.0146, 0.3414], [0.2713, 0.0199, 0.3473], [0.2726, 0.0256, 0.3531], [0.2738, 0.0315, 0.3589], [0.275, 0.0378, 0.3645], [0.276, 0.0442, 0.3702], [0.277, 0.0503, 0.3757], [0.2779, 0.0563, 0.3812], [0.2788, 0.0621, 0.3866], [0.2796, 0.0678, 0.3919], [0.2803, 0.0734, 0.3972], [0.2809, 0.0789, 0.4023], [0.2814, 0.0843, 0.4074], [0.2819, 0.0897, 0.4124], [0.2823, 0.095, 0.4173], [0.2827, 0.1002, 0.4222], [0.2829, 0.1054, 0.4269], [0.2831, 0.1106, 0.4316], [0.2832, 0.1157, 0.4361], [0.2832, 0.1208, 0.4406], [0.2832, 0.1258, 0.445], [0.2831, 0.1309, 0.4492], [0.2829, 0.1359, 0.4534], [0.2826, 0.1409, 0.4575], [0.2823, 0.1459, 0.4615], [0.2819, 0.1509, 0.4654], [0.2814, 0.1558, 0.4692], [0.2809, 0.1608, 0.4729], [0.2803, 0.1657, 0.4765], [0.2796, 0.1706, 0.48], [0.2788, 0.1755, 0.4834], [0.278, 0.1804, 0.4867], [0.2771, 0.1852, 0.4899], [0.2762, 0.1901, 0.493], [0.2752, 0.1949, 0.496], [0.2741, 0.1997, 0.4989], [0.273, 0.2045, 0.5017], [0.2718, 0.2093, 0.5044], [0.2706, 0.2141, 0.5071], [0.2693, 0.2188, 0.5096], [0.268, 0.2235, 0.512], [0.2666, 0.2283, 0.5143], [0.2651, 0.233, 0.5166], [0.2637, 0.2376, 0.5188], [0.2621, 0.2423, 0.5208], [0.2606, 0.2469, 0.5228], [0.259, 0.2515, 0.5247], [0.2573, 0.2561, 0.5266], [0.2556, 0.2607, 0.5283], [0.2539, 0.2653, 0.53], [0.2522, 0.2698, 0.5316], [0.2504, 0.2743, 0.5331], [0.2486, 0.2788, 0.5346], [0.2468, 0.2832, 0.5359], [0.245, 0.2877, 0.5373], [0.2431, 0.2921, 0.5385], [0.2412, 0.2965, 0.5397], [0.2393, 0.3009, 0.5408], [0.2374, 0.3052, 0.5419], [0.2355, 0.3095, 0.5429], [0.2336, 0.3138, 0.5439], [0.2317, 0.3181, 0.5448], [0.2297, 0.3224, 0.5457], [0.2278, 0.3266, 0.5465], [0.2259, 0.3308, 0.5473], [0.2239, 0.335, 0.5481], [0.222, 0.3392, 0.5488], [0.2201, 0.3433, 0.5494], [0.2181, 0.3474, 0.55], [0.2162, 0.3515, 0.5506], [0.2143, 0.3556, 0.5512], [0.2124, 0.3597, 0.5517], [0.2105, 0.3637, 0.5522], [0.2086, 0.3678, 0.5527], [0.2068, 0.3718, 0.5531], [0.2049, 0.3757, 0.5535], [0.2031, 0.3797, 0.5539], [0.2012, 0.3837, 0.5543], [0.1994, 0.3876, 0.5546], [0.1976, 0.3915, 0.555], [0.1959, 0.3954, 0.5553], [0.1941, 0.3993, 0.5556], [0.1924, 0.4032, 0.5558], [0.1906, 0.4071, 0.5561], [0.1889, 0.4109, 0.5563], [0.1872, 0.4147, 0.5565], [0.1856, 0.4186, 0.5568], [0.1839, 0.4224, 0.5569], [0.1823, 0.4262, 0.5571], [0.1806, 0.43, 0.5573], [0.179, 0.4338, 0.5574], [0.1774, 0.4375, 0.5576], [0.1758, 0.4413, 0.5577], [0.1743, 0.445, 0.5578], [0.1727, 0.4488, 0.5579], [0.1712, 0.4525, 0.558], [0.1696, 0.4563, 0.558], [0.1681, 0.46, 0.5581], [0.1666, 0.4637, 0.5581], [0.1651, 0.4674, 0.5581], [0.1636, 0.4711, 0.5581], [0.1621, 0.4748, 0.5581], [0.1607, 0.4785, 0.5581], [0.1592, 0.4822, 0.5581], [0.1577, 0.4859, 0.558], [0.1563, 0.4896, 0.5579], [0.1548, 0.4933, 0.5578], [0.1534, 0.497, 0.5577], [0.1519, 0.5007, 0.5576], [0.1505, 0.5044, 0.5574], [0.149, 0.5081, 0.5572], [0.1476, 0.5117, 0.557], [0.1462, 0.5154, 0.5568], [0.1448, 0.5191, 0.5566], [0.1433, 0.5228, 0.5563], [0.1419, 0.5265, 0.556], [0.1405, 0.5301, 0.5557], [0.1391, 0.5338, 0.5553], [0.1378, 0.5375, 0.5549], [0.1364, 0.5412, 0.5545], [0.1351, 0.5449, 0.554], [0.1337, 0.5485, 0.5535], [0.1324, 0.5522, 0.553], [0.1312, 0.5559, 0.5525], [0.1299, 0.5596, 0.5519], [0.1287, 0.5633, 0.5512], [0.1276, 0.5669, 0.5506], [0.1265, 0.5706, 0.5498], [0.1254, 0.5743, 0.5491], [0.1244, 0.578, 0.5483], [0.1235, 0.5817, 0.5474], [0.1226, 0.5854, 0.5466], [0.1218, 0.5891, 0.5456], [0.1211, 0.5927, 0.5446], [0.1206, 0.5964, 0.5436], [0.1201, 0.6001, 0.5425], [0.1197, 0.6038, 0.5414], [0.1195, 0.6075, 0.5402], [0.1194, 0.6111, 0.539], [0.1195, 0.6148, 0.5377], [0.1197, 0.6185, 0.5363], [0.1201, 0.6222, 0.5349], [0.1206, 0.6258, 0.5335], [0.1214, 0.6295, 0.532], [0.1223, 0.6332, 0.5304], [0.1234, 0.6368, 0.5288], [0.1248, 0.6405, 0.5271], [0.1263, 0.6441, 0.5253], [0.1281, 0.6477, 0.5235], [0.1301, 0.6514, 0.5216], [0.1323, 0.655, 0.5197], [0.1347, 0.6586, 0.5176], [0.1373, 0.6623, 0.5156], [0.1402, 0.6659, 0.5134], [0.1433, 0.6695, 0.5112], [0.1466, 0.673, 0.5089], [0.1501, 0.6766, 0.5066], [0.1539, 0.6802, 0.5042], [0.1579, 0.6838, 0.5017], [0.162, 0.6873, 0.4991], [0.1664, 0.6909, 0.4965], [0.1709, 0.6944, 0.4938], [0.1757, 0.6979, 0.491], [0.1807, 0.7014, 0.4882], [0.1858, 0.7049, 0.4853], [0.1911, 0.7084, 0.4823], [0.1966, 0.7118, 0.4792], [0.2022, 0.7153, 0.4761], [0.208, 0.7187, 0.4729], [0.214, 0.7221, 0.4696], [0.2201, 0.7255, 0.4662], [0.2264, 0.7289, 0.4628], [0.2328, 0.7322, 0.4593], [0.2394, 0.7356, 0.4557], [0.2461, 0.7389, 0.452], [0.2529, 0.7422, 0.4483], [0.2599, 0.7455, 0.4445], [0.2669, 0.7488, 0.4406], [0.2741, 0.752, 0.4366], [0.2815, 0.7552, 0.4326], [0.2889, 0.7584, 0.4284], [0.2965, 0.7616, 0.4242], [0.3041, 0.7647, 0.4199], [0.3119, 0.7678, 0.4156], [0.3198, 0.7709, 0.4112], [0.3278, 0.774, 0.4066], [0.3359, 0.777, 0.402], [0.3441, 0.78, 0.3974], [0.3524, 0.783, 0.3926], [0.3607, 0.786, 0.3878], [0.3692, 0.7889, 0.3829], [0.3778, 0.7918, 0.3779], [0.3864, 0.7946, 0.3729], [0.3952, 0.7975, 0.3678], [0.404, 0.8003, 0.3626], [0.4129, 0.803, 0.3573], [0.4219, 0.8058, 0.3519], [0.431, 0.8085, 0.3465], [0.4401, 0.8111, 0.341], [0.4494, 0.8138, 0.3354], [0.4587, 0.8164, 0.3297], [0.4681, 0.8189, 0.324], [0.4775, 0.8214, 0.3182], [0.487, 0.8239, 0.3123], [0.4966, 0.8264, 0.3064], [0.5063, 0.8288, 0.3004], [0.516, 0.8312, 0.2943], [0.5258, 0.8335, 0.2881], [0.5356, 0.8358, 0.2819], [0.5455, 0.838, 0.2756], [0.5555, 0.8403, 0.2693], [0.5655, 0.8424, 0.2629], [0.5756, 0.8446, 0.2564], [0.5857, 0.8467, 0.2499], [0.5958, 0.8487, 0.2433], [0.606, 0.8507, 0.2367], [0.6163, 0.8527, 0.2301], [0.6266, 0.8546, 0.2234], [0.6369, 0.8565, 0.2166], [0.6473, 0.8584, 0.2099], [0.6576, 0.8602, 0.2031], [0.6681, 0.862, 0.1963], [0.6785, 0.8637, 0.1895], [0.6889, 0.8654, 0.1827], [0.6994, 0.8671, 0.176], [0.7099, 0.8688, 0.1693], [0.7204, 0.8704, 0.1626], [0.7309, 0.8719, 0.156], [0.7414, 0.8734, 0.1496], [0.7519, 0.875, 0.1432], [0.7624, 0.8764, 0.1371], [0.7729, 0.8779, 0.1311], [0.7833, 0.8793, 0.1254], [0.7938, 0.8807, 0.12], [0.8042, 0.882, 0.115], [0.8146, 0.8834, 0.1103], [0.8249, 0.8847, 0.1062], [0.8353, 0.886, 0.1026], [0.8456, 0.8873, 0.0997], [0.8558, 0.8886, 0.0975], [0.866, 0.8899, 0.096], [0.8762, 0.8911, 0.0952], [0.8863, 0.8924, 0.0954], [0.8963, 0.8936, 0.0963], [0.9063, 0.8949, 0.0981], [0.9162, 0.8961, 0.1007], [0.9261, 0.8973, 0.1041], [0.9359, 0.8986, 0.1081], [0.9456, 0.8998, 0.1128], [0.9553, 0.9011, 0.1181], [0.9649, 0.9023, 0.1239], [0.9744, 0.9036, 0.1302], [0.9839, 0.9049, 0.1369], [0.9932, 0.9062, 0.1439]]}, "hsv": {"interpolate": true, "colors": [[1.0, 0.0, 0.0], [1.0, 0.0232, 0.0], [1.0, 0.0463, 0.0], [1.0, 0.0695, 0.0], [1.0, 0.0926, 0.0], [1.0, 0.1158, 0.0], [1.0, 0.139, 0.0], [1.0, 0.1621, 0.0], [1.0, 0.1853, 0.0], [1.0, 0.2085, 0.0], [1.0, 0.2316, 0.0], [1.0, 0.2548, 0.0], [1.0, 0.2779, 0.0], [1.0, 0.3011, 0.0], [1.0, 0.3243, 0.0], [1.0, 0.3474, 0.0], [1.0, 0.3706, 0.0], [1.0, 0.3938, 0.0], [1.0, 0.4169, 0.0], [1.0, 0.4401, 0.0], [1.0, 0.4632, 0.0], [1.0, 0.4864, 0.0], [1.0, 0.5096, 0.0], [1.0, 0.5327, 0.0], [1.0, 0.5559, 0.0], [1.0, 0.579, 0.0], [1.0, 0.6022, 0.0], [1.0, 0.6254, 0.0], [1.0, 0.6485, 0.0], [1.0, 0.6717, 0.0], [1.0, 0.6949, 0.0], [1.0, 0.718, 0.0], [1.0, 0.7412, 0.0], [1.0, 0.7643, 0.0], [1.0, 0.7875, 0.0], [1.0, 0.8107, 0.0], [1.0, 0.8338, 0.0], [1.0, 0.857, 0.0], [1.0, 0.8801, 0.0], [1.0, 0.9033, 0.0], [1.0, 0.9265, 0.0], [0.996, 0.9456, 0.0], [0.9882, 0.961, 0.0], [0.9805, 0.9765, 0.0], [0.9728, 0.9919, 0.0], [0.9577, 1.0, 0.0], [0.9346, 1.0, 0.0], [0.9114, 1.0, 0.0], [0.8882, 1.0, 0.0], [0.8651, 1.0, 0.0], [0.8419, 1.0, 0.0], [0.8187, 1.0, 0.0], [0.7956, 1.0, 0.0], [0.7724, 1.0, 0.0], [0.7493, 1.0, 0.0], [0.7261, 1.0, 0.0], [0.7029, 1.0, 0.0], [0.6798, 1.0, 0.0], [0.6566, 1.0, 0.0], [0.6335, 1.0, 0.0], [0.6103, 1.0, 0.0], [0.5871, 1.0, 0.0], [0.564, 1.0, 0.0], [0.5408, 1.0, 0.0], [0.5176, 1.0, 0.0], [0.4945, 1.0, 0.0], [0.4713, 1.0, 0.0], [0.4482, 1.0, 0.0], [0.425, 1.0, 0.0], [0.4018, 1.0, 0.0], [0.3787, 1.0, 0.0], [0.3555, 1.0, 0.0], [0.3324, 1.0, 0.0], [0.3092, 1.0, 0.0], [0.286, 1.0, 0.0], [0.2629, 1.0, 0.0], [0.2397, 1.0, 0.0], [0.2165, 1.0, 0.0], [0.1934, 1.0, 0.0], [0.1702, 1.0, 0.0], [0.1471, 1.0, 0.0], [0.1239, 1.0, 0.0], [0.1007, 1.0, 0.0], [0.0776, 1.0, 0.0], [0.0544, 1.0, 0.0], [0.0312, 1.0, 0.0], [0.0235, 1.0, 0.0154], [0.0158, 1.0, 0.0309], [0.0081, 1.0, 0.0463], [0.0004, 1.0, 0.0618], [0.0, 1.0, 0.0846], [0.0, 1.0, 0.1077], [0.0, 1.0, 0.1309], [0.0, 1.0, 0.154], [0.0, 1.0, 0.1772], [0.0, 1.0, 0.2004], [0.0, 1.0, 0.2235], [0.0, 1.0, 0.2467], [0.0, 1.0, 0.2699], [0.0, 1.0, 0.293], [0.0, 1.0, 0.3162], [0.0, 1.0, 0.3393], [0.0, 1.0, 0.3625], [0.0, 1.0, 0.3857], [0.0, 1.0, 0.4088], [0.0, 1.0, 0.432], [0.0, 1.0, 0.4551], [0.0, 1.0, 0.4783], [0.0, 1.0, 0.5015], [0.0, 1.0, 0.5246], [0.0, 1.0, 0.5478], [0.0, 1.0, 0.571], [0.0, 1.0, 0.5941], [0.0, 1.0, 0.6173], [0.0, 1.0, 0.6404], [0.0, 1.0, 0.6636], [0.0, 1.0, 0.6868], [0.0, 1.0, 0.7099], [0.0, 1.0, 0.7331], [0.0, 1.0, 0.7562], [0.0, 1.0, 0.7794], [0.0, 1.0, 0.8026], [0.0, 1.0, 0.8257], [0.0, 1.0, 0.8489], [0.0, 1.0, 0.8721], [0.0, 1.0, 0.8952], [0.0, 1.0, 0.9184], [0.0, 1.0, 0.9415], [0.0, 1.0, 0.9647], [0.0, 1.0, 0.9879], [0.0, 0.989, 1.0], [0.0, 0.9658, 1.0], [0.0, 0.9426, 1.0], [0.0, 0.9195, 1.0], [0.0, 0.8963, 1.0], [0.0, 0.8732, 1.0], [0.0, 0.85, 1.0], [0.0, 0.8268, 1.0], [0.0, 0.8037, 1.0], [0.0, 0.7805, 1.0], [0.0, 0.7574, 1.0], [0.0, 0.7342, 1.0], [0.0, 0.711, 1.0], [0.0, 0.6879, 1.0], [0.0, 0.6647, 1.0], [0.0, 0.6415, 1.0], [0.0, 0.6184, 1.0], [0.0, 0.5952, 1.0], [0.0, 0.5721, 1.0], [0.0, 0.5489, 1.0], [0.0, 0.5257, 1.0], [0.0, 0.5026, 1.0], [0.0, 0.4794, 1.0], [0.0, 0.4563, 1.0], [0.0, 0.4331, 1.0], [0.0, 0.4099, 1.0], [0.0, 0.3868, 1.0], [0.0, 0.3636, 1.0], [0.0, 0.3404, 1.0], [0.0, 0.3173, 1.0], [0.0, 0.2941, 1.0], [0.0, 0.271, 1.0], [0.0, 0.2478, 1.0], [0.0, 0.2246, 1.0], [0.0, 0.2015, 1.0], [0.0, 0.1783, 1.0], [0.0, 0.1551, 1.0], [0.0, 0.132, 1.0], [0.0, 0.1088, 1.0], [0.0, 0.0857, 1.0], [0.0, 0.0625, 1.0], [0.0077, 0.0471, 1.0], [0.0154, 0.0316, 1.0], [0.0232, 0.0162, 1.0], [0.0309, 0.0007, 1.0], [0.0533, 0.0, 1.0], [0.0765, 0.0, 1.0], [0.0996, 0.0, 1.0], [0.1228, 0.0, 1.0], [0.146, 0.0, 1.0], [0.1691, 0.0, 1.0], [0.1923, 0.0, 1.0], [0.2154, 0.0, 1.0], [0.2386, 0.0, 1.0], [0.2618, 0.0, 1.0], [0.2849, 0.0, 1.0], [0.3081, 0.0, 1.0], [0.3312, 0.0, 1.0], [0.3544, 0.0, 1.0], [0.3776, 0.0, 1.0], [0.4007, 0.0, 1.0], [0.4239, 0.0, 1.0], [0.4471, 0.0, 1.0], [0.4702, 0.0, 1.0], [0.4934, 0.0, 1.0], [0.5165, 0.0, 1.0], [0.5397, 0.0, 1.0], [0.5629, 0.0, 1.0], [0.586, 0.0, 1.0], [0.6092, 0.0, 1.0], [0.6324, 0.0, 1.0], [0.6555, 0.0, 1.0], [0.6787, 0.0, 1.0], [0.7018, 0.0, 1.0], [0.725, 0.0, 1.0], [0.7482, 0.0, 1.0], [0.7713, 0.0, 1.0], [0.7945, 0.0, 1.0], [0.8176, 0.0, 1.0], [0.8408, 0.0, 1.0], [0.864, 0.0, 1.0], [0.8871, 0.0, 1.0], [0.9103, 0.0, 1.0], [0.9335, 0.0, 1.0], [0.9566, 0.0, 1.0], [0.9724, 0.0, 0.9926], [0.9801, 0.0, 0.9772], [0.9879, 0.0, 0.9618], [0.9956, 0.0, 0.9463], [1.0, 0.0, 0.9276], [1.0, 0.0, 0.9044], [1.0, 0.0, 0.8813], [1.0, 0.0, 0.8581], [1.0, 0.0, 0.8349], [1.0, 0.0, 0.8118], [1.0, 0.0, 0.7886], [1.0, 0.0, 0.7654], [1.0, 0.0, 0.7423], [1.0, 0.0, 0.7191], [1.0, 0.0, 0.696], [1.0, 0.0, 0.6728], [1.0, 0.0, 0.6496], [1.0, 0.0, 0.6265], [1.0, 0.0, 0.6033], [1.0, 0.0, 0.5801], [1.0, 0.0, 0.557], [1.0, 0.0, 0.5338], [1.0, 0.0, 0.5107], [1.0, 0.0, 0.4875], [1.0, 0.0, 0.4643], [1.0, 0.0, 0.4412], [1.0, 0.0, 0.418], [1.0, 0.0, 0.3949], [1.0, 0.0, 0.3717], [1.0, 0.0, 0.3485], [1.0, 0.0, 0.3254], [1.0, 0.0, 0.3022], [1.0, 0.0, 0.279], [1.0, 0.0, 0.2559], [1.0, 0.0, 0.2327], [1.0, 0.0, 0.2096], [1.0, 0.0, 0.1864], [1.0, 0.0, 0.1632], [1.0, 0.0, 0.1401], [1.0, 0.0, 0.1169], [1.0, 0.0, 0.0938]]}, "jet": {"interpolate": true, "colors": [[0.0, 0.0, 0.5], [0.0, 0.0, 0.5178], [0.0, 0.0, 0.5357], [0.0, 0.0, 0.5535], [0.0, 0.0, 0.5713], [0.0, 0.0, 0.5891], [0.0, 0.0, 0.607], [0.0, 0.0, 0.6248], [0.0, 0.0, 0.6426], [0.0, 0.0, 0.6604], [0.0, 0.0, 0.6783], [0.0, 0.0, 0.6961], [0.0, 0.0, 0.7139], [0.0, 0.0, 0.7317], [0.0, 0.0, 0.7496], [0.0, 0.0, 0.7674], [0.0, 0.0, 0.7852], [0.0, 0.0, 0.803], [0.0, 0.0, 0.8209], [0.0, 0.0, 0.8387], [0.0, 0.0, 0.8565], [0.0, 0.0, 0.8743], [0.0, 0.0, 0.8922], [0.0, 0.0, 0.91], [0.0, 0.0, 0.9278], [0.0, 0.0, 0.9456], [0.0, 0.0, 0.9635], [0.0, 0.0, 0.9813], [0.0, 0.0, 0.9991], [0.0, 0.0, 1.0], [0.0, 0.0, 1.0], [0.0, 0.0, 1.0], [0.0, 0.002, 1.0], [0.0, 0.0176, 1.0], [0.0, 0.0333, 1.0], [0.0, 0.049, 1.0], [0.0, 0.0647, 1.0], [0.0, 0.0804, 1.0], [0.0, 0.0961, 1.0], [0.0, 0.1118, 1.0], [0.0, 0.1275, 1.0], [0.0, 0.1431, 1.0], [0.0, 0.1588, 1.0], [0.0, 0.1745, 1.0], [0.0, 0.1902, 1.0], [0.0, 0.2059, 1.0], [0.0, 0.2216, 1.0], [0.0, 0.2373, 1.0], [0.0, 0.2529, 1.0], [0.0, 0.2686, 1.0], [0.0, 0.2843, 1.0], [0.0, 0.3, 1.0], [0.0, 0.3157, 1.0], [0.0, 0.3314, 1.0], [0.0, 0.3471, 1.0], [0.0, 0.3627, 1.0], [0.0, 0.3784, 1.0], [0.0, 0.3941, 1.0], [0.0, 0.4098, 1.0], [0.0, 0.4255, 1.0], [0.0, 0.4412, 1.0], [0.0, 0.4569, 1.0], [0.0, 0.4725, 1.0], [0.0, 0.4882, 1.0], [0.0, 0.5039, 1.0], [0.0, 0.5196, 1.0], [0.0, 0.5353, 1.0], [0.0, 0.551, 1.0], [0.0, 0.5667, 1.0], [0.0, 0.5824, 1.0], [0.0, 0.598, 1.0], [0.0, 0.6137, 1.0], [0.0, 0.6294, 1.0], [0.0, 0.6451, 1.0], [0.0, 0.6608, 1.0], [0.0, 0.6765, 1.0], [0.0, 0.6922, 1.0], [0.0, 0.7078, 1.0], [0.0, 0.7235, 1.0], [0.0, 0.7392, 1.0], [0.0, 0.7549, 1.0], [0.0, 0.7706, 1.0], [0.0, 0.7863, 1.0], [0.0, 0.802, 1.0], [0.0, 0.8176, 1.0], [0.0, 0.8333, 1.0], [0.0, 0.849, 1.0], [0.0, 0.8647, 0.9962], [0.0, 0.8804, 0.9836], [0.0, 0.8961, 0.9709], [0.0095, 0.9118, 0.9583], [0.0221, 0.9275, 0.9456], [0.0348, 0.9431, 0.933], [0.0474, 0.9588, 0.9203], [0.0601, 0.9745, 0.9077], [0.0727, 0.9902, 0.895], [0.0854, 1.0, 0.8824], [0.098, 1.0, 0.8697], [0.1107, 1.0, 0.8571], [0.1233, 1.0, 0.8444], [0.136, 1.0, 0.8318], [0.1486, 1.0, 0.8191], [0.1613, 1.0, 0.8065], [0.1739, 1.0, 0.7938], [0.1866, 1.0, 0.7812], [0.1992, 1.0, 0.7685], [0.2119, 1.0, 0.7559], [0.2245, 1.0, 0.7432], [0.2372, 1.0, 0.7306], [0.2498, 1.0, 0.7179], [0.2625, 1.0, 0.7052], [0.2751, 1.0, 0.6926], [0.2878, 1.0, 0.6799], [0.3004, 1.0, 0.6673], [0.3131, 1.0, 0.6546], [0.3257, 1.0, 0.642], [0.3384, 1.0, 0.6293], [0.351, 1.0, 0.6167], [0.3637, 1.0, 0.604], [0.3763, 1.0, 0.5914], [0.389, 1.0, 0.5787], [0.4016, 1.0, 0.5661], [0.4143, 1.0, 0.5534], [0.4269, 1.0, 0.5408], [0.4396, 1.0, 0.5281], [0.4522, 1.0, 0.5155], [0.4649, 1.0, 0.5028], [0.4775, 1.0, 0.4902], [0.4902, 1.0, 0.4775], [0.5028, 1.0, 0.4649], [0.5155, 1.0, 0.4522], [0.5281, 1.0, 0.4396], [0.5408, 1.0, 0.4269], [0.5534, 1.0, 0.4143], [0.5661, 1.0, 0.4016], [0.5787, 1.0, 0.389], [0.5914, 1.0, 0.3763], [0.604, 1.0, 0.3637], [0.6167, 1.0, 0.351], [0.6293, 1.0, 0.3384], [0.642, 1.0, 0.3257], [0.6546, 1.0, 0.3131], [0.6673, 1.0, 0.3004], [0.6799, 1.0, 0.2878], [0.6926, 1.0, 0.2751], [0.7052, 1.0, 0.2625], [0.7179, 1.0, 0.2498], [0.7306, 1.0, 0.2372], [0.7432, 1.0, 0.2245], [0.7559, 1.0, 0.2119], [0.7685, 1.0, 0.1992], [0.7812, 1.0, 0.1866], [0.7938, 1.0, 0.1739], [0.8065, 1.0, 0.1613], [0.8191, 1.0, 0.1486], [0.8318, 1.0, 0.136], [0.8444, 1.0, 0.1233], [0.8571, 1.0, 0.1107], [0.8697, 1.0, 0.098], [0.8824, 1.0, 0.0854], [0.895, 1.0, 0.0727], [0.9077, 1.0, 0.0601], [0.9203, 1.0, 0.0474], [0.933, 1.0, 0.0348], [0.9456, 0.9884, 0.0221], [0.9583, 0.9739, 0.0095], [0.9709, 0.9593, 0.0], [0.9836, 0.9448, 0.0], [0.9962, 0.9303, 0.0], [1.0, 0.9158, 0.0], [1.0, 0.9012, 0.0], [1.0, 0.8867, 0.0], [1.0, 0.8722, 0.0], [1.0, 0.8577, 0.0], [1.0, 0.8431, 0.0], [1.0, 0.8286, 0.0], [1.0, 0.8141, 0.0], [1.0, 0.7996, 0.0], [1.0, 0.785, 0.0], [1.0, 0.7705, 0.0], [1.0, 0.756, 0.0], [1.0, 0.7415, 0.0], [1.0, 0.7269, 0.0], [1.0, 0.7124, 0.0], [1.0, 0.6979, 0.0], [1.0, 0.6834, 0.0], [1.0, 0.6688, 0.0], [1.0, 0.6543, 0.0], [1.0, 0.6398, 0.0], [1.0, 0.6253, 0.0], [1.0, 0.6107, 0.0], [1.0, 0.5962, 0.0], [1.0, 0.5817, 0.0], [1.0, 0.5672, 0.0], [1.0, 0.5527, 0.0], [1.0, 0.5381, 0.0], [1.0, 0.5236, 0.0], [1.0, 0.5091, 0.0], [1.0, 0.4946, 0.0], [1.0, 0.48, 0.0], [1.0, 0.4655, 0.0], [1.0, 0.451, 0.0], [1.0, 0.4365, 0.0], [1.0, 0.4219, 0.0], [1.0, 0.4074, 0.0], [1.0, 0.3929, 0.0], [1.0, 0.3784, 0.0], [1.0, 0.3638, 0.0], [1.0, 0.3493, 0.0], [1.0, 0.3348, 0.0], [1.0, 0.3203, 0.0], [1.0, 0.3057, 0.0], [1.0, 0.2912, 0.0], [1.0, 0.2767, 0.0], [1.0, 0.2622, 0.0], [1.0, 0.2476, 0.0], [1.0, 0.2331, 0.0], [1.0, 0.2186, 0.0], [1.0, 0.2041, 0.0], [1.0, 0.1895, 0.0], [1.0, 0.175, 0.0], [1.0, 0.1605, 0.0], [1.0, 0.146, 0.0], [1.0, 0.1314, 0.0], [1.0, 0.1169, 0.0], [1.0, 0.1024, 0.0], [1.0, 0.0879, 0.0], [0.9991, 0.0733, 0.0], [0.9813, 0.0588, 0.0], [0.9635, 0.0443, 0.0], [0.9456, 0.0298, 0.0], [0.9278, 0.0153, 0.0], [0.91, 0.0007, 0.0], [0.8922, 0.0, 0.0], [0.8743, 0.0, 0.0], [0.8565, 0.0, 0.0], [0.8387, 0.0, 0.0], [0.8209, 0.0, 0.0], [0.803, 0.0, 0.0], [0.7852, 0.0, 0.0], [0.7674, 0.0, 0.0], [0.7496, 0.0, 0.0], [0.7317, 0.0, 0.0], [0.7139, 0.0, 0.0], [0.6961, 0.0, 0.0], [0.6783, 0.0, 0.0], [0.6604, 0.0, 0.0], [0.6426, 0.0, 0.0], [0.6248, 0.0, 0.0], [0.607, 0.0, 0.0], [0.5891, 0.0, 0.0], [0.5713, 0.0, 0.0], [0.5535, 0.0, 0.0], [0.5357, 0.0, 0.0], [0.5178, 0.0, 0.0], [0.5, 0.0, 0.0]]}}; 2 | 3 | const turbo = partial('turbo'); 4 | const turbo_r = partial('turbo_r'); 5 | const viridis = partial('viridis'); 6 | const viridis_r = partial('viridis_r'); 7 | const hsv = partial('hsv'); 8 | const hsv_r = partial('hsv_r'); 9 | const jet = partial('jet'); 10 | const jet_r = partial('jet_r'); 11 | 12 | 13 | /* 14 | Define auxiliary functions for evaluating colormaps 15 | */ 16 | 17 | function ColorToHex(color) { 18 | var hexadecimal = color.toString(16); 19 | return hexadecimal.length == 1 ? "0" + hexadecimal : hexadecimal; 20 | } 21 | 22 | function ConvertRGBtoHex(color_arr) { 23 | return "#" + ColorToHex(color_arr[0]) + ColorToHex(color_arr[1]) + ColorToHex(color_arr[2]); 24 | } 25 | 26 | function evaluate_cmap(x, name, reverse) { 27 | /** 28 | * Evaluate colormap `name` at some value `x`. 29 | * @param {number} x - The value (between 0 and 1) at which to evaluate the colormap. 30 | * @param {string} name - The name of the colormap (see matplotlib documentation). 31 | * @reverse {boolean} reverse - Whether or not to reverse the colormap. 32 | * @return {list} - A 3-tuple (R, G, B) containing the color assigned to `x`. 33 | */ 34 | 35 | // Ensure that the value of `x` is valid (i.e., 0 <= x <= 1) 36 | if (!(0 <= x <= 1)) { 37 | alert('Illegal value for x! Must be in [0, 1].') 38 | } 39 | 40 | // Ensure that `name` is a valid colormap 41 | if (!(name in cm_data)) { 42 | alert('Colormap ' + name + 'does not exist!'); 43 | } 44 | 45 | // We can get the reverse colormap by evaluating colormap(1-x) 46 | if (reverse === true) { 47 | x = 1 - x; 48 | } 49 | 50 | // Get the colors and whether or not we need to interpolate 51 | let colors = cm_data[name]['colors']; 52 | let interpolate = cm_data[name]['interpolate']; 53 | 54 | if (interpolate === true) { 55 | return interpolated(x, colors); 56 | } else { 57 | return qualitative(x, colors); 58 | } 59 | } 60 | 61 | function interpolated(x, colors) { 62 | let lo = Math.floor(x * (colors.length - 1)); 63 | let hi = Math.ceil(x * (colors.length - 1)); 64 | let r = Math.round((colors[lo][0] + colors[hi][0]) / 2 * 255); 65 | let g = Math.round((colors[lo][1] + colors[hi][1]) / 2 * 255); 66 | let b = Math.round((colors[lo][2] + colors[hi][2]) / 2 * 255); 67 | return [r, g, b]; 68 | } 69 | 70 | function qualitative(x, colors) { 71 | let idx = 0; 72 | while (x > (idx + 1) / (colors.length - 0) ) { idx++; } 73 | let r = Math.round(colors[idx][0] * 255); 74 | let g = Math.round(colors[idx][1] * 255); 75 | let b = Math.round(colors[idx][2] * 255); 76 | return [r, g, b]; 77 | } 78 | 79 | function partial(name) { 80 | if (name.endsWith('_r')) { 81 | return function(x) { return evaluate_cmap(x, name.substring(0, name.length - 2), true) }; 82 | } else { 83 | return function(x) { return evaluate_cmap(x, name, false) }; 84 | } 85 | } -------------------------------------------------------------------------------- /js/jquery.form.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Form Plugin 3 | * version: 2.43 (12-MAR-2010) 4 | * @requires jQuery v1.3.2 or later 5 | * 6 | * Examples and documentation at: http://malsup.com/jquery/form/ 7 | * Dual licensed under the MIT and GPL licenses: 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * http://www.gnu.org/licenses/gpl.html 10 | */ 11 | ;(function($) { 12 | 13 | /* 14 | Usage Note: 15 | ----------- 16 | Do not use both ajaxSubmit and ajaxForm on the same form. These 17 | functions are intended to be exclusive. Use ajaxSubmit if you want 18 | to bind your own submit handler to the form. For example, 19 | 20 | $(document).ready(function() { 21 | $('#myForm').bind('submit', function() { 22 | $(this).ajaxSubmit({ 23 | target: '#output' 24 | }); 25 | return false; // <-- important! 26 | }); 27 | }); 28 | 29 | Use ajaxForm when you want the plugin to manage all the event binding 30 | for you. For example, 31 | 32 | $(document).ready(function() { 33 | $('#myForm').ajaxForm({ 34 | target: '#output' 35 | }); 36 | }); 37 | 38 | When using ajaxForm, the ajaxSubmit function will be invoked for you 39 | at the appropriate time. 40 | */ 41 | 42 | /** 43 | * ajaxSubmit() provides a mechanism for immediately submitting 44 | * an HTML form using AJAX. 45 | */ 46 | $.fn.ajaxSubmit = function(options) { 47 | // fast fail if nothing selected (http://dev.jquery.com/ticket/2752) 48 | if (!this.length) { 49 | log('ajaxSubmit: skipping submit process - no element selected'); 50 | return this; 51 | } 52 | 53 | if (typeof options == 'function') 54 | options = { success: options }; 55 | 56 | var url = $.trim(this.attr('action')); 57 | if (url) { 58 | // clean url (don't include hash vaue) 59 | url = (url.match(/^([^#]+)/)||[])[1]; 60 | } 61 | url = url || window.location.href || ''; 62 | 63 | options = $.extend({ 64 | url: url, 65 | type: this.attr('method') || 'GET', 66 | iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' 67 | }, options || {}); 68 | 69 | // hook for manipulating the form data before it is extracted; 70 | // convenient for use with rich editors like tinyMCE or FCKEditor 71 | var veto = {}; 72 | this.trigger('form-pre-serialize', [this, options, veto]); 73 | if (veto.veto) { 74 | log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); 75 | return this; 76 | } 77 | 78 | // provide opportunity to alter form data before it is serialized 79 | if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { 80 | log('ajaxSubmit: submit aborted via beforeSerialize callback'); 81 | return this; 82 | } 83 | 84 | var a = this.formToArray(options.semantic); 85 | if (options.data) { 86 | options.extraData = options.data; 87 | for (var n in options.data) { 88 | if(options.data[n] instanceof Array) { 89 | for (var k in options.data[n]) 90 | a.push( { name: n, value: options.data[n][k] } ); 91 | } 92 | else 93 | a.push( { name: n, value: options.data[n] } ); 94 | } 95 | } 96 | 97 | // give pre-submit callback an opportunity to abort the submit 98 | if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { 99 | log('ajaxSubmit: submit aborted via beforeSubmit callback'); 100 | return this; 101 | } 102 | 103 | // fire vetoable 'validate' event 104 | this.trigger('form-submit-validate', [a, this, options, veto]); 105 | if (veto.veto) { 106 | log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); 107 | return this; 108 | } 109 | 110 | var q = $.param(a); 111 | 112 | if (options.type.toUpperCase() == 'GET') { 113 | options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; 114 | options.data = null; // data is null for 'get' 115 | } 116 | else 117 | options.data = q; // data is the query string for 'post' 118 | 119 | var $form = this, callbacks = []; 120 | if (options.resetForm) callbacks.push(function() { $form.resetForm(); }); 121 | if (options.clearForm) callbacks.push(function() { $form.clearForm(); }); 122 | 123 | // perform a load on the target only if dataType is not provided 124 | if (!options.dataType && options.target) { 125 | var oldSuccess = options.success || function(){}; 126 | callbacks.push(function(data) { 127 | var fn = options.replaceTarget ? 'replaceWith' : 'html'; 128 | $(options.target)[fn](data).each(oldSuccess, arguments); 129 | }); 130 | } 131 | else if (options.success) 132 | callbacks.push(options.success); 133 | 134 | options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg 135 | for (var i=0, max=callbacks.length; i < max; i++) 136 | callbacks[i].apply(options, [data, status, xhr || $form, $form]); 137 | }; 138 | 139 | // are there files to upload? 140 | var files = $('input:file', this).fieldValue(); 141 | var found = false; 142 | for (var j=0; j < files.length; j++) 143 | if (files[j]) 144 | found = true; 145 | 146 | var multipart = false; 147 | // var mp = 'multipart/form-data'; 148 | // multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); 149 | 150 | // options.iframe allows user to force iframe mode 151 | // 06-NOV-09: now defaulting to iframe mode if file input is detected 152 | if ((files.length && options.iframe !== false) || options.iframe || found || multipart) { 153 | // hack to fix Safari hang (thanks to Tim Molendijk for this) 154 | // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d 155 | if (options.closeKeepAlive) 156 | $.get(options.closeKeepAlive, fileUpload); 157 | else 158 | fileUpload(); 159 | } 160 | else 161 | $.ajax(options); 162 | 163 | // fire 'notify' event 164 | this.trigger('form-submit-notify', [this, options]); 165 | return this; 166 | 167 | 168 | // private function for handling file uploads (hat tip to YAHOO!) 169 | function fileUpload() { 170 | var form = $form[0]; 171 | 172 | if ($(':input[name=submit]', form).length) { 173 | alert('Error: Form elements must not be named "submit".'); 174 | return; 175 | } 176 | 177 | var opts = $.extend({}, $.ajaxSettings, options); 178 | var s = $.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts); 179 | 180 | var id = 'jqFormIO' + (new Date().getTime()); 181 | var $io = $('