<commit_before>google.load("visualization", "1", {packages:["geochart"]});
google.setOnLoadCallback(onGoogleLoaded);

function onGoogleLoaded() {

  var ALL_MARKETS = {"AD":"Andorra","AR":"Argentina","AU":"Australia","AT":"Austria","BE":"Belgium","BO":"Bolivia","BR":"Brazil","BG":"Bulgaria","CA":"Canada","CL":"Chile","CO":"Colombia","CR":"Costa Rica","CY":"Cyprus","CZ":"Czech Republic","DK":"Denmark","DO":"Dominican Republic","EC":"Ecuador","SV":"El Salvador","EE":"Estonia","FI":"Finland","FR":"France","DE":"Germany","GR":"Greece","GT":"Guatemala","HN":"Honduras","HK":"Hong Kong","HU":"Hungary","IS":"Iceland","IE":"Republic of Ireland","IT":"Italy","LV":"Latvia","LI":"Liechtenstein","LT":"Lithuania","LU":"Luxembourg","MY":"Malaysia","MT":"Malta","MX":"Mexico","MC":"Monaco","NL":"Netherlands","NZ":"New Zealand","NI":"Nicaragua","NO":"Norway","PA":"Panama","PY":"Paraguay","PE":"Peru","PH":"Philippines","PL":"Poland","PT":"Portugal","RO":"Romania","ES":"Spain","SG":"Singapore","SK":"Slovakia","SI":"Slovenia","SE":"Sweden","CH":"Switzerland","TW":"Taiwan","TR":"Turkey","GB":"United Kingdom","US":"United States","UY":"Uruguay"};
  var SPOTIFY_API = 'https://api.spotify.com/v1';

  var HIGHLIGHT_TIMEOUT = 100;

  var chart;

  var chartContainer = document.querySelector('#regions-map');
  var searchForm = document.querySelector('#search-form');
  var albumInfoBig = document.querySelector('#data-info');
  var infoContainer = document.querySelector('#regions-info');
  var exactSearchButton = document.querySelector('#exact-search-button');

  var albumInfoBigTemplate = document.querySelector('#template-album-info-big').innerHTML;
  var albumNotAvailableTemplate = document.querySelector('#template-album-not-available').innerHTML;
  var albumNotFoundTemplate = document.querySelector('#template-album-not-found').innerHTML;

  document.body.addEventListener('drop', handleDrop, false);
  document.body.addEventListener('dragover', handleDragOver, false);

  var timeoutHandler;
  infoContainer.addEventListener('mouseover', handleMouseover);
  infoContainer.addEventListener('mouseout', handleMouseout);

  exactSearchButton.checked = !getExactSearchEnabled();
  exactSearchButton.addEventListener('change', handleExactChange);
  searchForm.addEventListener('submit', handleFormSubmit);

  function handleFormSubmit(evt) {
    evt.preventDefault();
    var searchValue = evt.target[0].value;
    var uri = parseUri(searchValue);
    validateAndPerformSearch(uri);
  }

  function handleExactChange(evt) {
    setExactSearchEnabled(!evt.target.checked);
    var lastSearch = getLastSearch();
    if (lastSearch) {
      performSearch(lastSearch);
    }
  }

  function handleMouseover(evt) {
    clearTimeout(timeoutHandler);
    var self = this;
    timeoutHandler = setTimeout(function() {
      var path = evt.path;
      var current = self.dataset.active;
      for(var i = 0; i < path.length; i++) {
        if (path[i].dataset && path[i].dataset.albumid) {
          if (path[i].dataset.albumid != current) {
            current = path[i].dataset.albumid;
            self.dataset.active = current;
            highlight(current);
          }
          return;
        }
      }
      highlight(null);
      self.active = null;
    }, HIGHLIGHT_TIMEOUT);
  }

  function handleMouseout(evt) {
    clearTimeout(timeoutHandler);
    var self = this;
    timeoutHandler = setTimeout(function() {
      self.dataset.active = null;
      highlight(null);
    }, HIGHLIGHT_TIMEOUT);
  }

  function handleDragOver(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    evt.dataTransfer.dropEffect = 'copy';
  }

  function handleDrop(evt) {
    evt.stopPropagation();
    evt.preventDefault();

    var url = evt.dataTransfer.getData('text/plain');
    if (!url) return;
    if (url.indexOf('open.spotify.com') > -1) {
      var parsed = parseUri(url.replace(/https?:\/\/open.spotify.com\//, 'spotify/'), '/');
    } else {
      var parsed = parseUri(url);
    }

    validateAndPerformSearch(parsed);

    return false;
  }

  function parseUri(uri, delimiter) {
    var segments = uri.split(delimiter || ':');
    var id, type;
    if (segments[1] === 'user') {
      type = segments[3];
      id = segments[2] + ':' + segments[4];
    } else if (segments[1] === 'album') {
      type = segments[1];
      id = segments[2];
    }
    return {type: type, id: id};
  }

  function validateAndPerformSearch(parsedUri) {
    if (parsedUri.type == 'album') {
      document.body.classList.remove('invalid-search');
      performSearch(parsedUri.id);
    } else {
      document.body.classList.add('invalid-search');
      drawChart([]);
      albumInfoBig.innerHTML = '';
      infoContainer.innerHTML = '';
    }
  }

  function performSearch(id) {
    setLastSearch(id);
    infoContainer.innerHTML = '';

    d3.json(SPOTIFY_API + '/albums/' + id, function(error, album) {
      if (error) {
        console.error(error);
        return;
      }

      fillInfo(album);

      function albumsCallback(result, next) {
        if (next) {
          getAlbums(next, album.name, albumsCallback, result);
        } else {
          fillInfoData(result, album);
          fillChartData(result);
        }
      }

      var uri = SPOTIFY_API + '/artists/' + album.artists[0].id + '/albums?album_type=' + album.album_type;
      getAlbums(uri, album.name, albumsCallback, { markets: [], ids: [], count: {} });
    });
  }

  function getAlbums(uri, albumName, callback, result) {
    d3.json(uri, function(error, albums) {
      albums.items.forEach(function(el) {
        var elName = el.name.toLowerCase().replace(/[,.;:?!"]/g, '');
        var alName = albumName.toLowerCase().replace(/[,.;:?!"]/g, '');
        var condition = getExactSearchEnabled() ?
          el.name == alName : elName.indexOf(alName) == 0 || alName.indexOf(elName) == 0
        if (condition) {
          result.markets.push(el.available_markets || []);
          result.ids.push(el.id);
          if (el.available_markets) {
            el.available_markets.forEach(function(market) {
              result.count[market] = result.count[market] || 0;
              result.count[market]++;
            });
          }
        }
      });

      callback(result, albums.next);
    });
  }

  function fillInfo(info) {
    var data = {
      albumTitle: info.name,
      albumType: info.album_type,
      artistName: info.artists.map(function(el) { return el.name; }).join(', ')
    }
    var rendered = Mustache.render(albumInfoBigTemplate, data);
    albumInfoBig.innerHTML = rendered;
  }

  var currentDataset;

  function highlight(id) {
    if (currentDataset) {
      var markets = [];
      var dataset = currentDataset.map(function(el) {
        var row = el.slice(0);
        row.spid = el.spid;
        if (row.spid && row.spid == id) {
          markets.push(row[0])
          row[1] = 0.5;
        }
        return row;
      });
      drawChart(dataset.filter(function(el) {
        return markets.indexOf(el[0]) == -1 || el.spid == id;
      }));
    }
  }

  function getAlbumInfo(name, albums, id) {
    var fragment = document.createDocumentFragment();
    var title = document.createElement('h3');
    title.classList.add("row");
    title.classList.add("album-title");
    title.innerHTML = name;

    fragment.appendChild(title);

    albums.forEach(function(album) {
      var div = document.createElement('div');
      div.dataset.albumid = album.id;
      div.classList.add("album-info");
      div.classList.add("row");

      if (album.id == id) {
        div.classList.add("searched");
      }

      var explicit = false;
      for(var i = 0; i < album.tracks.items.length; i++) {
        if (album.tracks.items[i].explicit) {
          explicit = true;
          break;
        }
      }

      var copyrights = d3.map(album.copyrights, function(d) { return d.type });

      var html = '';
      html += ''
      html += '';
      html += '';
      html += '
';
      html += '
';
      html += album.tracks.items.length + ' tracks on ' + album.tracks.items.pop().disc_number + ' discs';
      html += '
';
      html += '
' + album.album_type + ' • ';
      html += album.release_date + '
';
      if (explicit) {
        html += '
Explicit
';
      }
      html += '
';
      html += '
' + album.available_markets.map(function(el) {
        return '' + el + '';
      }).join(' ') + '
';
      html += '
' + album.uri+ '
';
      if (copyrights.get('C')) {
        html += '
© ' + copyrights.get('C').text; + '
';
      }
      if (copyrights.get('P')) {
        html += '
℗ ' + copyrights.get('P').text + '
';
      }
      div.innerHTML = html;

      fragment.appendChild(div);
    });
    return fragment;
  }

  function fillInfoData(result, album) {
    var ids = result.ids;
    if (ids.length) {
      d3.json(SPOTIFY_API + '/albums?ids=' + ids, function(error, albums) {
        console.log("Full found albums", albums.albums);
        var nest = d3.nest()
          .key(function(d) { return d.name; })
          .sortKeys(function(a, b) {
            return a == album.name ? 1 : -1;
          })
          .sortValues(function(a, b){
            return a.id == album.id ? -1 : 1;
          })
          .entries(albums.albums);

        nest.forEach(function(el) {
          infoContainer.insertBefore(getAlbumInfo(el.key, el.values, album.id), infoContainer.firstChild);
        });

        if(!infoContainer.querySelector(".searched")) {
          exactMatchNotFound(album);
        }
      });
    } else {
      exactMatchNotFound(album);
    }
  }

  function exactMatchNotFound(album) {
    var html = Mustache.render(albumNotFoundTemplate, {
      albumApiLink: album.href,
      albumUri: album.uri
    })
    infoContainer.innerHTML = html + infoContainer.innerHTML;
  }

  function fillChartData(result) {
    var marketsList = result.markets;
    var ids = result.ids;
    var data = [];
    var allMarkets = Object.keys(ALL_MARKETS);

    marketsList.forEach(function(markets, i) {
      markets.forEach(function(market) {
        var index = allMarkets.indexOf(market);
        if (index > -1) {
          allMarkets.splice(allMarkets.indexOf(market), 1);
        }

        if (ALL_MARKETS[market]) {
          var el = [ALL_MARKETS[market], result.count[market], result.count[market] + ' versions available'];
          el.spid = ids[i];
          data.push(el);
        } else {
          console.log('Not in available markets', market);
        }
      });
    });

    if (allMarkets.length) {
      console.log("Not available in: " + allMarkets);
      var html = Mustache.render(albumNotAvailableTemplate, {
        markets: allMarkets.map(function(el) {
          return { code: el, name: ALL_MARKETS[el]}
        })
      });
      infoContainer.innerHTML += html;
    }

    allMarkets.forEach(function(market) {
      data.push([ALL_MARKETS[market], 0, 'Not available']);
    });

    console.log("Chart data", data);
    currentDataset = data;
    drawChart(data);
  }

  function drawChart(markets) {
    var chartData = new google.visualization.DataTable();
    chartData.addColumn('string', 'Country');
    chartData.addColumn('number', 'Available');
    chartData.addColumn({type: 'string', role: 'tooltip'});
    chartData.addRows(markets);

    var max = d3.max(currentDataset, function(el) { return el[1] });

    if (max < 1) max = 1;

    var options = {
      backgroundColor: 'transparent',
      datalessRegionColor: '#2e2f33',
      keepAspectRatio: true,
      colorAxis: {
        minValue: 0,
        colors: ['#8f2600', '#bdaa00', '#4B6601', '#B4D612'],
        values: [0, 0.5, 1, max]
      },
      legend: 'none',
      tooltip: {
        showColorCode: false
      },
      enableRegionInteractivity: true,
      animation: {
        duration: 1000,
        easing: 'out',
      }
    };

    chart.draw(chartData, options);
  }

  function getLastSearch() {
    return window.location.hash.substring(1) || localStorage.getItem('lastSearch');
  }

  function setLastSearch(id) {
    localStorage.setItem('lastSearch', id);
    window.location.hash = id;
  }

  function setExactSearchEnabled(mode) {
    localStorage.setItem('exactSearch', mode);
  }

  function getExactSearchEnabled() {
    return localStorage.getItem('exactSearch') === 'true';
  }

  chart = new google.visualization.GeoChart(chartContainer);

  performSearch(getLastSearch() || "18qY7zpuNqeXNGywRysjxx");
}
<commit_msg>Show album availability even if artist search doesnt work correctly<commit_after>google.load("visualization", "1", {packages:["geochart"]});
google.setOnLoadCallback(onGoogleLoaded);

function onGoogleLoaded() {

  var ALL_MARKETS = {"AD":"Andorra","AR":"Argentina","AU":"Australia","AT":"Austria","BE":"Belgium","BO":"Bolivia","BR":"Brazil","BG":"Bulgaria","CA":"Canada","CL":"Chile","CO":"Colombia","CR":"Costa Rica","CY":"Cyprus","CZ":"Czech Republic","DK":"Denmark","DO":"Dominican Republic","EC":"Ecuador","SV":"El Salvador","EE":"Estonia","FI":"Finland","FR":"France","DE":"Germany","GR":"Greece","GT":"Guatemala","HN":"Honduras","HK":"Hong Kong","HU":"Hungary","IS":"Iceland","IE":"Republic of Ireland","IT":"Italy","LV":"Latvia","LI":"Liechtenstein","LT":"Lithuania","LU":"Luxembourg","MY":"Malaysia","MT":"Malta","MX":"Mexico","MC":"Monaco","NL":"Netherlands","NZ":"New Zealand","NI":"Nicaragua","NO":"Norway","PA":"Panama","PY":"Paraguay","PE":"Peru","PH":"Philippines","PL":"Poland","PT":"Portugal","RO":"Romania","ES":"Spain","SG":"Singapore","SK":"Slovakia","SI":"Slovenia","SE":"Sweden","CH":"Switzerland","TW":"Taiwan","TR":"Turkey","GB":"United Kingdom","US":"United States","UY":"Uruguay"};
  var SPOTIFY_API = 'https://api.spotify.com/v1';

  var HIGHLIGHT_TIMEOUT = 100;

  var chart;

  var chartContainer = document.querySelector('#regions-map');
  var searchForm = document.querySelector('#search-form');
  var albumInfoBig = document.querySelector('#data-info');
  var infoContainer = document.querySelector('#regions-info');
  var exactSearchButton = document.querySelector('#exact-search-button');

  var albumInfoBigTemplate = document.querySelector('#template-album-info-big').innerHTML;
  var albumNotAvailableTemplate = document.querySelector('#template-album-not-available').innerHTML;
  var albumNotFoundTemplate = document.querySelector('#template-album-not-found').innerHTML;

  document.body.addEventListener('drop', handleDrop, false);
  document.body.addEventListener('dragover', handleDragOver, false);

  var timeoutHandler;
  infoContainer.addEventListener('mouseover', handleMouseover);
  infoContainer.addEventListener('mouseout', handleMouseout);

  exactSearchButton.checked = !getExactSearchEnabled();
  exactSearchButton.addEventListener('change', handleExactChange);
  searchForm.addEventListener('submit', handleFormSubmit);

  function handleFormSubmit(evt) {
    evt.preventDefault();
    var searchValue = evt.target[0].value;
    var uri = parseUri(searchValue);
    validateAndPerformSearch(uri);
  }

  function handleExactChange(evt) {
    setExactSearchEnabled(!evt.target.checked);
    var lastSearch = getLastSearch();
    if (lastSearch) {
      performSearch(lastSearch);
    }
  }

  function handleMouseover(evt) {
    clearTimeout(timeoutHandler);
    var self = this;
    timeoutHandler = setTimeout(function() {
      var path = evt.path;
      var current = self.dataset.active;
      for(var i = 0; i < path.length; i++) {
        if (path[i].dataset && path[i].dataset.albumid) {
          if (path[i].dataset.albumid != current) {
            current = path[i].dataset.albumid;
            self.dataset.active = current;
            highlight(current);
          }
          return;
        }
      }
      highlight(null);
      self.active = null;
    }, HIGHLIGHT_TIMEOUT);
  }

  function handleMouseout(evt) {
    clearTimeout(timeoutHandler);
    var self = this;
    timeoutHandler = setTimeout(function() {
      self.dataset.active = null;
      highlight(null);
    }, HIGHLIGHT_TIMEOUT);
  }

  function handleDragOver(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    evt.dataTransfer.dropEffect = 'copy';
  }

  function handleDrop(evt) {
    evt.stopPropagation();
    evt.preventDefault();

    var url = evt.dataTransfer.getData('text/plain');
    if (!url) return;
    if (url.indexOf('open.spotify.com') > -1) {
      var parsed = parseUri(url.replace(/https?:\/\/open.spotify.com\//, 'spotify/'), '/');
    } else {
      var parsed = parseUri(url);
    }

    validateAndPerformSearch(parsed);

    return false;
  }

  function parseUri(uri, delimiter) {
    var segments = uri.split(delimiter || ':');
    var id, type;
    if (segments[1] === 'user') {
      type = segments[3];
      id = segments[2] + ':' + segments[4];
    } else if (segments[1] === 'album') {
      type = segments[1];
      id = segments[2];
    }
    return {type: type, id: id};
  }

  function validateAndPerformSearch(parsedUri) {
    if (parsedUri.type == 'album') {
      document.body.classList.remove('invalid-search');
      performSearch(parsedUri.id);
    } else {
      document.body.classList.add('invalid-search');
      drawChart([]);
      albumInfoBig.innerHTML = '';
      infoContainer.innerHTML = '';
    }
  }

  function performSearch(id) {
    setLastSearch(id);
    infoContainer.innerHTML = '';

    d3.json(SPOTIFY_API + '/albums/' + id, function(error, album) {
      if (error) {
        console.error(error);
        return;
      }

      fillInfo(album);

      function albumsCallback(result, next) {
        if (next) {
          getAlbums(next, album.name, albumsCallback, result);
        } else {
          fillInfoData(result, album);
          fillChartData(result);
        }
      }

      var uri = SPOTIFY_API + '/artists/' + album.artists[0].id + '/albums?album_type=' + album.album_type;

      var markets = [];
      var ids = [];
      var count = {};
      if (album.available_markets.length) {
        markets.push(album.available_markets);
        ids.push(album.id);
        album.available_markets.forEach(function(market) {
          count[market] = 1;
        });
      }

      getAlbums(uri, album.name, albumsCallback, { markets: markets, ids: ids, count: count });
    });
  }

  function getAlbums(uri, albumName, callback, result) {
    d3.json(uri, function(error, albums) {
      albums.items.forEach(function(el) {
        var elName = el.name.toLowerCase().replace(/[,.;:?!"]/g, '');
        var alName = albumName.toLowerCase().replace(/[,.;:?!"]/g, '');
        var condition = getExactSearchEnabled() ?
          el.name == alName : elName.indexOf(alName) == 0 || alName.indexOf(elName) == 0
        if (condition && result.ids.indexOf(el.id) == -1) {
          result.ids.push(el.id);
          result.markets.push(el.available_markets || []);
          if (el.available_markets) {
            el.available_markets.forEach(function(market) {
              result.count[market] = result.count[market] || 0;
              result.count[market]++;
            });
          }
        }
      });

      callback(result, albums.next);
    });
  }

  function fillInfo(info) {
    var data = {
      albumTitle: info.name,
      albumType: info.album_type,
      artistName: info.artists.map(function(el) { return el.name; }).join(', ')
    }
    var rendered = Mustache.render(albumInfoBigTemplate, data);
    albumInfoBig.innerHTML = rendered;
  }

  var currentDataset;

  function highlight(id) {
    if (currentDataset) {
      var markets = [];
      var dataset = currentDataset.map(function(el) {
        var row = el.slice(0);
        row.spid = el.spid;
        if (row.spid && row.spid == id) {
          markets.push(row[0])
          row[1] = 0.5;
        }
        return row;
      });
      drawChart(dataset.filter(function(el) {
        return markets.indexOf(el[0]) == -1 || el.spid == id;
      }));
    }
  }

  function getAlbumInfo(name, albums, id) {
    var fragment = document.createDocumentFragment();
    var title = document.createElement('h3');
    title.classList.add("row");
    title.classList.add("album-title");
    title.innerHTML = name;

    fragment.appendChild(title);

    albums.forEach(function(album) {
      var div = document.createElement('div');
      div.dataset.albumid = album.id;
      div.classList.add("album-info");
      div.classList.add("row");

      if (album.id == id) {
        div.classList.add("searched");
      }

      var explicit = false;
      for(var i = 0; i < album.tracks.items.length; i++) {
        if (album.tracks.items[i].explicit) {
          explicit = true;
          break;
        }
      }

      var copyrights = d3.map(album.copyrights, function(d) { return d.type });

      var html = '';
      html += ''
      html += '';
      html += '';
      html += '
';
      html += '
';
      html += album.tracks.items.length + ' tracks on ' + album.tracks.items.pop().disc_number + ' discs';
      html += '
';
      html += '
' + album.album_type + ' • ';
      html += album.release_date + '
';
      if (explicit) {
        html += '
Explicit
';
      }
      html += '
';
      html += '
' + album.available_markets.map(function(el) {
        return '' + el + '';
      }).join(' ') + '
';
      html += '
' + album.uri+ '
';
      if (copyrights.get('C')) {
        html += '
© ' + copyrights.get('C').text; + '
';
      }
      if (copyrights.get('P')) {
        html += '
℗ ' + copyrights.get('P').text + '
';
      }
      div.innerHTML = html;

      fragment.appendChild(div);
    });
    return fragment;
  }

  function fillInfoData(result, album) {
    var ids = result.ids;
    if (ids.length) {
      d3.json(SPOTIFY_API + '/albums?ids=' + ids, function(error, albums) {
        console.log("Full found albums", albums.albums);
        var nest = d3.nest()
          .key(function(d) { return d.name; })
          .sortKeys(function(a, b) {
            return a == album.name ? 1 : -1;
          })
          .sortValues(function(a, b){
            return a.id == album.id ? -1 : 1;
          })
          .entries(albums.albums);

        nest.forEach(function(el) {
          infoContainer.insertBefore(getAlbumInfo(el.key, el.values, album.id), infoContainer.firstChild);
        });

        if(!infoContainer.querySelector(".searched")) {
          exactMatchNotFound(album);
        }
      });
    } else {
      exactMatchNotFound(album);
    }
  }

  function exactMatchNotFound(album) {
    var html = Mustache.render(albumNotFoundTemplate, {
      albumApiLink: album.href,
      albumUri: album.uri
    })
    infoContainer.innerHTML = html + infoContainer.innerHTML;
  }

  function fillChartData(result) {
    var marketsList = result.markets;
    var ids = result.ids;
    var data = [];
    var allMarkets = Object.keys(ALL_MARKETS);

    marketsList.forEach(function(markets, i) {
      markets.forEach(function(market) {
        var index = allMarkets.indexOf(market);
        if (index > -1) {
          allMarkets.splice(allMarkets.indexOf(market), 1);
        }

        var name = market;
        if (ALL_MARKETS[market]) {
          name = ALL_MARKETS[market];
        } else {
          console.log('Not in available markets', market);
        }

        var el = [name, result.count[market], result.count[market] + ' versions available'];
        el.spid = ids[i];
        data.push(el);
      });
    });

    if (allMarkets.length) {
      console.log("Not available in: " + allMarkets);
      var html = Mustache.render(albumNotAvailableTemplate, {
        markets: allMarkets.map(function(el) {
          return { code: el, name: ALL_MARKETS[el]}
        })
      });
      infoContainer.innerHTML += html;
    }

    allMarkets.forEach(function(market) {
      data.push([ALL_MARKETS[market], 0, 'Not available']);
    });

    console.log("Chart data", data);
    currentDataset = data;
    drawChart(data);
  }

  function drawChart(markets) {
    var chartData = new google.visualization.DataTable();
    chartData.addColumn('string', 'Country');
    chartData.addColumn('number', 'Available');
    chartData.addColumn({type: 'string', role: 'tooltip'});
    chartData.addRows(markets);

    var max = d3.max(currentDataset, function(el) { return el[1] });

    if (max < 1) max = 1;

    var options = {
      backgroundColor: 'transparent',
      datalessRegionColor: '#2e2f33',
      keepAspectRatio: true,
      colorAxis: {
        minValue: 0,
        colors: ['#8f2600', '#bdaa00', '#4B6601', '#B4D612'],
        values: [0, 0.5, 1, max]
      },
      legend: 'none',
      tooltip: {
        showColorCode: false
      },
      enableRegionInteractivity: true,
      animation: {
        duration: 1000,
        easing: 'out',
      }
    };

    chart.draw(chartData, options);
  }

  function getLastSearch() {
    return window.location.hash.substring(1) || localStorage.getItem('lastSearch');
  }

  function setLastSearch(id) {
    localStorage.setItem('lastSearch', id);
    window.location.hash = id;
  }

  function setExactSearchEnabled(mode) {
    localStorage.setItem('exactSearch', mode);
  }

  function getExactSearchEnabled() {
    return localStorage.getItem('exactSearch') === 'true';
  }

  chart = new google.visualization.GeoChart(chartContainer);

  performSearch(getLastSearch() || "18qY7zpuNqeXNGywRysjxx");
}
<|endoftext|>


<commit_before>var SECTION = document.getElementsByClassName("js-section");
var back = document.getElementById("back");
var cancel = document.getElementById("cancel");

var lang = "it";
var form_stop;
var to_stop;
var matching_busstops = new Array(5);
var busstops = $.getJSON( "js/busstops.json", function(data) {
		autocom(0);
	});
if (navigator.language === "de") {
		lang = "de";
}
clearPage(1);
hideIcon(back);
hideIcon(cancel);

function clearPage(startSection) {
	var i = startSection;
	while (i < SECTION.length) {
		SECTION[i].style.display = "none";
		i++;
	}
}

function autocom(current_section) {
	var i;
	var children = SECTION[current_section].children;
	var input_string = children[1].value;

	i = 2
	while (i < children.length) {
			children[i].children[0].innerHTML = "";
			children[i].children[1].innerHTML = "";
			i++;
	}
	if (input_string != "") {
	children[2].children[1].innerHTML = "Couldn't find any matches...";
	children[2].children[1].className += " no-matches";
	input_string = input_string.split(" ");
	data = busstops.responseJSON;
	i = 2;
	data[lang].every( function (element, index, array) {
			var res = input_string.every( function (item, index, array) {
					var pattern = new RegExp(item, "i");
					var found_match = element.label.match(pattern);

					if (found_match != null) {
							return true;
					}
					else{
							return false;
					}

			});

			if (res && i < children.length) {

					matching_busstops[i-2] = element;
					children[i].children[0].innerHTML = element.name+", ";
					children[i].children[1].innerHTML = element.city;
					children[2].children[1].className = "line-small";
					i++;
			}
			if (i >= children.length) {
					return false;
			}
			else{
					return true;
			}

});
}
}
function selectBusstop(current_section, div_number) {
	SECTION[current_section].children[0].children[1].innerHTML = matching_busstops[div_number].name + ", ";
	SECTION[current_section].children[0].children[2].innerHTML = matching_busstops[div_number].city;
	SECTION[current_section].children[1].value = "";
	makeBlank(current_section);
	unBlank(current_section + 1);
	autocom(current_section);
	if (current_section === 0) {
			from_stop = matching_busstops[div_number].id;
	}
	if (current_section === 1) {
			to_stop = matching_busstops[div_number].id;
			autoSetTime();
	}
}
function makeBlank(current_section) {
	var i = 1;
	while (i < SECTION[current_section].children.length) {
			SECTION[current_section].children[i].style.display = "none";
			i++;
	}
	SECTION[current_section].className = "js-section";
}
function unBlank(current_section) {
	var i = 0;
	while (i < SECTION.length) {
			makeBlank(i);
			i++;
	}
	SECTION[current_section].style.display = "block";
	i = 0;
	while (i < SECTION[current_section].children.length) {
			SECTION[current_section].children[i].style.display = "block";
			i++;
	}
	if (SECTION[current_section].children[1] != null)
		SECTION[current_section].children[1].focus();
	addClass(current_section);
}
function autoSetTime() {
	var currentdate = new Date();
	console.log(currentdate);
	//SECTION[2].children[1].value = currentdate.getDate() + "/" + (currentdate.getMonth()+1)  + "/"  + currentdate.getFullYear();
  //SECTION[2].children[2].value = currentdate.getHours() + ":" + currentdate.getMinutes();

	SECTION[2].children[1].value = "27/02/2014";
  SECTION[2].children[2].value = "13:20";
	selectTime(2);
}
function selectTime(current_section) {
		var date_element = SECTION[current_section].children[1];
		var date = date_element.value;
		var time_element = SECTION[current_section].children[2];
		var time = time_element.value;

		if (date_element.validity.valid && time_element.validity.valid){
			SECTION[current_section].children[0].children[1].innerHTML = date + ", ";
			SECTION[current_section].children[0].children[2].innerHTML = time;
			makeBlank(current_section);
			getRoute(date,time);
			time_element.value = "";
			date_element.value = "";
		}
}
function addClass(current_section) {
	SECTION[current_section].className += " active-section";
}
function removeClass(current_section) {
	SECTION[current_section].className = "js-section";
}
function getRoute(date, time) {
	date = date.replace(/\//g, ":");
	date = date.replace(/\./g, ":");
	date = date.split(":");
	time = time.replace(":", "");
	count_date = date[2].split("");
	unBlank(3);
	if (count_date.length == 2) {
		date[2] = "20" + date[2];
	}
	var url = "http://html5.sasabus.org/backend/sasabusdb/calcRoute?";
	url = url + "startBusStationId=" + from_stop;
	url = url + "&endBusStationId=" + to_stop;
	url = url + "&yyyymmddhhmm=" + date[2] + date[1] + date[0] + time;
	var results = 3;
	var requestId;
	$.ajax({
		dataType: "jsonp",
		jsonpCallback: "Callback",
		url: url,
	 	success: function(data) {
			console.log(data);
			loadConnection(data, 0);

			requestId = data.ConResCtxt[0];
			console.log(requestId);

			requestId = requestId.split("#")[0];
			nextData(data, requestId, 1);
		}
	});
}
function nextData(data, requestId, count) {
	if (count < 5) {
		console.log(requestId);

		var nextUrl = "http://html5.sasabus.org/backend/sasabusdb/nextRoute?context=";
		nextUrl = nextUrl + requestId;
		nextUrl = nextUrl + "%23";
		nextUrl = nextUrl + count;

		console.log(nextUrl);
		$.ajax({
			dataType: "jsonp",
			jsonpCallback: "Callback",
			url: nextUrl,
		 	success: function(data) {
				console.log(data);
				loadConnection(data, count);
				console.log(requestId);
				nextData(data, requestId, parseInt(count) + 1);
			}
		});
	}
}
function loadConnection(data, resultPointer) {
	var con = data.ConnectionList.Connection[0].Overview;
	var arr_time = con.Arrival.BasicStop.Arr.Time;
	var dep_time = con.Departure.BasicStop.Dep.Time;
	var duration = con.Duration.Time;
	var transfers = con.Transfers;
	var overview_section = SECTION[3].children[0];

	console.log(SECTION[3].children[1]);
	arr_time = arr_time.split("d");
	arr_time = arr_time[1].split(":");
	arr_time = arr_time[0] + ":" + arr_time[1];
	dep_time = dep_time.split("d");
	dep_time = dep_time[1].split(":");
	dep_time = dep_time[0] + ":" + dep_time[1];
	duration = duration.split("d");
	duration = duration[1].split(":");
	duration = duration[0] + ":" + duration[1];

	if (transfers == 0)
		transfers = "no transfers";
	if (transfers == 1)
		transfers = "1 transfer";
	if (transfers > 1)
		transfers += " transfers ";

	overview_section.children[resultPointer].children[0].innerHTML = dep_time + " - " + arr_time;
	overview_section.children[resultPointer].children[1].innerHTML = duration + ", " + transfers;

	hideSpinner();
}
function hideSpinner() {
	SECTION[3].children[1].style.display = "none";
}
function hideIcon(icon) {
	icon.style.display = "none";
}
function showIcon(icon) {
	icon.style.display = "block";
}
function showDetails(resultNumber) {
	clearPage(0);
	unBlank(4);
	showIcon("back");
}
function goBack() {
	clearPage(0);
	unBlank(0);
	unBlank(1);
	unBlank(2);
	unBlank(3);
	hideBackButton();
	hideSpinner();
}
<commit_msg>[minor][fix] back button behaviour<commit_after>var SECTION = document.getElementsByClassName("js-section");
var back = document.getElementById("back");
var cancel = document.getElementById("cancel");

var lang = "it";
var form_stop;
var to_stop;
var matching_busstops = new Array(5);
var busstops = $.getJSON( "js/busstops.json", function(data) {
		autocom(0);
	});
if (navigator.language === "de") {
		lang = "de";
}
clearPage(1);
hideIcon(back);
hideIcon(cancel);

function clearPage(startSection) {
	var i = startSection;
	while (i < SECTION.length) {
		SECTION[i].style.display = "none";
		i++;
	}
}

function autocom(current_section) {
	var i;
	var children = SECTION[current_section].children;
	var input_string = children[1].value;

	i = 2
	while (i < children.length) {
			children[i].children[0].innerHTML = "";
			children[i].children[1].innerHTML = "";
			i++;
	}
	if (input_string != "") {
	children[2].children[1].innerHTML = "Couldn't find any matches...";
	children[2].children[1].className += " no-matches";
	input_string = input_string.split(" ");
	data = busstops.responseJSON;
	i = 2;
	data[lang].every( function (element, index, array) {
			var res = input_string.every( function (item, index, array) {
					var pattern = new RegExp(item, "i");
					var found_match = element.label.match(pattern);

					if (found_match != null) {
							return true;
					}
					else{
							return false;
					}

			});

			if (res && i < children.length) {

					matching_busstops[i-2] = element;
					children[i].children[0].innerHTML = element.name+", ";
					children[i].children[1].innerHTML = element.city;
					children[2].children[1].className = "line-small";
					i++;
			}
			if (i >= children.length) {
					return false;
			}
			else{
					return true;
			}

});
}
}
function selectBusstop(current_section, div_number) {
	SECTION[current_section].children[0].children[1].innerHTML = matching_busstops[div_number].name + ", ";
	SECTION[current_section].children[0].children[2].innerHTML = matching_busstops[div_number].city;
	SECTION[current_section].children[1].value = "";
	makeBlank(current_section);
	unBlank(current_section + 1);
	autocom(current_section);
	if (current_section === 0) {
			from_stop = matching_busstops[div_number].id;
	}
	if (current_section === 1) {
			to_stop = matching_busstops[div_number].id;
			autoSetTime();
	}
}
function makeBlank(current_section) {
	var i = 1;
	while (i < SECTION[current_section].children.length) {
			SECTION[current_section].children[i].style.display = "none";
			i++;
	}
	SECTION[current_section].className = "js-section";
}
function unBlank(current_section) {
	var i = 0;
	while (i < SECTION.length) {
			makeBlank(i);
			i++;
	}
	SECTION[current_section].style.display = "block";
	i = 0;
	while (i < SECTION[current_section].children.length) {
			SECTION[current_section].children[i].style.display = "block";
			i++;
	}
	if (SECTION[current_section].children[1] != null)
		SECTION[current_section].children[1].focus();
	addClass(current_section);
}
function autoSetTime() {
	var currentdate = new Date();
	console.log(currentdate);
	//SECTION[2].children[1].value = currentdate.getDate() + "/" + (currentdate.getMonth()+1)  + "/"  + currentdate.getFullYear();
  //SECTION[2].children[2].value = currentdate.getHours() + ":" + currentdate.getMinutes();

	SECTION[2].children[1].value = "27/02/2014";
  SECTION[2].children[2].value = "13:20";
	selectTime(2);
}
function selectTime(current_section) {
		var date_element = SECTION[current_section].children[1];
		var date = date_element.value;
		var time_element = SECTION[current_section].children[2];
		var time = time_element.value;

		if (date_element.validity.valid && time_element.validity.valid){
			SECTION[current_section].children[0].children[1].innerHTML = date + ", ";
			SECTION[current_section].children[0].children[2].innerHTML = time;
			makeBlank(current_section);
			getRoute(date,time);
			time_element.value = "";
			date_element.value = "";
		}
}
function addClass(current_section) {
	SECTION[current_section].className += " active-section";
}
function removeClass(current_section) {
	SECTION[current_section].className = "js-section";
}
function getRoute(date, time) {
	date = date.replace(/\//g, ":");
	date = date.replace(/\./g, ":");
	date = date.split(":");
	time = time.replace(":", "");
	count_date = date[2].split("");
	unBlank(3);
	if (count_date.length == 2) {
		date[2] = "20" + date[2];
	}
	var url = "http://html5.sasabus.org/backend/sasabusdb/calcRoute?";
	url = url + "startBusStationId=" + from_stop;
	url = url + "&endBusStationId=" + to_stop;
	url = url + "&yyyymmddhhmm=" + date[2] + date[1] + date[0] + time;
	var results = 3;
	var requestId;
	$.ajax({
		dataType: "jsonp",
		jsonpCallback: "Callback",
		url: url,
	 	success: function(data) {
			console.log(data);
			loadConnection(data, 0);

			requestId = data.ConResCtxt[0];
			console.log(requestId);

			requestId = requestId.split("#")[0];
			nextData(data, requestId, 1);
		}
	});
}
function nextData(data, requestId, count) {
	if (count < 5) {
		console.log(requestId);

		var nextUrl = "http://html5.sasabus.org/backend/sasabusdb/nextRoute?context=";
		nextUrl = nextUrl + requestId;
		nextUrl = nextUrl + "%23";
		nextUrl = nextUrl + count;

		console.log(nextUrl);
		$.ajax({
			dataType: "jsonp",
			jsonpCallback: "Callback",
			url: nextUrl,
		 	success: function(data) {
				console.log(data);
				loadConnection(data, count);
				console.log(requestId);
				nextData(data, requestId, parseInt(count) + 1);
			}
		});
	}
}
function loadConnection(data, resultPointer) {
	var con = data.ConnectionList.Connection[0].Overview;
	var arr_time = con.Arrival.BasicStop.Arr.Time;
	var dep_time = con.Departure.BasicStop.Dep.Time;
	var duration = con.Duration.Time;
	var transfers = con.Transfers;
	var overview_section = SECTION[3].children[0];

	console.log(SECTION[3].children[1]);
	arr_time = arr_time.split("d");
	arr_time = arr_time[1].split(":");
	arr_time = arr_time[0] + ":" + arr_time[1];
	dep_time = dep_time.split("d");
	dep_time = dep_time[1].split(":");
	dep_time = dep_time[0] + ":" + dep_time[1];
	duration = duration.split("d");
	duration = duration[1].split(":");
	duration = duration[0] + ":" + duration[1];

	if (transfers == 0)
		transfers = "no transfers";
	if (transfers == 1)
		transfers = "1 transfer";
	if (transfers > 1)
		transfers += " transfers ";

	overview_section.children[resultPointer].children[0].innerHTML = dep_time + " - " + arr_time;
	overview_section.children[resultPointer].children[1].innerHTML = duration + ", " + transfers;

	hideSpinner();
}
function hideSpinner() {
	SECTION[3].children[1].style.display = "none";
}
function hideIcon(icon) {
	icon.style.display = "none";
}
function showIcon(icon) {
	icon.style.display = "block";
}
function showDetails(resultNumber) {
	clearPage(0);
	unBlank(4);
	showIcon(back);
}
function goBack() {
	clearPage(0);
	unBlank(0);
	unBlank(1);
	unBlank(2);
	unBlank(3);
	hideIcon(back);
	hideSpinner();
}
<|endoftext|>


<commit_before>/**
 * Author: Olaolu Olawuyi

 * Date Created: 20/08/2015

 * Last Modified: 27/02/2016

 * Twitter: @whizkydee, @webtwic

 * Github: https://github.com/webtwic/webtwic.github.io

*/

var Webtwic = Webtwic || {};

var browser = bowser;

var test_canvas = document.createElement("canvas");
var canvascheck = (test_canvas.getContext) ? true : false;

Webtwic = {
	// Basic Information about Webtwic
	name: "Webtwic",
	description: "A community for coding and tech tweaks where beginners and experts can learn.",
	repo: "https://github.com/whizkydee/whizkydee.github.io",
	author: "Olaolu Olawuyi",
	version: 1.07,

	// Start main functions for the object

	// Function to add browser name and version to body class
	_showBrowser: function( b ) {
		$("body").addClass(b + " " + b + parseInt(browser.version));
	},

	// Function to set attributes and values to elements
	_setAttr: function( elem, name, val ) {
		$(elem, this).attr(name, val);
	},

	// Function to push down .site-content
	_adjustSiteContent: function() {
		if ( $("body").hasClass("default-body") ) {
			$(".top-stripe").addClass("adjustedMargin");
			$("#header .logo").addClass("adjustedTop");
			$(".main-menu").addClass("adjustedMargin");
			$("#header").addClass("adjustSiteContent");
		} else if ( $("body").hasClass("secondary-body") ) {
			$(".site-content").addClass("adjustSiteContent");
			$(".secondary-header").addClass("adjustedMargin");
		}
	},

	// Function to push up .site-content to default state
	_undoSiteAdjust: function() {
		if ( $("body").hasClass("default-body") ) {
			$(".top-stripe").removeClass("adjustedMargin");
			$("#header .logo").removeClass("adjustedTop");
			$(".main-menu").removeClass("adjustedMargin");
			$("#header").removeClass("adjustSiteContent");
		} else if ( $("body").hasClass("secondary-body") ) {
			$(".secondary-header").removeClass("adjustedMargin");
		}
	},

	// Function to show Notifications before header
	_showNotif: function( text ) {
		text = (typeof text == "undefined") ? notif_text : text;
		Webtwic._adjustSiteContent();
		$("body").prepend(
			"
"+text+"
"
		);

		$(".close-button").on("click", function() {
			Webtwic._undoReset();
		});
	},

	// Function to hide Notifications
	_hideNotif: function() {
		$("#notifBanner").removeClass("notif_vis");
	},

	_resetSite: function() {
		Webtwic._showNotif();
		Webtwic._adjustSiteContent();
	},

	_undoReset: function() {
		Webtwic._hideNotif();
		Webtwic._undoSiteAdjust();
	},

	// Function to launch modal

	_launchModal: function( w, h, r, p, c, e, b ) {
		this.width = w;
	}

}, WBT = Webtwic,
notif_text = "Some features which affect the functionality of webtwic are disabled in your browser. Please try refreshing the page or get a better browser. ";

// Detect when the document is ready

jQuery(document).ready(function() {
	// Test for HTML5 support
	if ( window.Modernizr ) {
		if ( !Modernizr.canvas ) {
			Webtwic._showNotif ( "Oops. Looks like your browser doesn't support HTML5. Please get a better browser  for an awesome experience.");
		} else {
			// Do nothing.
		}
	} else if ( !window.Modernizr ) {
		if ( canvascheck == false ) {
			Webtwic._showNotif ( "Oops. Looks like your browser doesn't support HTML5. Please get a better browser  for an awesome experience.");
		} else {
			// Do nothing.
		}
	} else {
		// Do nothing.
	}

	// Define Variables
	var $to_top = $("a.to-top"),
	is_toggle_active = $(".hamburger").hasClass("is_active"),
	height = 200;

	// Performance Fixes

	// Start browser detection

	browser.ie = browser.msie;

	if ( browser.webkit ) {
		$("body").addClass("webkit");
	}
	if ( browser.chrome ) {
		Webtwic._showBrowser("chrome");
	}
	if ( browser.msedge ) {
		Webtwic._showBrowser("msedge");
	}
	if ( browser.firefox ) {
		Webtwic._showBrowser("firefox");
	}
	if ( browser.msie ) {
		Webtwic._showBrowser("ie");
	}
	if ( browser.safari ) {
		Webtwic._showBrowser("safari");
	}
	if ( browser.opera ) {
		Webtwic._showBrowser("opera");
	}

	/*
		TODO: Rebuild Performance fixes for attributes
		See history of Performance fixes.
		Also, check StackOverflow.
		See Issue #12
	*/

	if ( window.Modernizr ) {
		if ( !Modernizr.flexbox || !Modernizr.inlinesvg || !Modernizr.svg || !Modernizr.svgclippaths || !Modernizr.fontface || !Modernizr.boxshadow || !Modernizr.borderradius || !Modernizr.csstransforms ) {
			Webtwic._showNotif();
		} else {
			// Do nothing.
		}
	} else {
		// Do nothing.
	}

	// Start Main Page

	$("nav li ul.drop-nav").hide().removeClass("dropNavFallback");

	if ( $(window).width() > 860 ) {
		$("nav li.dropdown").hover(function() {
			$("ul.drop-nav", this).stop().slideDown("fast");
		}, function() {
			$("ul.drop-nav", this).stop().slideUp("fast");
		});
	}

	$(".active-item").append(
		"<svg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><path d='M 16.682,19.674c 0.010-0.012, 0.014-0.028, 0.024-0.040l 6.982-7.714c 0.39-0.434, 0.39-1.138,0-1.572 c-0.004-0.004-0.008-0.006-0.012-0.008C 23.496,10.13, 23.244,10, 22.964,10L 8.998,10 c-0.286,0-0.54,0.138-0.722,0.352L 8.272,10.348 c-0.39,0.434-0.39,1.138,0,1.572l 6.998,7.754C 15.66,20.108, 16.292,20.108, 16.682,19.674z'></path></svg>"
	);

	$("a.hamburger").click(function( e ) {
		$(this).toggleClass("is_active");

		e.preventDefault();
	});
	$(".mobile-header .mobile-nav").hide();

	$(window).scroll(function() {
		($(this).scrollTop() > height) ? $to_top.addClass("topVisible"): $to_top.removeClass("topVisible");
	});

	// Styles for homepage article-social

	$(".article .article-social a").hover(function() {
		$("span", this).eq(1).fadeIn(400);
	}, function() {
		$("span", this).eq(1).fadeOut(250);
	});

	// Functions for search-icon and ui-overlay-search

	$(".header-follow-search .search-wrap").on("click", function() {
		openUiOverlay();
	});

	$(".header-follow-search .close-icon").on("click", function() {
		closeUiOverlay();
	});

	$(".header-follow-search .close-icon").hover(
		function() {
			$(this).addClass("spin");
		},
		function() {
			$(this).removeClass("spin");
	});

	function openUiOverlay() {
		$(".ui-overlay-search").fadeIn(400).addClass("is_open");
	}

	function closeUiOverlay() {
		$(".ui-overlay-search").fadeOut(400).removeClass("is_open");
	}

	$(".ui-overlay-search .search-input input").focus(function() {
		$(".search-input").attr("data-focused", true);
		$(".search-input input").addClass("_is-focused");
		$("#__expand").addClass("visible");
	});

	$(".ui-overlay-search .search-input input").blur(function() {
		$(".search-input").attr("data-focused", false);
		$(".search-input input").removeClass("_is-focused");
		$("#__expand").removeClass("visible");
	});

	$(".post-meta .post-meta-inner .cta-btns a.is_inactive").on("click", function( e ) {
		e.preventDefault();
	});

	$(document).keydown(function( e ) {
    if ( e.keyCode == 27 ) {
        closeUiOverlay();
    } else {
		 // Do nothing.
	 }});

	 $(".mobile-nav").hide();

	// Functions for more-posts button click

	function addLoader() {
		$(".secondary-category-section .category-posts-column [data-clicked='false']").attr("data-clicked", "true").append("");
	}
	$(".secondary-category-section .category-posts-column [data-clicked='false']").on("click", function( e ) {
		$(this).css({
			"background": "#50ABF1",
			"color": "#fff"
		});
		addLoader();
		e.preventDefault();
	});

	$to_top.on("click", function( e ) {
		$("body,html").animate({
			scrollTop: 0
		}, 1000);

		e.preventDefault();
	});

});
<commit_msg>Create $$ variable to return Webtwic object<commit_after>/**
 * Author: Olaolu Olawuyi

 * Date Created: 20/08/2015

 * Last Modified: 27/02/2016

 * Twitter: @whizkydee, @webtwic

 * Github: https://github.com/webtwic/webtwic.github.io

*/

var Webtwic = Webtwic || {};

var browser = bowser;

var test_canvas = document.createElement("canvas");
var canvascheck = (test_canvas.getContext) ? true : false;

Webtwic = {
	// Basic Information about Webtwic
	name: "Webtwic",
	description: "A community for coding and tech tweaks where beginners and experts can learn.",
	repo: "https://github.com/whizkydee/whizkydee.github.io",
	author: "Olaolu Olawuyi",
	version: 1.07,

	// Start main functions for the object

	// Function to add browser name and version to body class
	_showBrowser: function( b ) {
		$("body").addClass(b + " " + b + parseInt(browser.version));
	},

	// Function to set attributes and values to elements
	_setAttr: function( elem, name, val ) {
		$(elem, this).attr(name, val);
	},

	// Function to push down .site-content
	_adjustSiteContent: function() {
		if ( $("body").hasClass("default-body") ) {
			$(".top-stripe").addClass("adjustedMargin");
			$("#header .logo").addClass("adjustedTop");
			$(".main-menu").addClass("adjustedMargin");
			$("#header").addClass("adjustSiteContent");
		} else if ( $("body").hasClass("secondary-body") ) {
			$(".site-content").addClass("adjustSiteContent");
			$(".secondary-header").addClass("adjustedMargin");
		}
	},

	// Function to push up .site-content to default state
	_undoSiteAdjust: function() {
		if ( $("body").hasClass("default-body") ) {
			$(".top-stripe").removeClass("adjustedMargin");
			$("#header .logo").removeClass("adjustedTop");
			$(".main-menu").removeClass("adjustedMargin");
			$("#header").removeClass("adjustSiteContent");
		} else if ( $("body").hasClass("secondary-body") ) {
			$(".secondary-header").removeClass("adjustedMargin");
		}
	},

	// Function to show Notifications before header
	_showNotif: function( text ) {
		text = (typeof text == "undefined") ? notif_text : text;
		Webtwic._adjustSiteContent();
		$("body").prepend(
			"
"+text+"
"
		);

		$(".close-button").on("click", function() {
			Webtwic._undoReset();
		});
	},

	// Function to hide Notifications
	_hideNotif: function() {
		$("#notifBanner").removeClass("notif_vis");
	},

	_resetSite: function() {
		Webtwic._showNotif();
		Webtwic._adjustSiteContent();
	},

	_undoReset: function() {
		Webtwic._hideNotif();
		Webtwic._undoSiteAdjust();
	},

	// Function to launch modal

	_launchModal: function( w, h, r, p, c, e, b ) {
		this.width = w;
	}

}, WBT = Webtwic,
$$ = Webtwic,
notif_text = "Some features which affect the functionality of webtwic are disabled in your browser. Please try refreshing the page or get a better browser. ";

// Detect when the document is ready

jQuery(document).ready(function() {
	// Test for HTML5 support
	if ( window.Modernizr ) {
		if ( !Modernizr.canvas ) {
			Webtwic._showNotif ( "Oops. Looks like your browser doesn't support HTML5. Please get a better browser  for an awesome experience.");
		} else {
			// Do nothing.
		}
	} else if ( !window.Modernizr ) {
		if ( canvascheck == false ) {
			Webtwic._showNotif ( "Oops. Looks like your browser doesn't support HTML5. Please get a better browser  for an awesome experience.");
		} else {
			// Do nothing.
		}
	} else {
		// Do nothing.
	}

	// Define Variables
	var $to_top = $("a.to-top"),
	is_toggle_active = $(".hamburger").hasClass("is_active"),
	height = 200;

	// Performance Fixes

	// Start browser detection

	browser.ie = browser.msie;

	if ( browser.webkit ) {
		$("body").addClass("webkit");
	}
	if ( browser.chrome ) {
		Webtwic._showBrowser("chrome");
	}
	if ( browser.msedge ) {
		Webtwic._showBrowser("msedge");
	}
	if ( browser.firefox ) {
		Webtwic._showBrowser("firefox");
	}
	if ( browser.msie ) {
		Webtwic._showBrowser("ie");
	}
	if ( browser.safari ) {
		Webtwic._showBrowser("safari");
	}
	if ( browser.opera ) {
		Webtwic._showBrowser("opera");
	}

	/*
		TODO: Rebuild Performance fixes for attributes
		See history of Performance fixes.
		Also, check StackOverflow.
		See Issue #12
	*/

	if ( window.Modernizr ) {
		if ( !Modernizr.flexbox || !Modernizr.inlinesvg || !Modernizr.svg || !Modernizr.svgclippaths || !Modernizr.fontface || !Modernizr.boxshadow || !Modernizr.borderradius || !Modernizr.csstransforms ) {
			Webtwic._showNotif();
		} else {
			// Do nothing.
		}
	} else {
		// Do nothing.
	}

	// Start Main Page

	$("nav li ul.drop-nav").hide().removeClass("dropNavFallback");

	if ( $(window).width() > 860 ) {
		$("nav li.dropdown").hover(function() {
			$("ul.drop-nav", this).stop().slideDown("fast");
		}, function() {
			$("ul.drop-nav", this).stop().slideUp("fast");
		});
	}

	$(".active-item").append(
		"<svg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><path d='M 16.682,19.674c 0.010-0.012, 0.014-0.028, 0.024-0.040l 6.982-7.714c 0.39-0.434, 0.39-1.138,0-1.572 c-0.004-0.004-0.008-0.006-0.012-0.008C 23.496,10.13, 23.244,10, 22.964,10L 8.998,10 c-0.286,0-0.54,0.138-0.722,0.352L 8.272,10.348 c-0.39,0.434-0.39,1.138,0,1.572l 6.998,7.754C 15.66,20.108, 16.292,20.108, 16.682,19.674z'></path></svg>"
	);

	$("a.hamburger").click(function( e ) {
		$(this).toggleClass("is_active");

		e.preventDefault();
	});
	$(".mobile-header .mobile-nav").hide();

	$(window).scroll(function() {
		($(this).scrollTop() > height) ? $to_top.addClass("topVisible"): $to_top.removeClass("topVisible");
	});

	// Styles for homepage article-social

	$(".article .article-social a").hover(function() {
		$("span", this).eq(1).fadeIn(400);
	}, function() {
		$("span", this).eq(1).fadeOut(250);
	});

	// Functions for search-icon and ui-overlay-search

	$(".header-follow-search .search-wrap").on("click", function() {
		openUiOverlay();
	});

	$(".header-follow-search .close-icon").on("click", function() {
		closeUiOverlay();
	});

	$(".header-follow-search .close-icon").hover(
		function() {
			$(this).addClass("spin");
		},
		function() {
			$(this).removeClass("spin");
	});

	function openUiOverlay() {
		$(".ui-overlay-search").fadeIn(400).addClass("is_open");
	}

	function closeUiOverlay() {
		$(".ui-overlay-search").fadeOut(400).removeClass("is_open");
	}

	$(".ui-overlay-search .search-input input").focus(function() {
		$(".search-input").attr("data-focused", true);
		$(".search-input input").addClass("_is-focused");
		$("#__expand").addClass("visible");
	});

	$(".ui-overlay-search .search-input input").blur(function() {
		$(".search-input").attr("data-focused", false);
		$(".search-input input").removeClass("_is-focused");
		$("#__expand").removeClass("visible");
	});

	$(".post-meta .post-meta-inner .cta-btns a.is_inactive").on("click", function( e ) {
		e.preventDefault();
	});

	$(document).keydown(function( e ) {
    if ( e.keyCode == 27 ) {
        closeUiOverlay();
    } else {
		 // Do nothing.
	 }});

	 $(".mobile-nav").hide();

	// Functions for more-posts button click

	function addLoader() {
		$(".secondary-category-section .category-posts-column [data-clicked='false']").attr("data-clicked", "true").append("");
	}
	$(".secondary-category-section .category-posts-column [data-clicked='false']").on("click", function( e ) {
		$(this).css({
			"background": "#50ABF1",
			"color": "#fff"
		});
		addLoader();
		e.preventDefault();
	});

	$to_top.on("click", function( e ) {
		$("body,html").animate({
			scrollTop: 0
		}, 1000);

		e.preventDefault();
	});

});
<|endoftext|>


<commit_before>$(document).ready(function() {
  var $window = $(window);
  var $page = $('.page');
  var $miniMap = $('.minimap_main');
  var $miniMapIntro = $('.minimap_intro');
  var $minimapWindow = $('.minimap__window');
  var offsetX = window.pageXOffset;
  var viewportHeight;
  var viewportWidth;

  // transform vertical scrolling to horizontal one
  // scrollConverter.activate();

  // Calculate and set viewport dimensions
  function setViewportHeight() {
    viewportHeight = $window.height();
    viewportWidth = $window.width();

  if (viewportHeight <= 690) {
      $page.css({
        height: 690
      });
   } else {
       $page.css({
         height: viewportHeight
       });
   }
  };

  setViewportHeight();

  // Render is animated via CSS transition
  // to hide viewport height change
  $page.css({
    opacity: 1.0,
  });

  // Recalculate and set viewport height
  // after each window resize
  $window.resize(setViewportHeight);

  // Toggle miniMap fixed (sticky)
  // after intro offset
  var isMinimapFixed = false;
  var MAX_X_OFFSET = parseInt($page.css('width'));
  var MINIMAP_MARGIN = parseInt($('.minimap_intro').css('width'));

  function toggleMinimapFixed() {
    if (offsetX <= MINIMAP_MARGIN) {
      if (isMinimapFixed)  {
        $miniMapIntro.css('display', 'flex');
        isMinimapFixed = false;
      }
    } else {
      if (!isMinimapFixed) {
        $miniMap.css('left', 0);
        $miniMapIntro.css('display', 'none');
        isMinimapFixed = true;
      }
    }
  };

  // Set window size and position
  function controlMinimapWindow(offset) {
    var position = (offset - MINIMAP_MARGIN) / (MAX_X_OFFSET - MINIMAP_MARGIN) * 100;
    var width = viewportWidth / (MAX_X_OFFSET - MINIMAP_MARGIN) * 100;

    if (offset <= MINIMAP_MARGIN) {
      position = 0;
    };
    $minimapWindow.css('left', position + '%');
    $minimapWindow.css('width', width + '%');
  };

  // Calculate initial size and position
  // it needs if we scroll and reload the page
  toggleMinimapFixed();
  controlMinimapWindow(offsetX);

  var baseOffsetX = window.pageXOffset;

  // Recalculate during scrolling
  $window.scroll(function() {
    offsetX = window.pageXOffset;

    if ((offsetX !== baseOffsetX) && (offsetX <= MINIMAP_MARGIN)) {
      var mainOffset = MINIMAP_MARGIN;
      var introOffset = 0;

      mainOffset = mainOffset - offsetX;
      introOffset = introOffset - offsetX;

      $miniMap.css('left', mainOffset + 'px');
      $miniMapIntro.css('left', introOffset +'px');
    } else {
      var value = isMinimapFixed ? 0 : '838px';

      $miniMap.css('left', value);
      $miniMapIntro.css('left', 0);
    }
    baseOffsetX = offsetX;

    toggleMinimapFixed();
    controlMinimapWindow(offsetX);
  });
});
<commit_msg>Enable inverted scroll (for test reasons)<commit_after>$(document).ready(function() {
  var $window = $(window);
  var $page = $('.page');
  var $miniMap = $('.minimap_main');
  var $miniMapIntro = $('.minimap_intro');
  var $minimapWindow = $('.minimap__window');
  var offsetX = window.pageXOffset;
  var viewportHeight;
  var viewportWidth;

  //transform vertical scrolling to horizontal one
  scrollConverter.activate();

  // Calculate and set viewport dimensions
  function setViewportHeight() {
    viewportHeight = $window.height();
    viewportWidth = $window.width();

  if (viewportHeight <= 690) {
      $page.css({
        height: 690
      });
   } else {
       $page.css({
         height: viewportHeight
       });
   }
  };

  setViewportHeight();

  // Render is animated via CSS transition
  // to hide viewport height change
  $page.css({
    opacity: 1.0,
  });

  // Recalculate and set viewport height
  // after each window resize
  $window.resize(setViewportHeight);

  // Toggle miniMap fixed (sticky)
  // after intro offset
  var isMinimapFixed = false;
  var MAX_X_OFFSET = parseInt($page.css('width'));
  var MINIMAP_MARGIN = parseInt($('.minimap_intro').css('width'));

  function toggleMinimapFixed() {
    if (offsetX <= MINIMAP_MARGIN) {
      if (isMinimapFixed)  {
        $miniMapIntro.css('display', 'flex');
        isMinimapFixed = false;
      }
    } else {
      if (!isMinimapFixed) {
        $miniMap.css('left', 0);
        $miniMapIntro.css('display', 'none');
        isMinimapFixed = true;
      }
    }
  };

  // Set window size and position
  function controlMinimapWindow(offset) {
    var position = (offset - MINIMAP_MARGIN) / (MAX_X_OFFSET - MINIMAP_MARGIN) * 100;
    var width = viewportWidth / (MAX_X_OFFSET - MINIMAP_MARGIN) * 100;

    if (offset <= MINIMAP_MARGIN) {
      position = 0;
    };
    $minimapWindow.css('left', position + '%');
    $minimapWindow.css('width', width + '%');
  };

  // Calculate initial size and position
  // it needs if we scroll and reload the page
  toggleMinimapFixed();
  controlMinimapWindow(offsetX);

  var baseOffsetX = window.pageXOffset;

  // Recalculate during scrolling
  $window.scroll(function() {
    offsetX = window.pageXOffset;

    if ((offsetX !== baseOffsetX) && (offsetX <= MINIMAP_MARGIN)) {
      var mainOffset = MINIMAP_MARGIN;
      var introOffset = 0;

      mainOffset = mainOffset - offsetX;
      introOffset = introOffset - offsetX;

      $miniMap.css('left', mainOffset + 'px');
      $miniMapIntro.css('left', introOffset +'px');
    } else {
      var value = isMinimapFixed ? 0 : '838px';

      $miniMap.css('left', value);
      $miniMapIntro.css('left', 0);
    }
    baseOffsetX = offsetX;

    toggleMinimapFixed();
    controlMinimapWindow(offsetX);
  });
});
<|endoftext|>


<commit_before>$( document ).ready(function() {
	var appID = "7c3832ce234904f30881f09806b7a6d7";

   	$(".query_btn").click(function(){

    	var query_param = $(this).prev().val();

    	if ($(this).prev().attr("placeholder") == "City") {
    		var weather = "http://api.openweathermap.org/data/2.5/weather?q=" + query_param + "&units=imperial&APPID=" + appID;
    	} else if ($(this).prev().attr("placeholder") == "Zip Code") {
    		var weather = "http://api.openweathermap.org/data/2.5/weather?zip=" + query_param + "&units=imperial&APPID=" + appID;
    	}

        $.getJSON(weather,function(json){
            $("#city").html(json.name);
            $("#main_weather").html(json.weather[0].main);
            $("#description_weather").html(json.weather[0].description);
            $("#weather_image").attr("src", "http://openweathermap.org/img/w/" + json.weather[0].icon + ".png");
            $("#temperature").html(json.main.temp);
            $("#pressure").html(json.main.pressure);;
            $("#humidity").html(json.main.humidity);;
        });
    })

    if ($('#temperature').is(':empty') == false) {
  		$("#convert").click(function(){
  			$("#temperature").text() == ((($("#temperature").text() - 32) * 5) / 9  );
  		});
	}

});<commit_msg>attempting to fix temperature conversion<commit_after>$( document ).ready(function() {
	var appID = "7c3832ce234904f30881f09806b7a6d7";

   	$(".query_btn").click(function(){

    	var query_param = $(this).prev().val();

    	if ($(this).prev().attr("placeholder") == "City") {
    		var weather = "http://api.openweathermap.org/data/2.5/weather?q=" + query_param + "&units=imperial&APPID=" + appID;
    	} else if ($(this).prev().attr("placeholder") == "Zip Code") {
    		var weather = "http://api.openweathermap.org/data/2.5/weather?zip=" + query_param + "&units=imperial&APPID=" + appID;
    	}

        $.getJSON(weather,function(json){
            $("#city").html(json.name);
            $("#main_weather").html(json.weather[0].main);
            $("#description_weather").html(json.weather[0].description);
            $("#weather_image").attr("src", "http://openweathermap.org/img/w/" + json.weather[0].icon + ".png");
            $("#temperature").html(json.main.temp);
            $("#pressure").html(json.main.pressure);;
            $("#humidity").html(json.main.humidity);;
        });
    })

	$("#convert").click(function(){
		$("#temperature").text() == ((($("#temperature").text() - 32) * 5) / 9  );
		console.log($("#temperature").text());
	});

});<|endoftext|>


<commit_before>$('a').click(function(){

    //$(this).parent.addClass('selected');

    $('html, body').animate({
        scrollTop: $( $(this).attr('href') ).offset().top
    }, 250);

    //document.getElementByClass("selected").removeClass("selected");

    $(".selected").removeClass("selected");
    $(this).parent().addClass("selected");

    return false;
});<commit_msg>adds deep linking<commit_after>$('a').click(function(){

	// scroll to the proper tag
    $('html, body').animate({
        scrollTop: $( $(this).attr('href') ).offset().top
    }, 250);

    // logic for setting the current page
    $(".selected").removeClass("selected");
    $(this).parent().addClass("selected");

    //  change the URL for deep linking
  	var page = $(this).parent();
	window.location.href = url;

	// no return objects necessary
    return false;

});<|endoftext|>


<commit_before>(function() {
       var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
       po.src = 'https://apis.google.com/js/client:plusone.js';
       var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
     })();
var signin=false;
function signinCallback(authResult) {

  if(!signin){if (authResult['status']['signed_in']) {
    signin=true;

    $.ajax({
        url: "https://www.googleapis.com/plus/v1/people/me?access_token="+authResult["access_token"],
        type: 'GET',
        dataType: 'json',

        success: function(data) {
          alert("Welcome! "+data["displayName"]+" you are logged in!")
        },

    });
    // Update the app to reflect a signed in user
    // Hide the sign-in button now that the user is authorized, for example:
    document.getElementById('signinButton').setAttribute('style', 'display: none');
    document.getElementById('signoutButton').setAttribute('style', 'display: inline')
  } else {

    // Update the app to reflect a signed out user
    // Possible error values:
    //   "user_signed_out" - User is signed-out
    //   "access_denied" - User denied access to your app
    //   "immediate_failed" - Could not automatically log in the user
    console.log('Sign-in state: ' + authResult['error']);
  }}

}
  function signout(){
    $.ajax({
                  type: 'GET',
                  url: 'https://accounts.google.com/o/oauth2/revoke?token=' + gapi.auth.getToken().access_token,
                  async: false,
                  contentType: 'application/json',
                  dataType: 'jsonp',
                  success: function(result) {

                    document.getElementById('signinButton').setAttribute('style', 'display: inline')
                    document.getElementById('signoutButton').setAttribute('style', 'display: none')
                  },
                  error: function(e) {
                    console.log(e);
                  }
    })

}<commit_msg>Signin/signout fix<commit_after>(function() {
       var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
       po.src = 'https://apis.google.com/js/client:plusone.js';
       var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
     })();
function signinCallback(authResult) {

  if (authResult['status']['signed_in']) {
    signin=true
    $.ajax({
        url: "https://www.googleapis.com/plus/v1/people/me?access_token="+authResult["access_token"],
        type: 'GET',
        dataType: 'json',

        success: function(data) {
          alert("Welcome! "+data["displayName"]+" you are logged in!")
        },

    })
    // Update the app to reflect a signed in user
    // Hide the sign-in button now that the user is authorized, for example:
    document.getElementById('signinButton').setAttribute('style', 'display: none');
    document.getElementById('signoutButton').setAttribute('style', 'display: inline')
  } else {
    document.getElementById('signinButton').setAttribute('style', 'display: inline')
    document.getElementById('signoutButton').setAttribute('style', 'display: none')

    // Update the app to reflect a signed out user
    // Possible error values:
    //   "user_signed_out" - User is signed-out
    //   "access_denied" - User denied access to your app
    //   "immediate_failed" - Could not automatically log in the user
    console.log('Sign-in state: ' + authResult['error']);
  }

}
  function signout(){
    $.ajax({
                  type: 'GET',
                  url: 'https://accounts.google.com/o/oauth2/revoke?token=' + gapi.auth.getToken().access_token,
                  async: false,
                  contentType: 'application/json',
                  dataType: 'jsonp',
                  success: function(result) {

                    document.getElementById('signinButton').setAttribute('style', 'display: inline')
                    document.getElementById('signoutButton').setAttribute('style', 'display: none')
                  },
                  error: function(e) {
                    console.log(e);
                  }
    })

}<|endoftext|>


<commit_before>function setup() {

}

var mic, recorder, soundFile;

var state = 0; // mousePress will increment from Record, to Stop, to Play

function setup() {
  createCanvas(400,400);
//    background(200);
//   fill(0);
  text('Enable mic and click the mouse to begin recording', 20, 20);

  // create an audio in
  mic = new p5.AudioIn();

  // users must manually enable their browser microphone for recording to work properly!
  mic.start();

  // create a sound recorder
  recorder = new p5.SoundRecorder();

  // connect the mic to the recorder
  recorder.setInput(mic);

  // create an empty sound file that we will use to playback the recording
  soundFile = new p5.SoundFile();
}

function draw() {
  background(200);

  // Get the overall volume (between 0 and 1.0)
  var vol = mic.getLevel();
  fill(127);
  stroke(0);

  // Draw an ellipse with height based on volume
  var h = map(vol, 0, 1, height, 0);
  ellipse(width/2, h - 25, 50, 50);
}

function mousePressed() {
  // use the '.enabled' boolean to make sure user enabled the mic (otherwise we'd record silence)
  if (state === 0 && mic.enabled) {

    // Tell recorder to record to a p5.SoundFile which we will use for playback
    recorder.record(soundFile);

    background(255,0,0);
    text('Recording now! Click to stop.', 20, 20);
    state++;
  }

  else if (state === 1) {
    recorder.stop(); // stop recorder, and send the result to soundFile

    background(0,255,0);
    text('Recording stopped. Click to play & save', 20, 20);
    state++;
  }

  else if (state === 2) {
    soundFile.play(); // play the result!
    saveSound(soundFile, 'js/mySound.wav'); // save file
    state++;
  }
}
<commit_msg>Update sketch.js<commit_after>function setup() {

}

var mic, recorder, soundFile;

var state = 0; // mousePress will increment from Record, to Stop, to Play

function setup() {
  createCanvas(400,400);
//    background(200);
//   fill(0);
  text('Enable mic and click the mouse to begin recording', 20, 20);

  // create an audio in
  mic = new p5.AudioIn();

  // users must manually enable their browser microphone for recording to work properly!
  mic.start();

  // create a sound recorder
  recorder = new p5.SoundRecorder();

  // connect the mic to the recorder
  recorder.setInput(mic);

  // create an empty sound file that we will use to playback the recording
  soundFile = new p5.SoundFile();
}

function draw() {
  background(0,0,0,0);

  // Get the overall volume (between 0 and 1.0)
  var vol = mic.getLevel();
  fill(127);
  stroke(0);

  // Draw an ellipse with height based on volume
  var h = map(vol, 0, 1, height, 0);
  ellipse(width/2, h - 25, 50, 50);
}

function mousePressed() {
  // use the '.enabled' boolean to make sure user enabled the mic (otherwise we'd record silence)
  if (state === 0 && mic.enabled) {

    // Tell recorder to record to a p5.SoundFile which we will use for playback
    recorder.record(soundFile);

    background(255,0,0);
    text('Recording now! Click to stop.', 20, 20);
    state++;
  }

  else if (state === 1) {
    recorder.stop(); // stop recorder, and send the result to soundFile

    background(0,255,0);
    text('Recording stopped. Click to play & save', 20, 20);
    state++;
  }

  else if (state === 2) {
    soundFile.play(); // play the result!
    saveSound(soundFile, 'js/mySound.wav'); // save file
    state++;
  }
}
<|endoftext|>


<commit_before>var fft, osc, canvas, pitch = 100;

var screenWidth = $(window).width(),
	screenHeight = $(window).height();

/* Initiate */
function setup() {
	canvas = createCanvas( screenWidth, screenHeight, P2D);
	noCursor();

	osc = new p5.Oscillator(100);
	osc.start();

	canvas.mousePressed( mouseDragged );
	canvas.mouseReleased( mouseReleased );

	fft = new p5.FFT();

	resizePlayArea();
}

function draw(){
	background("rgba(380,380,380,.5)");
	/* antenna */
	push();
	stroke('grey');
	strokeWeight(5);
	line(50,10, 50, 280 );
	pop();
	/* arm */
	push();
	stroke('black');
	strokeWeight(20);
	line(50,280, 180, 280 );
	pop();
	/* body */
	push();
	stroke('black');
  	fill('black');
	strokeWeight(20);
	rect(180,280, 50, 120 );
	pop();
	/* hoop */
	push();
	noFill();
	stroke('black');
	ellipse(260,280, 100, 10);
	pop();
	/* position dot */
	push();
	stroke('black');
	fill('black');
	ellipse(mouseX, mouseY, 10,10);
	pop();
	/* Wave for that visually displays the frequency */
  	noFill();
  	beginShape();
  	stroke('red');
  	strokeWeight(1);
	drawWaveform(fft.waveform());
  	endShape();
	/* Test that visually displays the HZ value */
  	push();
  	var pitchText = round(pitch) + "HZ";
  	textSize(40);
  	fill("red");
  	text(pitchText, 100, 100);
  	pop();
}

function mouseDragged() {
	pitchRange = ( 800 - 439 ) / screenHeight;
	pitch = ( screenHeight - mouseY ) * pitchRange + 439;

	ampRange = (.9) / screenWidth;
  	amplitude = (screenWidth - mouseX ) * ampRange;

	osc.freqNode.value = pitch;
  	osc.output.gain.value = amplitude;
}

function mouseReleased() {
	osc.freqNode.value = 0;
}

function resizePlayArea() {
	$(window).resize(function() {
		resizeCanvas($(window).width(), $(window).height());
	});
}

function drawWaveform(waveform) {
	var x, y;
	for (var i = 0; i< waveform.length; i++){
	  	x = map(i, 0, waveform.length, 0, width);
	  	y = map(waveform[i], -1, 1, 0, height);
	  	vertex(x,y);
	}
}<commit_msg>Theremin Sound Project<commit_after>var fft, osc, canvas, currentPitch, minPitch = 0, maxPitch = 3000;

var screenWidth = $(window).width(),
	screenHeight = $(window).height();

$(window).resize(function() {
	screenWidth = $(window).width();
	screenHeight = $(window).height();
});

/* Initiate */
function setup() {
	canvas = createCanvas( screenWidth, screenHeight, P2D);
	noCursor();

	osc = new p5.Oscillator(minPitch);
	osc.start();

	canvas.mousePressed( mouseDragged );
	canvas.mouseReleased( mouseReleased );

	fft = new p5.FFT();

	resizePlayArea();
}

function draw(){
	background("rgba(380,380,380,.5)");
	/* antenna */
	push();
	stroke('grey');
	strokeWeight(5);
	line(300,10, 300, 280 );
	pop();
	/* arm */
	push();
	stroke('black');
	strokeWeight(20);
	line(100,280, 300, 280 );
	pop();
	/* body */
	push();
	stroke('black');
  	fill('black');
	strokeWeight(20);
	rect(180,280, 50, 120 );
	pop();
	/* hoop */
	push();
	noFill();
	stroke('black');
	ellipse(75,280, 100, 10);
	pop();
	/* position dot */
	push();
	stroke('black');
	fill('black');
	ellipse(mouseX, mouseY, 10,10);
	pop();
	/* Wave for that visually displays the frequency */
  	noFill();
  	beginShape();
  	stroke('red');
  	strokeWeight(1);
	drawWaveform(fft.waveform());
  	endShape();
	/* Test that visually displays the HZ value */
  	push();
  	var pitchText = round(currentPitch) + "HZ";
  	textSize(40);
  	fill("red");
  	text(pitchText, 100, 100);
  	pop();
}

function mouseDragged() {
	yPerc = ( mouseX / screenWidth ) * 100;
	pitchPerc = 100 / yPerc;
	currentPitch = maxPitch / pitchPerc;

	ampRange = (.9) / screenHeight;
  	amplitude = (screenHeight - mouseY ) * ampRange;

	osc.freqNode.value = currentPitch;
  	osc.output.gain.value = amplitude;
}

function mouseReleased() {
	osc.freqNode.value = 0;
}

function resizePlayArea() {
	$(window).resize(function() {
		resizeCanvas(screenWidth, screenHeight);
	});
}

function drawWaveform(waveform) {
	var x, y;
	for (var i = 0; i< waveform.length; i++){
	  	x = map(i, 0, waveform.length, 0, width);
	  	y = map(waveform[i], -1, 1, 0, height);
	  	vertex(x,y);
	}
}<|endoftext|>


<commit_before>;
(function ($, window, document, undefined) {

    "use strict";

    var pluginName = "slider";
    var that;
    var timer;
    var defaults = {
        delay: 1000,
        interval: 10000,
        slide: 1,
        slides: 0
    };

    function Plugin(element, options) {
        this.element = element;
        this.settings = $.extend({}, defaults, options);
        this._defaults = defaults;
        this._name = pluginName;
        this.init();
    }

    Plugin.prototype = {
        init: function () {
            that = this;
            var $slider = $(this.element);
            var $position = $slider.find('.position');
            $slider.children('.slides').find('img').each(function (index, element) {
                that.settings.slides++;
                if (that.settings.slides == that.settings.slide) {
                    $(element).addClass('active').css('opacity', '1');
                    $position.append('

');
                } else {
                    $(element).css('opacity', '0');
                    $position.append('

');
                }
            });
            $position.find('.points').each(function (index) {
                $(this).click(function () {
                    that.show(index + 1);
                });
            });
            $slider.hover(function () {
                clearInterval(timer);
            }, function () {
                that.auto();
            });
            $slider.find('.prev > *').click(function () {
                that.prev();
            });
            $slider.find('.next > *').click(function () {
                that.next();
            });
            that.auto();
        },
        auto: function () {
            timer = setInterval(function () {
                that.next();
            }, that.settings.interval);
        },
        next: function () {
            if (that.settings.slide < that.settings.slides) {
                that.show(that.settings.slide + 1);
            } else {
                that.show(1);
            }
        },
        prev: function () {
            if (that.settings.slide > 1) {
                that.show(that.settings.slide - 1);
            } else {
                that.show(that.settings.slides);
            }
        },
        show: function (slide) {
            $(that.element).find('.slides img:nth-child(' + that.settings.slide + ')').stop().removeClass('active').animate({opacity: 0}, that.settings.delay);
            $(that.element).find('.position .points:nth-child(' + that.settings.slide + ')').removeClass('active');
            $(that.element).find('.text span:nth-child(' + that.settings.slide + ')').removeClass('active');
            that.settings.slide = slide;
            $(that.element).find('.slides img:nth-child(' + that.settings.slide + ')').stop().addClass('active').animate({opacity: 1}, that.settings.delay);
            $(that.element).find('.position .points:nth-child(' + that.settings.slide + ')').addClass('active');
            $(that.element).find('.text span:nth-child(' + that.settings.slide + ')').addClass('active');
            return this;
        }
    };

    $.fn[ pluginName ] = function (options) {
        this.each(function () {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName, new Plugin(this, options));
            }
        });
        return this;
    };

})(jQuery, window, document);
<commit_msg>Update slider.js<commit_after>;
(function ($, window, document, undefined) {

    "use strict";

    var pluginName = "slider";
    var that;
    var timer;
    var slide = 1;
    var slides = 0;
    var defaults = {
        delay: 1000,
        interval: 10000
    };

    function Plugin(element, options) {
        this.element = element;
        this.settings = $.extend({}, defaults, options);
        this._defaults = defaults;
        this._name = pluginName;
        this.init();
    }

    Plugin.prototype = {
        init: function () {
            that = this;
            var $slider = $(this.element);
            var $position = $slider.find('.position');
            $slider.children('.slides').find('img').each(function (index, element) {
                slides++;
                if (slides == slide) {
                    $(element).addClass('active').css('opacity', '1');
                    $position.append('

');
                } else {
                    $(element).css('opacity', '0');
                    $position.append('

');
                }
            });
            $position.find('.points').each(function (index) {
                $(this).click(function () {
                    that.show(index + 1);
                });
            });
            $slider.hover(function () {
                clearInterval(timer);
            }, function () {
                that.auto();
            });
            $slider.find('.prev > *').click(function () {
                that.prev();
            });
            $slider.find('.next > *').click(function () {
                that.next();
            });
            that.auto();
        },
        auto: function () {
            timer = setInterval(function () {
                that.next();
            }, that.settings.interval);
        },
        next: function () {
            if (slide < slides) {
                that.show(slide + 1);
            } else {
                that.show(1);
            }
        },
        prev: function () {
            if (slide > 1) {
                that.show(slide - 1);
            } else {
                that.show(slides);
            }
        },
        show: function (newSlide) {
            $(that.element).find('.slides img:nth-child(' + slide + ')').stop().removeClass('active').animate({opacity: 0}, that.settings.delay);
            $(that.element).find('.position .points:nth-child(' + slide + ')').removeClass('active');
            $(that.element).find('.text span:nth-child(' + slide + ')').removeClass('active');
            slide = newSlide;
            $(that.element).find('.slides img:nth-child(' + slide + ')').stop().addClass('active').animate({opacity: 1}, that.settings.delay);
            $(that.element).find('.position .points:nth-child(' + slide + ')').addClass('active');
            $(that.element).find('.text span:nth-child(' + slide + ')').addClass('active');
            return this;
        }
    };

    $.fn[pluginName] = function (options) {
        this.each(function () {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName, new Plugin(this, options));
            }
        });
        return this;
    };

})(jQuery, window, document);
<|endoftext|>


<commit_before>var stream	= new function () {

/**
* @namespace Player
*/
var self	= this;

/**
* @field
* @property {bool}
*/
var isPlaying;

/**
* @field
* @property {int}
*/
var newTime;

/**
* @field
* @property {int}
*/
var newTimeProcessed;

/**
* @field
* @property {Node}
*/
var player;

/**
* @field
* @property {2-Tuple (int)}
*/
var syncTimeouts;

/**
* @function
* @property {void} Initialises this namespace
*/
var init;

/**
* @function
* @property {bool} Indicates whether or not current track has completed
*/
var isFinished;

/**
* @function
* @property {int} Length of current track
*/
var length;

/**
* @function
* @property {void} Loads track in player
* @param {string} trackid
* @param {function} callback
* @param {bool} noUpdate
*/
var loadTrack;

/**
* @function
* @property {void} Mutes or unmutes player
* @param {bool} shouldMute
*/
var mute;

/**
* @function
* @property {void} Executes callback when track is finished
* @param {bool} callback Optional; removes any previous callback if undefined
*/
var onFinished;

/**
* @function
* @property {void} Plays or pauses current track
* @param {bool} shouldPlay
* @param {bool} noUpdate
*/
var play;

/**
* @function
* @property {int} Formats time value to human-readable timestamp
* @param {int} time
*/
var processTime;

/**
* @function
* @property {void} Syncs player state with specified user
* @param {string} userid Optional; if undefined, will default to current user (thereby syncing multiple instances of Napster.fm owned by the same user)
*/
var sync;

/**
* @function
* @property {int} Gets or sets time in current track
* @param {int} newTime
* @param {bool} noUpdate
*/
var time;

/**
* @function
* @property {void} Updates datastore.data.user.current.nowPlaying with current state of player
*/
var updateNowPlaying;

/**
* @function
* @property {int} Gets or sets player volume
* @param {int} newVolume
*/
var volume;

self.init	= function () {
	var onYouTubePlayerReady = function () {
		var wait		= new goog.async.ConditionalDelay(function () { return window.datastoreIsReady; });
		wait.onSuccess	= function () {
			self.onFinished();
		};
		wait.start();
	};

	var onYouTubePlayerStateChange = function (state) {
		var eventListener	=
			state.data == YT.PlayerState.PLAYING ?
				window.onYouTubeVideoStarted :
				state.data == YT.PlayerState.ENDED ?
					window.onYouTubeVideoFinished :
					null
		;

		eventListener && eventListener();
		ui.update();
	};

	var onYouTubePlayerError = function () {

	};

	window.onYouTubeIframeAPIReady	= function () {
		self.player	= new YT.Player($('#stream')[0], {
			height: '390',
			width: '640',
			events: {
				'onReady': onYouTubePlayerReady,
				'onStateChange': onYouTubePlayerStateChange,
				'onError': onYouTubePlayerError
			}
		});
	};

	datastore.user().nowPlayingChild.isPlaying.setOnDisconnect(false);
	datastore.user().nowPlayingChild.lastChange.setOnDisconnect(0);

	self.syncTimeouts	= [];
};

self.isFinished	= function () {
	return self.time() >= self.length();
};

self.length	= function () {
	return self.player.getDuration();
};

self.loadTrack	= function (trackid, callback, noUpdate) {
	self.player.stopVideo();
	self.time(0, true);

	window.onYouTubeVideoStarted	= function () {
		window.onYouTubeVideoStarted	= null;
		window.setTimeout(function () {
			stream.volume(0);
			self.time(0, true);
			self.play(true, true);
			datastore.track(self.currentTrack).length.set(self.length());
			callback && callback();
		}, 2000);
	};

	datastore.track(trackid).once('value', function (o) {
		var val	= o.val();
		var id	= o.name();

		ui.slider.setMaximum(val.length);

		datastore.track(trackid).lastPlayed.set(Date.now());
		datastore.track(trackid).lastPlayedBy.set(authentication.userid);

		datastore.lastPlayed().push(id);

		self.player.loadVideoById(val.youtubeid);

		self.currentTrack	= trackid;

		if (noUpdate != true) {
			datastore.track(trackid).playCount.set(++val.playCount);
			self.updateNowPlaying();
		}

		var o	= datastore.data.user.current.library.processed;
		for (var k in o) {
			var processedTrack	= o[k];
			processedTrack.nowPlayingClass	= processedTrack.id == self.currentTrack ? 'now-playing' : '';
		}
	});
};

self.mute	= function (shouldMute) {
	shouldMute != false ? self.player.mute() : self.player.unMute();
};

self.onFinished	= function (callback) {
	window.onYouTubeVideoFinished	= function () {
		self.play(false);
		window.clearInterval(ui.slider.playInterval);
		callback && callback();
	};
};

self.play	= function (shouldPlay, noUpdate) {
	self.isPlaying	= shouldPlay == false ? false : true;

	self.isPlaying ? self.volume(100) : self.volume(0);

	window.clearInterval(ui.slider.playInterval);
	if (self.isPlaying) {
		ui.slider.playInterval	= window.setInterval(function () {
			if (!ui.slider.valueJustChanged && self.isPlaying) {
				ui.slider.animatedSetValue(self.time());
				ui.update();
			}
		}, 500);
	}

	self.isPlaying ? self.player.playVideo() : self.player.pauseVideo();

	ui.update();
	self.time();

	if (noUpdate != true) {
		self.updateNowPlaying();
	}
};

self.processTime	= function (time) {
	return (time < 60 ? '0:' : '') + (time < 10 ? '0' : '') + ([].add(new Date (0, 0, 0, 0, 0, time).toLocaleTimeString().match('[^0:].*'))[0] || 0);
}

self.sync	= function (userid) {
	userid		= userid || authentication.userid;
	var user	= datastore.user(userid);

	datastore.user(datastore.data.user.current.following).nowPlayingChild.lastChange.off();

	datastore.user().following.set(userid);

	user.nowPlayingChild.lastChange.on('value', function (o) {
		var lastChange	= o.val();
		var timeOffset	= (Date.now() - lastChange) / 1000;

		user.nowPlaying.once('value', function (o) {
			var nowPlaying	= o.val();

			var newTime		= nowPlaying.time + (nowPlaying.isPlaying ? timeOffset : 0);
			var updatePlay	= function () { nowPlaying.isPlaying ? self.player.playVideo() : self.player.pauseVideo(); };
			var updateTime	= function () { self.time(newTime, true); };

			if (nowPlaying.track != self.currentTrack) {
				self.loadTrack(nowPlaying.track, function () {
					self.syncTimeouts[0]	= window.setTimeout(function () {
						if (nowPlaying.track == self.currentTrack) {
							self.player.pauseVideo();
						}
						self.syncTimeouts[1]	= window.setTimeout(function () {
							if (nowPlaying.track == self.currentTrack) {
								self.play(nowPlaying.isPlaying, true);
								updateTime();
								ui.slider.animatedSetValue(newTime);
							}
						}, 3000);
					}, 3000);
				}, true);
			}
			else {
				updatePlay();
				updateTime();
			}

			ui.update();
		});
	});
};

self.time	= function (newTime, noUpdate) {
	newTime	= newTime === 0 ? 1 : newTime;

	if (newTime && Math.abs(newTime - self.time()) < 5) {
		return newTime;
	}

	if (newTime) {
		self.newTime	= newTime;

		if (noUpdate != true) {
			self.updateNowPlaying();
		}
		else {
			self.player.seekTo(newTime, true);
		}
	}

	if ((newTime >= self.length() || self.player.getCurrentTime() >= self.length()) && self.isPlaying) {
		self.isPlaying	= false;
		self.newTime	= 0;
		ui.update();
	}

	self.newTime			= self.player.getCurrentTime() || self.newTime;
	self.newTimeProcessed	= self.processTime(self.newTime);
	return self.newTime;
};

self.updateNowPlaying	= function () {
	datastore.user().nowPlaying.set({
		isPlaying: self.isPlaying,
		lastChange: Date.now(),
		time: self.newTime,
		track: self.currentTrack
	});

	ui.update();
};

self.volume	= function (newVolume) {
	if (!isNaN(newVolume)) {
		self.player.setVolume(newVolume);
	}

	return self.player.getVolume();
};

};
<commit_msg>Real-time time syncing with datastore.data.user.current.nowPlaying.time<commit_after>var stream	= new function () {

/**
* @namespace Player
*/
var self	= this;

/**
* @field
* @property {bool}
*/
var isPlaying;

/**
* @field
* @property {int}
*/
var newTime;

/**
* @field
* @property {int}
*/
var newTimeProcessed;

/**
* @field
* @property {Node}
*/
var player;

/**
* @field
* @property {2-Tuple (int)}
*/
var syncTimeouts;

/**
* @function
* @property {void} Initialises this namespace
*/
var init;

/**
* @function
* @property {bool} Indicates whether or not current track has completed
*/
var isFinished;

/**
* @function
* @property {int} Length of current track
*/
var length;

/**
* @function
* @property {void} Loads track in player
* @param {string} trackid
* @param {function} callback
* @param {bool} noUpdate
*/
var loadTrack;

/**
* @function
* @property {void} Mutes or unmutes player
* @param {bool} shouldMute
*/
var mute;

/**
* @function
* @property {void} Executes callback when track is finished
* @param {bool} callback Optional; removes any previous callback if undefined
*/
var onFinished;

/**
* @function
* @property {void} Plays or pauses current track
* @param {bool} shouldPlay
* @param {bool} noUpdate
*/
var play;

/**
* @function
* @property {int} Formats time value to human-readable timestamp
* @param {int} time
*/
var processTime;

/**
* @function
* @property {void} Syncs player state with specified user
* @param {string} userid Optional; if undefined, will default to current user (thereby syncing multiple instances of Napster.fm owned by the same user)
*/
var sync;

/**
* @function
* @property {int} Gets or sets time in current track
* @param {int} newTime
* @param {bool} noUpdate
*/
var time;

/**
* @function
* @property {void} Updates datastore.data.user.current.nowPlaying with current state of player
*/
var updateNowPlaying;

/**
* @function
* @property {int} Gets or sets player volume
* @param {int} newVolume
*/
var volume;

self.init	= function () {
	var onYouTubePlayerReady = function () {
		var wait		= new goog.async.ConditionalDelay(function () { return window.datastoreIsReady; });
		wait.onSuccess	= function () {
			self.onFinished();
		};
		wait.start();
	};

	var onYouTubePlayerStateChange = function (state) {
		var eventListener	=
			state.data == YT.PlayerState.PLAYING ?
				window.onYouTubeVideoStarted :
				state.data == YT.PlayerState.ENDED ?
					window.onYouTubeVideoFinished :
					null
		;

		eventListener && eventListener();
		ui.update();
	};

	var onYouTubePlayerError = function () {

	};

	window.onYouTubeIframeAPIReady	= function () {
		self.player	= new YT.Player($('#stream')[0], {
			height: '390',
			width: '640',
			events: {
				'onReady': onYouTubePlayerReady,
				'onStateChange': onYouTubePlayerStateChange,
				'onError': onYouTubePlayerError
			}
		});
	};

	datastore.user().nowPlayingChild.isPlaying.setOnDisconnect(false);
	datastore.user().nowPlayingChild.lastChange.setOnDisconnect(0);

	self.syncTimeouts	= [];
};

self.isFinished	= function () {
	return self.time() >= self.length();
};

self.length	= function () {
	return self.player.getDuration();
};

self.loadTrack	= function (trackid, callback, noUpdate) {
	self.player.stopVideo();
	self.time(0, true);

	window.onYouTubeVideoStarted	= function () {
		window.onYouTubeVideoStarted	= null;
		window.setTimeout(function () {
			stream.volume(0);
			self.time(0, true);
			self.play(true, true);
			datastore.track(self.currentTrack).length.set(self.length());
			callback && callback();
		}, 2000);
	};

	datastore.track(trackid).once('value', function (o) {
		var val	= o.val();
		var id	= o.name();

		ui.slider.setMaximum(val.length);

		datastore.track(trackid).lastPlayed.set(Date.now());
		datastore.track(trackid).lastPlayedBy.set(authentication.userid);

		datastore.lastPlayed().push(id);

		self.player.loadVideoById(val.youtubeid);

		self.currentTrack	= trackid;

		if (noUpdate != true) {
			datastore.track(trackid).playCount.set(++val.playCount);
			self.updateNowPlaying();
		}

		var o	= datastore.data.user.current.library.processed;
		for (var k in o) {
			var processedTrack	= o[k];
			processedTrack.nowPlayingClass	= processedTrack.id == self.currentTrack ? 'now-playing' : '';
		}
	});
};

self.mute	= function (shouldMute) {
	shouldMute != false ? self.player.mute() : self.player.unMute();
};

self.onFinished	= function (callback) {
	window.onYouTubeVideoFinished	= function () {
		self.play(false);
		window.clearInterval(ui.slider.playInterval);
		callback && callback();
	};
};

self.play	= function (shouldPlay, noUpdate) {
	self.isPlaying	= shouldPlay == false ? false : true;

	self.isPlaying ? self.volume(100) : self.volume(0);

	window.clearInterval(ui.slider.playInterval);
	if (self.isPlaying) {
		ui.slider.playInterval	= window.setInterval(function () {
			if (!ui.slider.valueJustChanged && self.isPlaying) {
				ui.slider.animatedSetValue(self.time());
				ui.update();
			}
		}, 500);
	}

	self.isPlaying ? self.player.playVideo() : self.player.pauseVideo();

	ui.update();
	self.time();

	if (noUpdate != true) {
		self.updateNowPlaying();
	}
};

self.processTime	= function (time) {
	time	= time || 0;
	return (time < 60 ? '0:' : '') + (time < 10 ? '0' : '') + ([].add(new Date (0, 0, 0, 0, 0, time).toLocaleTimeString().match('[^0:].*'))[0] || 0);
}

self.sync	= function (userid) {
	userid		= userid || authentication.userid;
	var user	= datastore.user(userid);

	datastore.user(datastore.data.user.current.following).nowPlayingChild.lastChange.off();

	datastore.user().following.set(userid);

	user.nowPlayingChild.lastChange.on('value', function (o) {
		var lastChange	= o.val();
		var timeOffset	= (Date.now() - lastChange) / 1000;

		user.nowPlaying.once('value', function (o) {
			var nowPlaying	= o.val();

			var newTime		= nowPlaying.time + (nowPlaying.isPlaying ? timeOffset : 0);
			var updatePlay	= function () { nowPlaying.isPlaying ? self.player.playVideo() : self.player.pauseVideo(); };
			var updateTime	= function () { self.time(newTime, true); };

			if (nowPlaying.track != self.currentTrack) {
				self.loadTrack(nowPlaying.track, function () {
					self.syncTimeouts[0]	= window.setTimeout(function () {
						if (nowPlaying.track == self.currentTrack) {
							self.player.pauseVideo();
						}
						self.syncTimeouts[1]	= window.setTimeout(function () {
							if (nowPlaying.track == self.currentTrack) {
								self.play(nowPlaying.isPlaying, true);
								updateTime();
								ui.slider.animatedSetValue(newTime);
							}
						}, 3000);
					}, 3000);
				}, true);
			}
			else {
				updatePlay();
				updateTime();
			}

			ui.update();
		});
	});
};

self.time	= function (newTime, noUpdate) {
	newTime	= newTime === 0 ? 1 : newTime;

	if (newTime && Math.abs(newTime - self.time()) < 5) {
		return newTime;
	}

	if (newTime) {
		self.newTime	= newTime;

		if (noUpdate != true) {
			self.updateNowPlaying();
		}
		else {
			self.player.seekTo(newTime, true);
		}
	}

	if ((newTime >= self.length() || self.player.getCurrentTime() >= self.length()) && self.isPlaying) {
		self.isPlaying	= false;
		self.newTime	= 0;
		ui.update();
	}

	self.newTime			= self.player.getCurrentTime() || self.newTime;
	self.newTimeProcessed	= self.processTime(self.newTime);

	if (self.newTime) {
		datastore.user().nowPlayingChild.time.set(self.newTime);
	}

	return self.newTime;
};

self.updateNowPlaying	= function () {
	datastore.user().nowPlaying.set({
		isPlaying: self.isPlaying,
		lastChange: Date.now(),
		time: self.newTime,
		track: self.currentTrack
	});

	ui.update();
};

self.volume	= function (newVolume) {
	if (!isNaN(newVolume)) {
		self.player.setVolume(newVolume);
	}

	return self.player.getVolume();
};

};
<|endoftext|>