Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using it's URL and the proper URL extention.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <div class="background dusk">
</div>
<div class="background dawn">
</div>

<div class="author_info" id="author_info">
  <h1>My Overachieving Weather App</h1>
  <div class="author_info_content">
  <p>Hey there! So here is my little weather app. I'm currently going through the Free Code Camp curriculum on a part-time basis. I've been involved with web technologies since the mid-1990s - the Compuserve era in fact!</p>
  <p>This little page is my answer to their Weather App challenge. I decided to spice it up a bit. The original challenge called for the user of the browser geolocation API as well as a weather API to show current weather for the user's location as well as the ability to toggle temperatures between Fahrenheit and Celsius.</p>
  <p>I wanted the challenge of working with multiple APIs to put together a page. So this page presents a small, arbitrary gallery of 10 cities around the planet for which you can view the weather. Additionally, it is backed by Google's places API, so you can enter any city and it will display the weather first result found.</p>
    <p>
      Using Sunset/Sunrise times the page will also update its look based on the time of day as well as for current weather conditions.
    </p>
    <p>In the end, nothing super groundbreaking (in fact, I don't think there's anything done here that hasn't been done before). But it was a fun challenge for myself and I hope you enjoy it!</p>
  </div>
</div>

<div class="main container">

  <div class="row">
    
    <div class="left hidden-xs col-xs-12 col-sm-2 col-md-2 col-lg-2">
    </div>

    <div class="middle col-xs-12 col-sm-8 col-md-8 col-lg-8">

      <div class="upper grid">

        <div class="top conditions">

          <h1 class="location_name">
          </h1>
          <h3 class="current_conditions"></h3>
          <div class="weather_icon"><img class="day"><img class="night"></div>
          <div class="info temperature margin_left hidden" title="Toggle Temperature Scale" data-clickhandler="temperature">
            <p>Temperature <span class="temp"></span>&deg; <span class="scale"></span></p>
          </div>
          <div class="info wind hidden">
            <p>Wind <span class="wind_speed" title="Meters/Second"></span> <span class="wind_direction"></span>&deg; (<span class="wind_compass_direction"></span>)</p>
          </div>
          <div class="info latlong margin_left hidden" data-clickhandler="display_map" title="Open in Google Maps!">
            <p>Latitude: <span class="lat"></span>&deg;</p>
            <p>Longitude: <span class="lng"></span>&deg;</p>
          </div>
          <div class="info time hidden" title="These times are adjusted relative to the location you are viewing.">
            <p>Sunrise: <span class="sunrise"></span></p>
            <p>Sunset: <span class="sunset"></span></p>
          </div>

        </div> 

      </div>

      <div class="lower">

        <div class="top forecast">
          <h3>Forecast</h3>

        </div>

        <div class="bottom">
        </div>

      </div>

    </div>

    <div class="right hidden-xs ccol-xs-12 col-sm-2 col-md-2 col-lg-2">
    </div>    
    
  </div>

  <div class="row">
    <div class="text-center find_location col-xs-12 col-sm-12 col-md-12 col-lg-12">
      <form class="find_city"><input type="text" class="location" value="" placeholder="Enter a City Name"><button class="find" type="button" data-clickhandler="load_city">Find it!</button></form>
    </div>
  </div>
  
  <div class="row">
    <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
      <p class="text-center"><span data-clickhandler="show_author_info" class="show_author_info">About this Weather App.</span> | Micheal Hall, 2016 </p>
    </div>
  </div>
  
</div>

              
            
!

CSS

              
                /* COLORS */
.main a,
.main a:hover{
  color: white;
}

.background{
  position: fixed;
  left: 0;
  top: 0;
  height: 100%;
  width: 100%;
}

button {
  font-family: 'Oswald';
  color: black;
  font-size: .8em;
}

body{
  background-color: rgb(122, 122, 122);  
}

body,
input
{
  transition: background-color 3s, color .5s;
}

input{
  color: rgba(0,0,0,.5);
}

.info,
input{
  transition: background-color .5s, color .5s;
}

.latlong:hover,
.temperature:hover{
  cursor: pointer;
}

body .weather_icon img.day,
body .weather_icon img.night{
  display: none;
}

body.day .weather_icon img.day,
body.night .weather_icon img.night{
  display: inline-block;
}

body.temp_scale_C .min_f,
body.temp_scale_C .max_f,
body.temp_scale_F .min_c,
body.temp_scale_F .max_c{
  display: none;
}


.author_info {
  z-index: 15;
  position: absolute;
  left: 0;
  top: 0;
  width: 50%;
  height: 75%;
  margin-left: 25%;
  margin-top: 5%;
  background-color: rgb( 200,200,200);
  color: black;
  border-radius: 6px;
  transition: transform .25s cubic-bezier(.42,0,.91,1.22), background-color 3s, color 3s;
  box-shadow: 0 0 6px rgba( 0,0,0,.5 );
  overflow: hidden;
}

.author_info.hidden_left{
  transition: transform .25s ease-out;  
  transform: translateX(-200%);
}

.author_info p{
  margin: 1em 2em;
}

.author_info .author_info_content{
  overflow: auto;
  margin-top: 1em;
  height: calc( 100% - 8em );
}

span.show_author_info:hover{
  cursor: pointer;
  text-decoration: underline;
}


/* SUNNY COLOR STYLES */
body .dusk,
body .dawn{
  opacity: 0;
  transition: opacity 3s; 
}

body.clear.dawn .dawn{
  transition: opacity 3s;  
  opacity: 1;
  background: linear-gradient(to bottom, rgba(6,3,79,1) 0%,rgba(54,46,209,1) 29%,rgba(175,196,208,1) 65%,rgba(247,220,81,1) 81%,rgba(244,168,80,1) 88%,rgba(210,42,22,1) 96%,rgba(210,42,22,1) 100%);  
}

body.clear.dusk .dusk{
  transition: opacity 3s;
  opacity: 1;
  background: linear-gradient(to bottom, rgba(6,3,79,1) 0%,rgba(46,42,170,1) 29%,rgba(206,175,194,1) 65%,rgba(247,230,145,1) 81%,rgba(244,168,80,1) 88%,rgba(209,23,47,1) 96%,rgba(209,23,72,1) 100%);  
}

body.clear .author_info{
 color: white;
 background-color: rgb(128, 187, 247);  
}


body.clear ::-webkit-input-placeholder{
  color: white;
}

.clear input{
  color: white;
  background-color: rgb(128, 187, 247);
}

.clear .gallery_item img:hover {
  box-shadow: 0 0 3px 3px rgb(224, 161, 13);
}

.clear .latlong:hover,
.clear .temperature:hover,
.clear input:focus{
  background-color: rgb(255, 212, 112);
  color: rgba(0,0,0,.5);
}

body.clear{
   background: none;
   background-color: rgb(7, 99, 191);
}

body.clear.night {
  background-color: rgb(9, 12, 71);
}

.clear.night .gallery_item img:hover{
  box-shadow: 0 0 3px 3px rgb(95, 103, 239);  
}




/* THUNDERSTORM COLOR STYLES */
body.thunderstorm{
  background-color: rgb(15,15,15);
}

body.thunderstorm.night{
  color: white;
  background-color: rgb(0, 0, 0);
}

body.thunderstorm .author_info{
 background-color: rgb(45,45,45);  
}

.thunderstorm input{
  background-color: rgb(64, 64, 64);
}

.thunderstorm .latlong:hover,
.thunderstorm .info.temperature:hover,
.thunderstorm input:focus{
  background-color: rgb(255, 253, 155);
  color: black;
}

.thunderstorm .forecast_box{
  color: rgb(255, 253, 155);
}




/* CLOUDY COLOR STYLES */


body.cloudy{
  background-color: rgb(68, 68, 68);
}

body.cloudy.night{
  background-color: rgb(8,8,8);
}

body.cloudy .author_info{
 color: white;
 background-color: rgb(128,128,128);  
}

.cloudy .middle{
  border-color: rgb(12, 12, 12);
}

.cloudy input{
  background-color: rgb(64,64,64);
}

.cloudy .latlong:hover,
.cloudy .temperature:hover,
.cloudy input:focus{
  background-color: rgb(112, 193, 255);
  color: rgba(0,0,0,.5);
}

.cloudy .gallery_item img{
  filter: grayscale(75%);
}

.cloudy .gallery_item img:hover {
  box-shadow: 0 0 3px 3px rgb(28, 28, 28);
}







/* SNOWY COLOR STYLES */

.snowy a,
.snowy a:hover{
  color: black;
}

body.snowy{
  background: none;
  background-color: rgb(255,255,255);
}

.snowy .lower .forecast{
  background-color: rgba( 0,0,0,.3);
  border: solid 1px black;
  border-radius: 3px;
}


.snowy input:focus{
  background-color: black;
  color: white;
}

.snowy .gallery_item img{
  filter: grayscale(100%);
}


.snowy .latlong:hover,
.snowy .temperature:hover{
  cursor: pointer;  
}

.snowy .latlong:hover,
.snowy .info.temperature:hover{
  background-color: rgb(170, 212, 255);
}

.snowy {
  color: rgb(28,28,28);
}

.snowy .info{
  background-color: rgba(0,0,0,.1);
}

.snowy .gallery_item img:hover {
  box-shadow: 0 0 3px 3px rgb(28, 28, 28);
}




/* END COLOR THEMES */
  









body {
  font-family: 'Montserrat', sans-serif;
  color: white;
}

h1,
h3{
  text-align: center;
  margin: 0;
}

h1{
  margin-top: 1em;
}

h1,
.top.forecast{
  font-family: 'Oswald';
}

.middle{
  margin: 0;
  height: 100%;
  z-index: 10;
  overflow: hidden;
}


.lower .bottom,
.lower .top,
.middle .upper,
.middle .lower{
  height: 65%;
}

.lower .top{
  margin-top: 2em;
}

.middle .upper {
  left: 0;
  top: 0;
  height: 75%;
}

.middle .lower {
  left: 0;
  top: 65%;
  height: 50%;
  z-index: 10;
}

.find_location {
  text-align: center;
  padding: 1em;
  bottom: 0;
  font-size: 1.5em;
}


.forecast h3{
  margin: .5em 0;
}

.forecast {
  overflow: hidden;
  position: relative;
}

.forecast_box {
  opacity: 1;
  display: inline-block;
  width: 23%;
  height: calc( 100% - 6em );
  margin-left: 1.25%;
  text-align: center;
  padding-top: .5em;
  overflow: hidden;
  box-sizing: border-box;
}

.forecast_box._0{
  transition: transform .2s cubic-bezier(.56,-0.01,.9,1.33), opacity .35s ease-out .1s;
}

.forecast_box._1{
  transition: transform .2s cubic-bezier(.56,-0.01,.9,1.33) .125s, opacity .35s ease-out .15s;
}

.forecast_box._2{
  transition: transform .2s cubic-bezier(.56,-0.01,.9,1.33) .25s, opacity .35s ease-out .2s;
}

.forecast_box._3{
  transition: transform .2s cubic-bezier(.56,-0.01,.9,1.33) .375s, opacity .35s ease-out .25s;
}

.forecast_box.hidden_bottom{
  transform: translateY(350px);
  opacity: 0;
}

.forecast_box p.in_left{
  transition: transform .25s ease-in .25s, opacity .25s ease-in .21s;
  opacity: 0;
  transform: translateX(-200%);
}
.forecast_box p.in_right{
  transition: transform .25s ease-in .25s, opacity .25s ease-in .21s;
  opacity: 0;
  transform: translateX(200%);
}

.forecast_box:hover p.in_bottom,
.forecast_box:hover p.in_left,
.forecast_box:hover p.in_right{
  opacity: 1;
  transition: transform .25s ease-in, opacity .25s ease-in .05s;
  transform: translateX(0) translateY(0);
}

.forecast_box p.in_bottom{
  transition: transform .25s ease-in .25s, opacity .25s ease-in .21s;
  opacity: 0;
  transform: translateY(-200%);
}

.forecast_box p{
  margin-bottom: 0;
}

.forecast_box img{
  margin: 0;
  margin-left: -.75em;
  width: 100%;
  max-width: 170px;
  height: auto;
}


input{
  padding-left: .5em;
  border: none;
  border-radius: 3px;
  box-shadow: inset 2px 2px 2px rgba( 0,0,0, .5);
}

.gallery_item {
  height: calc( 20% - .5em );
  width: 100%;
  float: left;
  overflow: hidden;
  margin-bottom: .5em;
  text-align: center;
  color: white;
  text-shadow: 1px 1px 1px rgba( 0,0,0,.8);
}

.gallery_item:hover{
  cursor: pointer;
}

.gallery_item img:hover{
  filter: none;
}

.gallery_item img{
  width: 100px;
  height: auto;
  margin-top: .5em;
  border-radius: 50%;
  border: none;
  box-shadow: 0 0 6px rgba( 0,0,0,.75);
}

.info{
  border-radius: 3px;
  background-color: rgba(255,255,255,.2);
  display: inline-block;
  width: 35%;
  font-size: .8em;
  text-align: center;
  min-height: 25%;
  font-size: 1.2em;  
  margin-top: 1em;
  margin-left: 3%;
  overflow: hidden;
}

.info.margin_left {
  margin-left: 15%;
}

.info p {
  margin-top: 1em;
}

.weather_icon{
	height: 120px;
}

.weather_icon img{
  display: block;
	width: 175px;
	height: 120px;
	margin-left: calc( 50% - 90px );
}

.reset {
  position: relative;
}

@media all and (min-width: 480px) {
  
  .author_info{
    margin: 0;
    width: 100%;
    height: 100%;
  }

  .gallery_item {
    margin-top: 0;
    width: 20%;
  }
  
  .gallery_item img{
    width: 85px;
  }
  
  .info {
    font-size: .8em;
  }
  
}


@media all and (min-width: 768px) {

  .author_info{
    width: 50%;
    height: 75%;
    margin-left: 25%;
    margin-top: 5%;    
  }
  
  .gallery_item:first-child{
    margin-top: 1em;
  }
  
  .gallery_item {
    width: 100%;
  }
  .gallery_item img {
    width: 85px;
  }
  
}

@media all and (min-width: 992px) {

  .gallery_item img {
    width: 105px;
  }
  
  .info {
    font-size: 1em;
  }
  
  
}
              
            
!

JS

              
                (() => {

  var now     = new Date();
  const $body = $( 'body' );
  const $time = $body.find( '.info.time' );
  
  const config = {
    'templates':{
      'gallery_item': $( '<div class="gallery_item" data-clickhandler="load_gallery_city"><img class="city_image clickable" title="Click to check the weather!"><p class="city_name"></p></div>' ),
      'forecast_item': $( '<div class="forecast_box hidden_bottom"><p class="in_left date"></p><p class="in_right time"><span class="min_f"></span><span class="min_c"></span>&deg; - <span class="max_f"></span><span class="max_c"></span>&deg;</p><img class="forecast_icon"><p class="in_bottom conditions"></p></div>' ),
      'author_info': null,
    },
    'condition_classes': [ 'day', 'clear', 'cloudy', 'snowy', 'thunderstorm', 'night', 'dawn', 'dusk' ].join( ' ' ),
    'temperature_classes': [ 'temp_scale_F', 'temp_scale_C' ].join( ' '),
    'current_conditions': {},
    'do_location_query': true,
    'forecast_conditions': {},
    'forecast_limit': 4,
    'forecast_time': '12:00:00',
    'weather_conditions' : {
      '200': {
        'condition': 'Thunderstorms with light rain.',
        'css_class': 'thunderstorm',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png'
        }
      },
      '201': {
        'condition': 'Thunderstorms with rain.',
        'css_class': 'thunderstorm',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png'
        }
      },
      '202': {
        'condition': 'Thunderstorms with heavy rain.',
        'css_class': 'thunderstorm',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png'
        }
      },
      '203': {
        'condition': 'Light thunderstorms.',
        'css_class': 'thunderstorm',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png'
        }
      },
      '204': {
        'condition': 'Thunderstorm.',
        'css_class': 'thunderstorm',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png'
        }
      },
      '205': {
        'condition': 'Heavy Thunderstorm',
        'css_class': 'thunderstorm',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png'
        }
      },
      '206': {
        'condition': 'Ragged Thunderstorm.',
        'css_class': 'thunderstorm',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png'
        }
      },
      '207': {
        'condition': 'Thunderstorm with Light Drizzle.',
        'css_class': 'thunderstorm',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png'
        }
      },
      '208': {
        'condition': 'Thunderstorm with Drizzle.',
        'css_class': 'thunderstorm',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png'
        }
      },
      '209': {
        'condition': 'Thunderstorm with Heavy Drizzle.',
        'css_class': 'thunderstorm',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png'
        }
      },
      '300': {
        'condition': 'Light intensity Drizzle.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/9.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/9.png'
        }
      },
      '301': {
        'condition': 'Drizzle.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/9.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/9.png'
        }
      },
      '302': {
        'condition': 'Heavy intensity Drizzle.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/9.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/9.png'
        }
      },
      '310': {
        'condition': 'Light intensity Drizzle Rain.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/9.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/9.png'
        }
      },
      '311': {
        'condition': 'Drizzle Rain.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/9.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/9.png'
        }
      },
      '312': {
        'condition': 'Heavy intensity Drizzle Rain.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/9.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/9.png'
        }
      },
      '313': {
        'condition': 'Shower Rain and Drizzle.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/9.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/9.png'
        }
      },
      '314': {
        'condition': 'Heavy Shower Rain and Drizzle.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/9.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/9.png'
        }
      },
      '321': {
        'condition': 'Shower Drizzle.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/9.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/9.png'
        }
      },
      '500': {
        'condition': 'Light Rain.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/11.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/11.png'
        }
      },
      '501': {
        'condition': 'Moderate Rain.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/11.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/11.png'
        }
      },
      '502': {
        'condition': 'Heavy Intensity Rain.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/12.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/12.png'
        }
      },
      '503': {
        'condition': 'Very Heavy Rain.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/12.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/12.png'
        }
      },
      '504': {
        'condition': 'Extreme Rain.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/12.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/12.png'
        }
      },
      '511': {
        'condition': 'Freezing Rain.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/08.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/08.png'
        }
      },
      '520': {
        'condition': 'Light Intensity Shower Rain.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/11.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/11.png'
        }
      },
      '521': {
        'condition': 'Shower Rain.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/11.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/11.png'
        }
      },
      '522': {
        'condition': 'Heavy Intensity Shower Rain.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/12.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/12.png'
        }
      },
      '531': {
        'condition': 'Ragged Shower Rain.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/12.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/12.png'
        }
      },
      '600': {
        'condition': 'Light Snow.',
        'css_class': 'snowy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/13.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/13.png'
        }
      },
      '601': {
        'condition': 'Snow.',
        'css_class': 'snowy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/14.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/14.png'
        }
      },
      '602': {
        'condition': 'Heavy Snow.',
        'css_class': 'snowy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/18.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/18.png'
        }
      },
      '611': {
        'condition': 'Sleet.',
        'css_class': 'snowy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/25.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/25.png'
        }
      },
      '612': {
        'condition': 'Shower Sleet.',
        'css_class': 'snowy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/8.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/8.png'
        }
      },
      '615': {
        'condition': 'Light Rain and Snow.',
        'css_class': 'snowy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/5.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/5.png'
        }
      },
      '616': {
        'condition': 'Rain and Snow.',
        'css_class': 'snowy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/6.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/6.png'
        }
      },
      '620': {
        'condition': 'Light Shower Snow.',
        'css_class': 'snowy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/14.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/14.png'
        }
      },
      '621': {
        'condition': 'Shower Snow.',
        'css_class': 'snowy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/14.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/14.png'
        }
      },
      '622': {
        'condition': 'Heavy Shower Snow.',
        'css_class': 'snowy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/18.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/18.png'
        }
      },
      '701': {
        'condition': 'Mist.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png'
        }
      },
      '711': {
        'condition': 'Smoke.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png'
        }
      },
      '721': {
        'condition': 'Haze.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png'
        }
      },
      '731': {
        'condition': 'Sand, Dust Whirls.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png'
        }
      },
      '741': {
        'condition': 'Fog.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png'
        }
      },
      '751': {
        'condition': 'Sand.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png'
        }
      },
      '761': {
        'condition': 'Dust.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png'
        }
      },
      '762': {
        'condition': 'Volcanic Ash.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png'
        }
      },
      '771': {
        'condition': 'Squalls.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png'
        }
      },
      '781': {
        'condition': 'Tornado.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png'
        }
      },
      '800': {
        'condition': 'Clear Sky.',
        'css_class': 'clear',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/32.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/31.png'
        }
      },
      '801': {
        'condition': 'Few Clouds.',
        'css_class': 'clear',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/34.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/33.png'
        }
      },
      '802': {
        'condition': 'Scattered Clouds.',
        'css_class': 'clear',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/30.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/29.png'
        }
      },
      '803': {
        'condition': 'Broken Clouds.',
        'css_class': 'clear',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/28.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/27.png'
        }
      },
      '804': {
        'condition': 'Overcast Clouds.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png'
        }
      },
      '900': {
        'condition': 'Tornado.',
        'css_class': 'cloudy',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png'
        }
      },
      '901': {
        'condition': 'Tropical Storm.',
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png',
          'css_class': 'cloudy'
      },
      '902': {
        'condition': 'Hurricane.',
        'css_class': 'cloudy',
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/26.png'
      },
      '903': {
        'condition': 'Cold.',
        'css_class': 'cloudy',
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/32.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/31.png'
      },
      '904': {
        'condition': 'Hot.',
        'css_class': 'clear',
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/32.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/31.png'
      },
      '905': {
        'condition': 'Windy.',
        'css_class': 'clear',
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/32.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/31.png'
      },
      '906': {
        'condition': 'Hail.',
        'css_class': 'cloudy',
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/32.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/31.png'
      },
      '951': {
        'condition': 'Calm.',
        'css_class': 'clear',
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/32.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/31.png'
      },
      '952': {
        'condition': 'Light Breeze.',
        'css_class': 'clear',
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/32.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/31.png'
      },
      '953': {
        'condition': 'Gentle Breeze.',
        'css_class': 'clear',
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/32.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/31.png'
      },
      '954': {
        'condition': 'Moderate Breeze.',
        'css_class': 'clear',
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/32.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/31.png'
      },
      '955': {
        'condition': 'Fresh Breeze.',
        'css_class': 'clear',
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/32.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/31.png'
      },
      '956': {
        'condition': 'Strong Breeze.',
        'css_class': 'clear',
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/32.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/31.png'
      },
      '957': {
        'condition': 'High Wind, Near Gale.',
        'css_class': 'cloudy',
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/32.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/31.png'
      },
      '958': {
        'condition': 'Gale.',
        'css_class': 'cloudy',
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/32.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/31.png'
      },
      '959': {
        'condition': 'Severe Gale.',
        'css_class': 'cloudy',
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/32.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/31.png'
      },
      '960': {
        'condition': 'Storm.',
        'css_class': 'cloudy',
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/12.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/12.png'
      },
      '961': {
        'condition': 'Violent Storm.',
        'css_class': 'cloudy',
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/12.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/12.png'
      },
      '962': {
        'condition': 'Hurricane.',
        'css_class': 'cloudy',
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/12.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/12.png'
      }
    },
    'gallery_cities': {
      "left": [
        {
          "_id": 5368361,
          "name": "Los Angeles",
          "images": {
            "day": 'https://www.dropbox.com/s/6ozv286lh0ri4bz/losangeles-day.jpg?dl=1',
            "night": 'https://www.dropbox.com/s/0krb9opwcna7bnu/losangeles-night.jpg?dl=1'
          },
          "country": "US",
          "coord": {
            "lon": -118.243683,
            "lat": 34.052231
          }
        }, 
        {
          "_id": 5128581,
          "name": "New York",
          "images": {
            "day": 'https://www.dropbox.com/s/g1ot02pkeyl6ihq/newyork-day.jpg?dl=1',
            "night": 'https://www.dropbox.com/s/092i9ppilhaej7z/newyork-night.jpg?dl=1'
          },
          "country": "US",
          "coord": {
            "lon": -74.005966,
            "lat": 40.714272
          }
        },
        {
          "_id": 2643741,
          "name": "London",
          "images": {
            "day": 'https://www.dropbox.com/s/0r0lbqoi5tywm7a/london-day.jpg?dl=1',
            "night": 'https://www.dropbox.com/s/rgw1ku6pcag261p/london-night.jpg?dl=1'
          },
          "country": "GB",
          "coord": {
            "lon": -0.09184,
            "lat": 51.512791
          }
        },
        {
          "_id": 756135,
          "name": "Warsaw",
          "images": {
            "day": 'https://www.dropbox.com/s/ll5g0slpgleniqy/warsaw-day.jpg?dl=1',
            "night": 'https://www.dropbox.com/s/8jw0tstuclspfes/warsaw-night.jpg?dl=1'
          },
          "country": "PL",
          "coord": {
            "lon": 21.01178,
            "lat": 52.229771
          }
        },
        {
          "_id": 703448,
          "name": "Kiev",
          "images": {
            "day": 'https://www.dropbox.com/s/823795b15fqgcij/kiev-day.jpg?dl=1',
            "night": 'https://www.dropbox.com/s/h6een3uv709cu0o/kiev-night.jpg?dl=0'
          },
          "country": "UA",
          "coord": {
            "lon": 30.516666,
            "lat": 50.433334
          }
        },
      ],
      "right": [
        {
          "_id": 524901,
          "name": "Moscow",
          "images": {
            "day": 'https://www.dropbox.com/s/wuptt82lc45x1ct/moscow-day.jpg?dl=1',
            "night": 'https://www.dropbox.com/s/skuwlbhv3n1350z/moscow-night.jpg?dl=1'
          },
          "country": "RU",
          "coord": {
            "lon": 37.615555,
            "lat": 55.75222
          }
      },
        {
          "_id": 1496153,
          "name": "Omsk",
          "images": {
            "day": 'https://www.dropbox.com/s/sawe9lohmr3rp26/omsk-day.jpg?dl=1',
            "night": 'https://www.dropbox.com/s/cjmhqahcuv880oo/omsk-night.jpg?dl=1'
          },
          "country": "RU",
          "coord": {
            "lon": 73.400002,
            "lat": 55
          }
        },
        {
          "_id": 1816670,
          "name": "Beijing",
          "images": {
            "day": 'https://www.dropbox.com/s/aac8s0wd2adhjps/beijing-day.jpg?dl=1',
            "night": 'https://www.dropbox.com/s/x2367kka1551mgu/beijing-night2.jpg?dl=1'
          },
          "country": "CN",
          "coord": {
            "lon": 116.397232,
            "lat": 39.907501
          }
        },
        {
          "_id": 1850147,
          "name": "Tokyo",
          "images": {
            "day": 'https://www.dropbox.com/s/1ofl9ij8gvq9vb0/tokyo-day.jpg?dl=1',
            "night": 'https://www.dropbox.com/s/mu0xboclmy3d7yq/tokyo-night.jpg?dl=1'
          },
          "country": "JP",
          "coord": {
            "lon": 139.691711,
            "lat": 35.689499
          }
        },
        {
          "_id": 5856195,
          "name": "Honolulu",
          "images": {
            "day": 'https://www.dropbox.com/s/vdd0cmnifog95o2/honolulu-day.jpg?dl=1',
            "night": 'https://www.dropbox.com/s/hbjr806gzumyqdk/honolulu-night.jpg?dl=1'
          },
          "country": "US",
          "coord": {
            "lon": -157.858337,
            "lat": 21.30694
          }
        }
      ]
    },
    'other_queries': {
      'alternate_location': 'http://ipinfo.io',
      'sunrise': 'https://api.sunrise-sunset.org/json?',
      'geocode': 'https://maps.googleapis.com/maps/api/geocode/json?address=',
      'locationinfo': 'http://api.geonames.org/findNearbyWikipediaJSON?',
      'googlemaps': 'https://www.google.com/maps/place/',
      'googletimezone': 'https://maps.googleapis.com/maps/api/timezone/json?'
    },
    'keys' :{
      'weather': '&APPID=5d378b44b8f7ee222ef047c6a8346be5',
      'geocode': '&key=AIzaSyDFFp6_TdGTAsKIErvMWihBbTCRaCApw18',
      'geonames': '&username=michealhall',
      'timezone': '&key=AIzaSyDfde92MVuy_GyuFC9Qf6x4CarZl3CEh9Q'
    },
    'temp_scale': 'F',
    'weather_queries': {
      'forecastbycity' : 'https://api.openweathermap.org/data/2.5/forecast?id=',
      'forecast_daily' : 'https://api.openweathermap.org/data/2.5/forecast/daily?',
      'forecast' : 'https://api.openweathermap.org/data/2.5/forecast?',
      'latlong': 'https://api.openweathermap.org/data/2.5/weather?',
      'postalcode': 'https://api.openweathermap.org/data/2.5/weather?zip=',
      'city': 'https://api.openweathermap.org/data/2.5/weather?q=',
      'citygroup': 'https://api.openweathermap.org/data/2.5/group?id='
    },
    'compass_sectors' : [
      "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW", "N"
   ]
  };

  
  
  /* CONVERTERS  */
  function convert_degree_to_compass( degree ){
    // https://www.campbellsci.com/blog/convert-wind-directions
    return config.compass_sectors[Math.round( ( degree % 360 ) / 22.5 )];
  }
  
  function convert_k_to_f( kelvin ){
    //http://www.metric-conversions.org/temperature/kelvin-to-fahrenheit.htm
    return ( ( kelvin - 273.15 ) * 1.8000 + 32.00 ).toFixed( 2 );
  }
  
  function convert_k_to_c( kelvin ){
    //http://www.metric-conversions.org/temperature/kelvin-to-celsius.htm
    return ( kelvin - 273.15 ).toFixed( 2 );
  }
  
  
  /* TIME FUNCTIONS */
  function hours_to_milliseconds( hours ){
    return hours * 60 * 60000;
  }
  
  function min_to_milliseconds( minutes ){
    return minutes * 60000;
  }
  
  function sec_to_milliseconds( seconds ){
    return seconds * 1000;
  }
  
  function time_to_milliseconds( time_string ){
    
    const time_array = time_string.split(':');
    return hours_to_milliseconds( time_array[ 0 ] ) + min_to_milliseconds( time_array[ 1 ] + sec_to_milliseconds( time_array[ 2 ] ) );    
    
  }

  
  function is_same_day( now, then ){
    
    // TAKES TWO DATES,COMPARES YYYY:MM:DD
    return ( now.getFullyear() === then.getFullYear() &&
            now.getMonth() === then.getMonth() &&
            now.getDate() === then.getDate() );
    
  }
  
  function is_it_daylight( now, sunrise, sunset ){
    
      // RETURN A BOOLEAN - IF CURRENT TIME IS WITHIN AN HOUR OF SUNRISE OR SUNSET
      const one_hour    = time_to_milliseconds( '01:00:00' );
    
      const now_in_m    = now.getTime();
      const rise_in_m   = sunrise.getTime();
      const set_in_m    = sunset.getTime();
    
      return ( now_in_m > ( rise_in_m - one_hour ) && ( now_in_m < set_in_m + one_hour ));
    
  }

  function is_within_time_range( start, end, compare ){
    
    // WITHIN AN ARBITRARY WINDOW OF TIME - EITHER SIDE
    return ( start > end - compare && start < end + compare );
    
  }
  
  function get_date_from_forecast_string( str ){
    // EXPECTING FORMAT STRING: 2016-10-20 00:00:00
    return str.split( ' ' )[ 0 ];
  }
  
  function get_day_from_forecast_string( str, asInt ){
    // EXPECTING FORMAT STRING: 2016-10-20 00:00:00
    return ( asInt ) ?
      parseInt( str.split( ' ' )[ 0 ].split( '-' )[ 2 ], 10 ) :
      str.split( ' ' )[ 0 ].split( '-' )[ 2 ];
  }
  
  function get_days_in_month( month, year ){
    // http://stackoverflow.com/questions/1184334/get-number-days-in-a-specified-month-using-javascript
    return new Date( year, month, 0 ).getDate();
  }

  function get_offset_date( date, offset ){
    return new Date( date.getTime() + offset );
  }
  

  function get_time_from_forecast_string( str ){
    // EXPECTING FORMAT STRING: 2016-10-20 00:00:00
    return str.split( ' ' )[ 1 ];
  }
  
  function get_time_offset( date, rawOffset, dstOffset ){

    // CALCULATE DATE OFFSET IN MILLISECONDS AND RETURN NEW DATE
    const our_offset   = date.getTimezoneOffset() * 60000;
    const their_offset = ( rawOffset + dstOffset ) * 1000;
    
    return our_offset + their_offset;
    
  }
  
  
  
  /* QUERIES */
  function do_alternate_location_query( callback ){

    $.getJSON( config.other_queries.alternate_location, ( data ) => {

      const coords_array = data.loc.split( ',' );

      (typeof callback === 'function') &&
        callback({
          'coords': {
            'latitude' : coords_array[0], 
            'longitude': coords_array[1] 
          }
        });

    });
    
  }
  
  function do_geocode_lookup( location, callback ){
   
    $.ajax({
      'url': config.other_queries.geocode + location + config.keys.geocode,
      'type': 'GET',
      'success': (data, status, xhr) => {
        
        if ( !data || !data.results )
          return;
        
        const location = data.results[ 0 ].geometry.location;
        const coords = { 'coords': { 'latitude': location.lat, 'longitude': location.lng } };
        
        (typeof callback === 'function') &&
            callback( coords );
        
      }
    });
    
  }
  
  function do_location_query( callback ) {
    
    // THIS DOESN'T WORK IN CHROME OVER HTTP ANY MORE, SO I'M USING A FALLBACK
    // HOWEVER THE FALL BACK DOES WORK IN FF! SO I TRY THE FF VERSION, IF IT 
    // FAILS I FALLBACK TO THE ALTERNATE VERSION THAT WORKS IN CHROME
    if ( !config.do_location_query )
      return;
    
    if ( !navigator.geolocation )
      return do_alternate_location_query( callback );
    
     return navigator.geolocation.getCurrentPosition( callback, ( err ) => {
       do_alternate_location_query( callback );
       return;
     });
      
  }

  function do_sunrise_query( position, callback ){
    
    $.ajax({
      'url': config.other_queries.sunrise + position + '&date=today&formatted=0',
      'type': 'GET',
      'success': ( data, status, xhr ) => {

        (typeof callback === 'function') &&
          callback( data );

      }
    });

  }
  
  function do_timezone_query( location, callback ){
    
    // GOOGLE'S TIMEZONE API WANTS A LOCATION AND A TIMESTAMP
    // TIMESTAMP IN SECONDS.
    return $.ajax({
      'url': config.other_queries.googletimezone + 'location=' + location.coords.latitude + ',' + location.coords.longitude + '&timestamp=' + ( now.getTime() / 1000 ) + config.keys.timezone,
      'type': 'GET'
    });
    
  }
  
  function do_weather_query(options) {
    
    $.ajax({
      'url': config.weather_queries[options.query_type] + options.parameters + config.keys.weather,
      'type': 'GET',
      'success': (data, status, xhr) => {

        (typeof options.callback === 'function') &&
        options.callback(data);

      }
    });

  }

  
  function get_sunrise_and_load( location ){
    
    const sunrise_pos = 'lat=' + location.coords.latitude + '&lng=' + location.coords.longitude;

    do_sunrise_query( sunrise_pos, ( sunrise_data ) => {
      
      sunrise_data.sunrise = new Date( sunrise_data.results.sunrise );
      sunrise_data.sunset  = new Date( sunrise_data.results.sunset );
      
      get_weather_and_forecast( location, sunrise_data );
      
    });
        
  }
  
  function get_weather_and_forecast( location, sunrise_data, is_daylight ){
    
    const $body = $( 'body' );
    const lat_long = 'lat=' + location.coords.latitude + '&lon=' + location.coords.longitude;
    
    // LOAD CURRENT WEATHER
    do_weather_query({
        'query_type': 'latlong',
        'parameters': lat_long,
        'callback': ( data ) => {

          data.sunrise_data = sunrise_data;
          cache_weather_data( data );
          
          do_timezone_query( location )
            .then( ( data ) => {

               if ( !data )
                 return;

               ui_update_for_timezone( location, data );

             });
          
           ui_insert_current_conditions( $body, config.current_conditions, is_daylight );

        }
      });
    
    // LOAD FORECAST WEATHER
    do_weather_query({
        'query_type': 'forecast',
        'parameters': lat_long,
        'callback': ( data ) => {

          cache_forecast_data( data );
          ui_insert_forecasts( $( 'div.forecast' ), config.templates.forecast_item.clone(), data.list );

        }
      });
    
  }

  
  
  /* CACHE DATA */
  function cache_forecast_data( data ){
    config.forecast_conditions = data;
  }

  function cache_weather_data(data) {
    config.current_conditions = data;
  }
  

  
  
  
  /* EVENT HANDLERS */
  const handle_clicks = (() => {

    now = new Date();
    
    const $location_input = $( 'input.location' );
    const $temperature_container = $( '.info.temperature' );

    const click_handlers = {
        'display_map'       : ( e, $clicked ) => {
          
          const options = config.current_conditions.name + '/@' + config.current_conditions.coord.lon + ',' + config.current_conditions.coord.lat;
          
          window.open( config.other_queries.googlemaps + options, 'location');
          
        },
        'load_city'         : ( e, $clicked ) => {
          
          const val = $location_input.val();
          
          if ( !val )
            return false
          
          ui_remove_forecasts( () => do_geocode_lookup( val.split( ' ' ).join('+'), () => get_sunrise_and_load( now ) ) );
          
          return false;

        },
        'load_gallery_city' : ( e, $clicked ) => {

          const city = $clicked.data( 'city' );
          $('input.location').val( city.name );
          
          ui_remove_forecasts( () => get_sunrise_and_load({ 'coords': { 'latitude': city.coord.lat, 'longitude': city.coord.lon }}) );

        },
        'show_author_info'  : ( e, $clicked ) => {
          
          const $author_info = $( '#author_info' );
          
          if ( $author_info.length )
            return ui_remove_author_info( $author_info );
          
          ui_show_author_info();
          
        },
        'temperature'       : ( e, $clicked ) => {
          
          ui_insert_temperature( $temperature_container, config.current_conditions, ( config.temp_scale === 'F' ) ? 'C' : 'F' );
          
        }
    };
    
    return function(){

        $body
          .off( '.weather_app' )
          .on( 'click.weather_app', '.info, .gallery_item, button, .show_author_info', ( e ) => {
          
            const $clicked = $( e.currentTarget );
            const click_handler = $clicked.data( 'clickhandler' );
          
            if ( !click_handler )
              return;
          
            ( typeof click_handlers[ click_handler ] === 'function' ) &&
              click_handlers[ click_handler ]( e, $clicked );

          });

      };
   
  })();
  
  function handle_submit( $form ){
    
    $form.on( 'submit', () => {
      
      ui_remove_forecasts( ()=> do_geocode_lookup( $form.find( 'input' ).val().split( ' ' ).join('+'), get_sunrise_and_load ) );
      return false;
      
    });
    
    
  }
  
  
  
  function pad_string( length, padding, side, string ){

    if ( string.length >= length )
      return string;

    const pad_array = [];
    pad_array.length = ( length - string.length ) + 1;

    return ( side === 'left' ) ? 
      pad_array.join( padding ) + string :
    string + pad_array.join( padding );

  }
  
  
  
  /* UI FUNCTIONS  */
  function ui_build_city_gallery( $item_container, $item_template, city_list ){
    
    city_list.forEach( ( city ) => {
      
      const $city = $item_template.clone();
      
      $city
          .data( 'city', city )
          .find( '.city_name' )
            .text( city.name )
          .end()
          .find( 'img' )
            .attr( 'src', city.images.day )
          .end();
      
      $item_container.append( $city );
      
    });
    
    return $item_container;

  }
  
  function ui_build_forecast_box( condition, $item ){
    
    // GIVEN A PASSED CONDITION, FORMAT AND RETURN A CONDITION UI ITEM
    const f_conditions = config.weather_conditions[ condition.weather[ 0 ].id ];
    const date_string  = get_date_from_forecast_string( condition.dt_txt );

    $item
      .find( '.date' )
        .text( date_string )
      .end()
      .find( '.min_f' )
        .text( convert_k_to_f( condition.main.temp_min ) )
      .end()
      .find( '.max_f' )
        .text( convert_k_to_f( condition.main.temp_max ) )
      .end()
      .find( '.min_c' )
        .text( convert_k_to_c( condition.main.temp_min ) )
      .end()
      .find( '.max_c' )
        .text( convert_k_to_c( condition.main.temp_max ) )
      .end()
      .find( '.conditions' )
        .text( f_conditions.condition )  
      .end()
      .find( '.forecast_icon' )
        .attr( 'src', f_conditions.icons.day )
      .end();
    
    return $item;
    
  }
  
  function ui_insert_city_gallery(){
    
    ui_build_city_gallery( $( 'div.left' ), config.templates.gallery_item.clone(), config.gallery_cities.left );

    ui_build_city_gallery( $( 'div.right' ), config.templates.gallery_item.clone(), config.gallery_cities.right );
    
  }

  function ui_insert_content(){

    // CACHE PAGE INFO TEMPLATE AND REMOVE FROM VISIBLE UI
    config.templates.author_info = $( '#author_info' ).clone();
    $( '#author_info' ).remove();
    
    ui_insert_city_gallery();
    handle_clicks();
    handle_submit( $body.find( 'form.find_city' ) );
    do_location_query( get_sunrise_and_load );
    
  }

  function ui_insert_current_conditions( $body, conditions ){
    
    const weather_condition = config.weather_conditions[ conditions.weather[ 0 ].id ];
    const $container     = $body.find( 'div.middle' );
    const classes_to_add = [];
    const icons = weather_condition.icons;
    
    classes_to_add.push( weather_condition.css_class );
    
    $container
      .find( 'h1.location_name' )
        .text( conditions.name )
      .end()
      .find( 'h3.current_conditions' )
        .text( weather_condition.condition )
      .end()
      .find( 'div.weather_icon img.day' )
        .attr( 'src', ( icons ) ? icons.day : '' )
      .end()
      .find( 'div.weather_icon img.night' )
        .attr( 'src', ( icons ) ? icons.night : '' )
      .end();
    
    ui_insert_temperature( $container.find( 'div.info.temperature' ), conditions, 'F' );
    ui_insert_wind( $container.find( 'div.info.wind'), conditions );
    ui_insert_location_data( $container.find( 'div.info.latlong' ), conditions.coord );
    
    $container.find( '.info' ).removeClass( 'hidden' );
    
    $body
        .removeClass( config.condition_classes )
        .addClass( classes_to_add.join( ' ' ) );

  }
  
  function ui_insert_forecasts( $container, $item_template, conditions ){

    // REMOVE  EXISTING FORECAST BOXES AND FILL WITH NEW
    $container.find( '.forecast_box' ).remove();
    
    if ( !conditions || !conditions.length )
      return;
    
    // FILL FORECAST BOXES WITH FOUR DAY FORECAST, NOON
    const target_time = config.forecast_time;
    let   target_day  = get_day_from_forecast_string( conditions[ 0 ].dt_txt, true );
    const days_in_mo  = get_days_in_month( now.getMonth() + 1, now.getFullYear() )
    let   found       = 0;
    let   target_str  = pad_string( 2, '0', 'left', target_day + '' );
    const f_limit     = Math.min( config.forecast_limit, conditions.length );
    let   c_counter   = 0;
    
    
    while ( found < f_limit ){
      
      // GET LIST OF FORECAST DAYS MATCHING DATE AND TIME
      let day_list = conditions
        .filter(( forecast ) => get_day_from_forecast_string( forecast.dt_txt ) === target_str )
        .filter(( forecast ) => get_time_from_forecast_string( forecast.dt_txt ) === target_time );
      
      // INSERT FORECAST UI
      if ( day_list.length ){
        
          let $forecast_ui = ui_build_forecast_box( day_list[0], $item_template.clone() );
        
          $forecast_ui.addClass( '_' + found );
        
          $container.append( $forecast_ui );
          found++;
        
          setTimeout( () => $forecast_ui.removeClass( 'hidden_bottom' ), 5 );
        
      }

      target_day++;
      c_counter++;
      
      if ( target_day > days_in_mo )
      {
        target_day = 1;
      }
      
      target_str = pad_string( 2, '0', 'left',  target_day + '' );;
      
      // MAKE SURE WE DON'T WIND UP IN AN INFINITE LOOP BASED ON WONKY DATA
      if ( c_counter > conditions.length )
        break;
      
    };

  }
  
  function ui_insert_location_data( $container, coord ){
    
    $container
      .find( '.lat' )
        .text( coord.lat.toFixed( 2 ) )
      .end()
      .find( '.lng' )
        .text( coord.lon.toFixed( 2 ) )
      .end();
    
  }
  
  function ui_insert_sunrise_data( $container, sunrise, sunset ){

    $container
      .find( '.sunrise' )
        .text( sunrise )
      .end()
      .find( '.sunset' )
        .text( sunset )
      .end();    
    
  }
  
  function ui_insert_temperature( $container, conditions, scale ){
    
    let temp;
    let scale_abbr;
    
    if ( scale.toLowerCase() === 'f' ){
      temp = convert_k_to_f( conditions.main.temp );
      scale_abbr = 'F';
    }
    else
    {
      temp = convert_k_to_c( conditions.main.temp );
      scale_abbr = 'C';
    }
    
    config.temp_scale = scale_abbr;

    // SET BODY CLASSES TO CONTROL VISIBILITY OF PROPER TEMPS IN FORECAST
    $body
        .removeClass( config.temperature_classes )
        .addClass( 'temp_scale_' + scale_abbr );
    
    $container    
      .find( 'span.temp' )
        .text( temp )
      .end()
      .find( 'span.scale' )
        .text( scale_abbr )
      .end();
    
  }
  
  function ui_insert_wind( $container, conditions ){
    
    const wind = conditions.wind || {};
    const wind_deg = ( conditions.wind.deg !== undefined ) ? wind.deg : '';
    const compass_direction = ( wind.deg ) ? convert_degree_to_compass( wind.deg ) : '';
    
    $container
      .find( '.wind_speed' )
        .text( wind.speed || '' )
      .end()
      .find( '.wind_direction' )
        .text( ( wind_deg ) ? wind.deg.toFixed(1) : '' )
      .end()
      .find( '.wind_compass_direction' )
        .text( compass_direction )
      .end();
    
  }

  function ui_remove_author_info( $author_info ){
    
    $author_info
      .one( 'transitionend', ( e ) => $author_info.remove() )
      .addClass( 'hidden_left');
    
  }
  
  function ui_remove_forecasts( fn_callback ){
    
    const $forecasts = $( '.forecast_box' );

    $forecasts
      .last()
        .on( 'transitionend', () => {

          $forecasts.remove();
      
          ( typeof fn_callback === 'function' ) &&
             fn_callback();

        })
      .end()
      .each( ( f, forecast ) => $( forecast ).addClass( 'hidden_bottom' ) );
    
  }
  
  function ui_show_author_info(){
    
    const $author_info = config.templates.author_info.clone();
    
    $author_info.addClass( 'hidden_left' );
    
    $body.append( $author_info );
    
    setTimeout( () => $author_info.removeClass( 'hidden_left' ), 25 );
    
    $author_info
      .one( 'click', ( e ) => {
        ui_remove_author_info( $author_info );
      });
    
  }
  
  function ui_update_for_timezone( location, data ){
    
    const classes_to_add = [];
    
    // CALCULATE MILLISECOND DATE OFFSET BASED ON LAT/LONG DATA
    const offset = get_time_offset( now, data.rawOffset, data.dstOffset );
    
    // CREATE NEW DATE USING CURRENT TIME AND CALCULATED OFFSET
    // DO SAME FOR SUNRISE AND SUNSET TIMES
    // THIS GIVES US DATES WITH TIMES CORRECT FOR THE LOCATION WE ARE
    // INTERESTED IN
    const their_date   = get_offset_date( now, offset );
    const sunrise_data = config.current_conditions.sunrise_data;
    const sunrise      = get_offset_date( sunrise_data.sunrise, offset );
    const sunset       = get_offset_date( sunrise_data.sunset, offset );
    const is_daylight  = is_it_daylight( their_date, sunrise, sunset );
    
    ui_insert_sunrise_data( $time, sunrise.toLocaleString( 'en-us',{ 'timezone': data.timeZoneId }).split( ', ')[1], sunset.toLocaleString( 'en-us',{ 'timezone': data.timeZoneId }).split( ', ')[1] );
    
    const is_dawn = is_within_time_range( their_date.getTime(), sunrise.getTime(), time_to_milliseconds( '01:00:00' ) );
    const is_dusk = is_within_time_range( their_date.getTime(), sunset.getTime(), time_to_milliseconds( '01:00:00' ) );
    
    ( is_daylight ) ?
        classes_to_add.push( 'day' ) :
        classes_to_add.push( 'night' );
    
    ( is_dawn ) &&
        classes_to_add.push( 'dawn' );

    ( is_dusk ) &&
        classes_to_add.push( 'dusk' );
    
    $body.addClass( classes_to_add.join( ' ') );
    
  }
  
  
  
  // START!
  ui_insert_content();
  
})();
              
            
!
999px

Console