<commit_before>var getRentForm = document.getElementById('propertyDetails');
getRentForm.addEventListener('submit', handleFormSubmit);
var counter = 0;
window.addEventListener('load', initializeIndex)

function initializeIndex(){
  if (localStorage.getItem('counter')){
    counter = localStorage.getItem('counter');
  }
}

function Property(type, rent, sqFeet, beds, baths, street, zip) {
    this.type = type;
    this.rent = rent;
    this.sqFeet = sqFeet;
    this.beds = beds;
    this.baths = baths;
    this.street = street;
    this.zip = zip;
}

function handleFormSubmit(e) {
  e.preventDefault();

  if(document.getElementById('apartment').checked) {
     var type = 'apartment';
   } else { var type = 'house';
   }

  var rent = document.getElementById('monthlyRent').value;
  var sqFeet = document.getElementById('sq-feet').value;
  var beds = document.getElementById('beds').value;
  var baths = document.getElementById('baths').value;
  var street = document.getElementById('street').value.toString();
  var zip = document.getElementById('zip').value;
  console.log('street =' + street);
  console.log(street);
  console.log(typeof(street));
  console.dir(street);
  localStorage.setItem('mostRecentStreet', street);
  localStorage.setItem('mostRecentZip', zip);

  var objProperty = new Property(type, rent, sqFeet, beds, baths, street, zip);
  addPropertyToStorage(objProperty,counter);
  counter++;
  getZillowResults(street, zip);
}

function addPropertyToStorage(objProperty, counter) {
localStorage.setItem('property'+counter, JSON.stringify(objProperty));
localStorage.setItem('counter', JSON.stringify(counter));
}

//form input validation
//address should contain only alphanumeric characters, used regular expression  http://www.the-art-of-web.com/javascript/validate/

function checkFormInput(getRentForm) {
  var address = document.getElementById('street');
  if (address.value == "" || address.value == "Street address" ) {
      alert('field cannot be empty!');
      address.focus();
      return false;
  }
  //regular expression to match only alphanumeric characters and spaces
  var addressValidation = /^[\w ]+$/;

  if(!addressValidation.test(address.value)) {
      alert('error: the address includes invalid characters');
      address.focus();
      return false;
  }

  return true;
}

  function getZillowResults(address, zip){
    var returnedJson = makeZillowAjaxCall(address, zip, formatZillowResults);
  }

  function formatZillowResults(returnedJson){
    console.log(returnedJson['SearchResults:searchresults']['response']['results']['result']);
    var result = returnedJson['SearchResults:searchresults']['response']['results']['result'];
    storeZillowInLs(result);
  }

  function storeZillowInLs(result) {
    localStorage.setItem('mostRecentLat', parseFloat(result['address']['latitude']['#text']));
    localStorage.setItem('mostRecentLong', parseFloat(result['address']['longitude']['#text']));
    localStorage.setItem('mostRecentRentEstimate', parseFloat(result['rentzestimate']['amount']['#text']));
    localStorage.setItem('mostRecentCounter', counter - 1);
  }
  //using a CORS proxy at https://crossorigin.me/
  function makeZillowAjaxCall(address, zip, callbackFunction){
    var inputAddress = address;
    var formattedAddress = inputAddress.replace(/ /g, '-');
    // var zipCode = zip.toString();
    var cityStateZip = zip.toString();
    var url = 'http://crossorigin.me/' + 'http://www.zillow.com/webservice/GetSearchResults.htm?zws-id=X1-ZWz19vtt4r677v_3v2ae&address=' + formattedAddress + '&citystatezip=' + cityStateZip + '&rentzestimate=true';
    console.log(url);

    $.ajax({
      type: 'GET',
      url: url,
      dataType: 'xml',
      success: function (xml){
        console.log(xml);
        var returnedJson = xmlToJson(xml);
        console.log(returnedJson);
        callbackFunction(returnedJson);
      },
      error: function(){
        console.log('error');
      }
    });

  }

  //code taken from https://davidwalsh.name/convert-xml-json
  function xmlToJson(xml) {
  	// Create the return object
  	var obj = {};
  	if (xml.nodeType == 1) { // element
  		// do attributes
  		if (xml.attributes.length > 0) {
  		obj["@attributes"] = {};
  			for (var j = 0; j < xml.attributes.length; j++) {
  				var attribute = xml.attributes.item(j);
  				obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
  			}
  		}
  	} else if (xml.nodeType == 3) { // text
  		obj = xml.nodeValue;
  	}
    // do children
  	if (xml.hasChildNodes()) {
  		for(var i = 0; i < xml.childNodes.length; i++) {
  			var item = xml.childNodes.item(i);
  			var nodeName = item.nodeName;
  			if (typeof(obj[nodeName]) == "undefined") {
  				obj[nodeName] = xmlToJson(item);
  			} else {
  				if (typeof(obj[nodeName].push) == "undefined") {
  					var old = obj[nodeName];
  					obj[nodeName] = [];
  					obj[nodeName].push(old);
  				}
  				obj[nodeName].push(xmlToJson(item));
  			}
  		}
  	}
  	return obj;
  };
<commit_msg>added send to results.html page at end of event handler in submitButton.js<commit_after>var getRentForm = document.getElementById('propertyDetails');
getRentForm.addEventListener('submit', handleFormSubmit);
var counter = 0;
window.addEventListener('load', initializeIndex)

function initializeIndex(){
  if (localStorage.getItem('counter')){
    counter = localStorage.getItem('counter');
  }
}

function Property(type, rent, sqFeet, beds, baths, street, zip) {
    this.type = type;
    this.rent = rent;
    this.sqFeet = sqFeet;
    this.beds = beds;
    this.baths = baths;
    this.street = street;
    this.zip = zip;
}

function handleFormSubmit(e) {
  e.preventDefault();

  if(document.getElementById('apartment').checked) {
     var type = 'apartment';
   } else { var type = 'house';
   }

  var rent = document.getElementById('monthlyRent').value;
  var sqFeet = document.getElementById('sq-feet').value;
  var beds = document.getElementById('beds').value;
  var baths = document.getElementById('baths').value;
  var street = document.getElementById('street').value.toString();
  var zip = document.getElementById('zip').value;
  console.log('street =' + street);
  console.log(street);
  console.log(typeof(street));
  console.dir(street);
  localStorage.setItem('mostRecentStreet', street);
  localStorage.setItem('mostRecentZip', zip);

  var objProperty = new Property(type, rent, sqFeet, beds, baths, street, zip);
  addPropertyToStorage(objProperty,counter);
  counter++;
  getZillowResults(street, zip);
  window.location.href = 'results.html';
}

function addPropertyToStorage(objProperty, counter) {
localStorage.setItem('property'+counter, JSON.stringify(objProperty));
localStorage.setItem('counter', JSON.stringify(counter));
}

//form input validation
//address should contain only alphanumeric characters, used regular expression  http://www.the-art-of-web.com/javascript/validate/

function checkFormInput(getRentForm) {
  var address = document.getElementById('street');
  if (address.value == "" || address.value == "Street address" ) {
      alert('field cannot be empty!');
      address.focus();
      return false;
  }
  //regular expression to match only alphanumeric characters and spaces
  var addressValidation = /^[\w ]+$/;

  if(!addressValidation.test(address.value)) {
      alert('error: the address includes invalid characters');
      address.focus();
      return false;
  }

  return true;
}

  function getZillowResults(address, zip){
    var returnedJson = makeZillowAjaxCall(address, zip, formatZillowResults);
  }

  function formatZillowResults(returnedJson){
    console.log(returnedJson['SearchResults:searchresults']['response']['results']['result']);
    var result = returnedJson['SearchResults:searchresults']['response']['results']['result'];
    storeZillowInLs(result);
  }

  function storeZillowInLs(result) {
    localStorage.setItem('mostRecentLat', parseFloat(result['address']['latitude']['#text']));
    localStorage.setItem('mostRecentLong', parseFloat(result['address']['longitude']['#text']));
    localStorage.setItem('mostRecentRentEstimate', parseFloat(result['rentzestimate']['amount']['#text']));
    localStorage.setItem('mostRecentCounter', counter - 1);
  }
  //using a CORS proxy at https://crossorigin.me/
  function makeZillowAjaxCall(address, zip, callbackFunction){
    var inputAddress = address;
    var formattedAddress = inputAddress.replace(/ /g, '-');
    // var zipCode = zip.toString();
    var cityStateZip = zip.toString();
    var url = 'http://crossorigin.me/' + 'http://www.zillow.com/webservice/GetSearchResults.htm?zws-id=X1-ZWz19vtt4r677v_3v2ae&address=' + formattedAddress + '&citystatezip=' + cityStateZip + '&rentzestimate=true';
    console.log(url);

    $.ajax({
      type: 'GET',
      url: url,
      dataType: 'xml',
      success: function (xml){
        console.log(xml);
        var returnedJson = xmlToJson(xml);
        console.log(returnedJson);
        callbackFunction(returnedJson);
      },
      error: function(){
        console.log('error');
      }
    });

  }

  //code taken from https://davidwalsh.name/convert-xml-json
  function xmlToJson(xml) {
  	// Create the return object
  	var obj = {};
  	if (xml.nodeType == 1) { // element
  		// do attributes
  		if (xml.attributes.length > 0) {
  		obj["@attributes"] = {};
  			for (var j = 0; j < xml.attributes.length; j++) {
  				var attribute = xml.attributes.item(j);
  				obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
  			}
  		}
  	} else if (xml.nodeType == 3) { // text
  		obj = xml.nodeValue;
  	}
    // do children
  	if (xml.hasChildNodes()) {
  		for(var i = 0; i < xml.childNodes.length; i++) {
  			var item = xml.childNodes.item(i);
  			var nodeName = item.nodeName;
  			if (typeof(obj[nodeName]) == "undefined") {
  				obj[nodeName] = xmlToJson(item);
  			} else {
  				if (typeof(obj[nodeName].push) == "undefined") {
  					var old = obj[nodeName];
  					obj[nodeName] = [];
  					obj[nodeName].push(old);
  				}
  				obj[nodeName].push(xmlToJson(item));
  			}
  		}
  	}
  	return obj;
  };
<|endoftext|>


<commit_before>/**
 * Created by slanska on 28.09.2015.
 */

<commit_msg>Delete config.js<commit_after><|endoftext|>


<commit_before>/*
 * == BSD2 LICENSE ==
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 * == BSD2 LICENSE ==
 */

var _ = require('lodash');
var d3 = require('d3');

var validate = require('./validation/validate');

var TidelineCrossFilter = require('./data/util/tidelinecrossfilter');
var BasalUtil = require('./data/basalutil');
var BolusUtil = require('./data/bolusutil');
var BGUtil = require('./data/bgutil');
var SettingsUtil = require('./data/settingsutil');
var dt = require('./data/util/datetime');

var log = require('bows')('TidelineData');

function TidelineData(data, opts) {

  var REQUIRED_TYPES = ['basal', 'bolus', 'wizard', 'cbg', 'message', 'smbg', 'settings'];

  opts = opts || {};

  var defaults = {
    CBG_PERCENT_FOR_ENOUGH: 0.75,
    CBG_MAX_DAILY: 288,
    SMBG_DAILY_MIN: 4,
    fillOpts: {
      classes: {
        0: 'darkest',
        3: 'dark',
        6: 'lighter',
        9: 'light',
        12: 'lightest',
        15: 'lighter',
        18: 'dark',
        21: 'darker'
      },
      duration: 3
    },
    diabetesDataTypes: [
      'smbg',
      'carbs',
      'bolus',
      'cbg',
      'settings',
      'basal-rate-segment'
    ]
  };

  _.defaults(opts, defaults);
  var that = this;

  function checkRequired() {
    _.each(REQUIRED_TYPES, function(type) {
      if (!that.grouped[type]) {
        log('No', type, 'data! Replaced with empty array.');
        that.grouped[type] = [];
      }
    });

    return that;
  }

  function addAndResort(datum, a) {
    return _.sortBy((function() {
      a.push(datum);
      return a;
    }()), function(d) { return d.normalTime; });
  }

  function updateCrossFilters(data) {
    that.filterData = new TidelineCrossFilter(data);
    that.dataByDate = that.createCrossFilter('date');
    that.dataById = that.createCrossFilter('id');
    that.dataByType = that.createCrossFilter('datatype');
  }

  this.createCrossFilter = function(dim) {
    return this.filterData.addDimension(dim);
  };

  this.addDatum = function(datum) {
    this.grouped[datum.type] = addAndResort(datum, this.grouped[datum.type]);
    this.data = addAndResort(datum, this.data);
    updateCrossFilters(this.data);
    return this;
  };

  this.editDatum = function(datum, timeKey) {
    this.dataById.filter(datum.id);
    var newDatum = this.filterData.getOne(this.dataById);
    // because some timestamps are deviceTime, some are utcTime
    newDatum[timeKey] = datum[timeKey];
    // everything has normalTime
    newDatum.normalTime = datum.normalTime;
    // remove pre-updated datum and add updated
    this.filterData.remove();
    this.filterData.add(newDatum);
    // clear filters
    this.dataById.filter(null);
    this.dataByDate.filter(null);
    return this;
  };

  function fillDataFromInterval(first, last) {
    var data = [];
    var points = d3.time.hour.utc.range(first, last, opts.fillOpts.duration);
    for (var i = 0; i < points.length; ++i) {
      if (i !== points.length - 1) {
        data.push({
          fillColor: opts.fillOpts.classes[points[i].getUTCHours()],
          id: 'fill_' + points[i].toISOString().replace(/[^\w\s]|_/g, ''),
          normalEnd: points[i + 1].toISOString(),
          normalTime: points[i].toISOString(),
          type: 'fill'
        });
      }
    }
    return data;
  }

  function getTwoWeekFillEndpoints() {
    var data;
    if (that.grouped.smbg && that.grouped.smbg.length !== 0) {
      data = that.grouped.smbg;
    }
    else {
      data = that.diabetesData;
    }
    var first = data[0].normalTime, last = data[data.length - 1].normalTime;
    return [dt.getMidnight(first), dt.getMidnight(last, true)];
  }

  this.generateFillData = function() {
    var lastDatum = data[data.length - 1];
    // the fill should extend past the *end* of a segment (i.e. of basal data)
    // if that's the last datum in the data
    var lastTimestamp = lastDatum.normalEnd || lastDatum.normalTime;
    var first = new Date(data[0].normalTime), last = new Date(lastTimestamp);
    // make sure we encapsulate the domain completely by padding the start and end with twice the duration
    first.setUTCHours(first.getUTCHours() - first.getUTCHours() % opts.fillOpts.duration - (opts.fillOpts.duration * 2));
    last.setUTCHours(last.getUTCHours() + last.getUTCHours() % opts.fillOpts.duration + (opts.fillOpts.duration * 2));
    this.grouped.fill = fillDataFromInterval(first, last);
    return this;
  };

  // two-week view requires background fill rectangles from midnight to midnight
  // for each day from the first through last days where smbg exists at all
  this.adjustFillsForTwoWeekView = function() {
    var fillData = this.grouped.fill;
    var endpoints = getTwoWeekFillEndpoints();
    var startOfTwoWeekFill = endpoints[0], endOfTwoWeekFill = endpoints[1];
    var startOfFill = fillData[0].normalEnd, endOfFill = fillData[fillData.length - 1].normalEnd;
    this.twoWeekData = this.grouped.smbg || [];
    var twoWeekFills = [];
    for (var i = 0; i < this.grouped.fill.length; ++i) {
      var d = this.grouped.fill[i];
      if (d.normalTime >= startOfFill || d.normalTime <= endOfFill) {
        twoWeekFills.push(d);
      }
    }

    // first, fill in two week fills where potentially missing at the end of data domain
    if (endOfTwoWeekFill > endOfFill) {
      var end = new Date(endOfTwoWeekFill);
      // intervals are exclusive of endpoint, so
      // to get last segment, need to extend endpoint out +1
      end.setUTCHours(end.getUTCHours() + 3);
      twoWeekFills = twoWeekFills.concat(
        fillDataFromInterval(new Date(endOfFill),end)
      );
    }
    else {
      // filter out any fills from two week fills that go beyond extent of smbg data
      twoWeekFills = _.reject(twoWeekFills, function(d) {
        return d.normalTime >= endOfTwoWeekFill;
      });
    }

    // similarly, fill in two week fills where potentially missing at the beginning of data domain
    if (startOfTwoWeekFill < startOfFill) {
      twoWeekFills = twoWeekFills.concat(
        fillDataFromInterval(new Date(startOfTwoWeekFill), new Date(startOfFill))
      );
    }
    else {
      // filter out any fills from two week fills that go beyond extent of smbg data
      twoWeekFills = _.reject(twoWeekFills, function(d) {
        return d.normalTime < startOfTwoWeekFill;
      });
    }

    this.twoWeekData = _.sortBy(this.twoWeekData.concat(twoWeekFills), function(d) {
      return d.normalTime;
    });
  };

  this.setBGCategories = function() {
    var units = _.uniq(_.pluck(this.grouped.smbg.concat(this.grouped.cbg), 'units'));
    if (units.length > 1) {
      log(new Error('Your BG data is of mixed units; I have no idea how to display it :('));
      this.bgUnits = null;
    }
    else {
      this.bgUnits = units[0];
    }

    var classes = {
      'very-low': {boundary: 60},
      low: {boundary: 80},
      target: {boundary: 180},
      high: {boundary: 200},
      'very-high': {boundary: 300}
    };

    if (this.bgUnits === 'mmol/L') {
      var GLUCOSE_MM = 18.01559;
      for (var key in classes) {
        if (key === 'units') {
          classes[key] = 'mmol/L';
        }
        else {
          classes[key].boundary = classes[key].boundary/GLUCOSE_MM;
        }
      }
    }
    this.bgClasses = classes;
  };

  log('Items to validate:', data.length);

  console.time('Validation in');
  var res = validate.validateAll(data);
  console.timeEnd('Validation in');

  log('Valid items:', res.valid.length);
  log('Invalid items:', res.invalid.length);

  data = res.valid;

  this.grouped = _.groupBy(data, function(d) { return d.type; });

  this.diabetesData = _.sortBy(_.flatten([].concat(_.map(opts.diabetesDataTypes, function(type) {
    return this.grouped[type] || [];
  }, this))), function(d) {
    return d.normalTime;
  });

  this.setBGCategories();

  this.basalUtil = new BasalUtil(this.grouped.basal);
  this.bolusUtil = new BolusUtil(this.grouped.bolus);
  this.cbgUtil = new BGUtil(this.grouped.cbg, {
    bgUnits: this.bgUnits,
    categories: this.bgClasses,
    DAILY_MIN: (opts.CBG_PERCENT_FOR_ENOUGH * opts.CBG_MAX_DAILY)
  });
  this.smbgUtil = new BGUtil(this.grouped.smbg, {
    bgUnits: this.bgUnits,
    categories: this.bgClasses,
    DAILY_MIN: opts.SMBG_DAILY_MIN
  });

  if (data.length > 0 && !_.isEmpty(this.diabetesData)) {
    this.settingsUtil = new SettingsUtil(this.grouped.settings || [], [this.diabetesData[0].normalTime, this.diabetesData[this.diabetesData.length - 1].normalTime]);
    this.settingsUtil.getAllSchedules(this.settingsUtil.endpoints[0], this.settingsUtil.endpoints[1]);
    var segmentsBySchedule = this.settingsUtil.annotateBasalSettings(this.basalUtil.actual);
    this.grouped['basal-settings-segment'] = [];
    for (var key in segmentsBySchedule) {
      this.grouped['basal-settings-segment'] = this.grouped['basal-settings-segment'].concat(segmentsBySchedule[key]);
    }
    this.data = _.sortBy(data.concat(this.grouped['basal-settings-segment']), function(d) {
      return d.normalTime;
    });

    this.generateFillData().adjustFillsForTwoWeekView();
    this.data = _.sortBy(this.data.concat(this.grouped.fill), function(d) { return d.normalTime; });
  }
  else {
    this.data = [];
  }

  updateCrossFilters(this.data);

  return checkRequired(this);
}

module.exports = TidelineData;
<commit_msg>only time validation when running in browser<commit_after>/*
 * == BSD2 LICENSE ==
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 * == BSD2 LICENSE ==
 */

var _ = require('lodash');
var d3 = require('d3');

var validate = require('./validation/validate');

var TidelineCrossFilter = require('./data/util/tidelinecrossfilter');
var BasalUtil = require('./data/basalutil');
var BolusUtil = require('./data/bolusutil');
var BGUtil = require('./data/bgutil');
var SettingsUtil = require('./data/settingsutil');
var dt = require('./data/util/datetime');

var log = require('bows')('TidelineData');

function TidelineData(data, opts) {

  var REQUIRED_TYPES = ['basal', 'bolus', 'wizard', 'cbg', 'message', 'smbg', 'settings'];

  opts = opts || {};

  var defaults = {
    CBG_PERCENT_FOR_ENOUGH: 0.75,
    CBG_MAX_DAILY: 288,
    SMBG_DAILY_MIN: 4,
    fillOpts: {
      classes: {
        0: 'darkest',
        3: 'dark',
        6: 'lighter',
        9: 'light',
        12: 'lightest',
        15: 'lighter',
        18: 'dark',
        21: 'darker'
      },
      duration: 3
    },
    diabetesDataTypes: [
      'smbg',
      'carbs',
      'bolus',
      'cbg',
      'settings',
      'basal-rate-segment'
    ]
  };

  _.defaults(opts, defaults);
  var that = this;

  function checkRequired() {
    _.each(REQUIRED_TYPES, function(type) {
      if (!that.grouped[type]) {
        log('No', type, 'data! Replaced with empty array.');
        that.grouped[type] = [];
      }
    });

    return that;
  }

  function addAndResort(datum, a) {
    return _.sortBy((function() {
      a.push(datum);
      return a;
    }()), function(d) { return d.normalTime; });
  }

  function updateCrossFilters(data) {
    that.filterData = new TidelineCrossFilter(data);
    that.dataByDate = that.createCrossFilter('date');
    that.dataById = that.createCrossFilter('id');
    that.dataByType = that.createCrossFilter('datatype');
  }

  this.createCrossFilter = function(dim) {
    return this.filterData.addDimension(dim);
  };

  this.addDatum = function(datum) {
    this.grouped[datum.type] = addAndResort(datum, this.grouped[datum.type]);
    this.data = addAndResort(datum, this.data);
    updateCrossFilters(this.data);
    return this;
  };

  this.editDatum = function(datum, timeKey) {
    this.dataById.filter(datum.id);
    var newDatum = this.filterData.getOne(this.dataById);
    // because some timestamps are deviceTime, some are utcTime
    newDatum[timeKey] = datum[timeKey];
    // everything has normalTime
    newDatum.normalTime = datum.normalTime;
    // remove pre-updated datum and add updated
    this.filterData.remove();
    this.filterData.add(newDatum);
    // clear filters
    this.dataById.filter(null);
    this.dataByDate.filter(null);
    return this;
  };

  function fillDataFromInterval(first, last) {
    var data = [];
    var points = d3.time.hour.utc.range(first, last, opts.fillOpts.duration);
    for (var i = 0; i < points.length; ++i) {
      if (i !== points.length - 1) {
        data.push({
          fillColor: opts.fillOpts.classes[points[i].getUTCHours()],
          id: 'fill_' + points[i].toISOString().replace(/[^\w\s]|_/g, ''),
          normalEnd: points[i + 1].toISOString(),
          normalTime: points[i].toISOString(),
          type: 'fill'
        });
      }
    }
    return data;
  }

  function getTwoWeekFillEndpoints() {
    var data;
    if (that.grouped.smbg && that.grouped.smbg.length !== 0) {
      data = that.grouped.smbg;
    }
    else {
      data = that.diabetesData;
    }
    var first = data[0].normalTime, last = data[data.length - 1].normalTime;
    return [dt.getMidnight(first), dt.getMidnight(last, true)];
  }

  this.generateFillData = function() {
    var lastDatum = data[data.length - 1];
    // the fill should extend past the *end* of a segment (i.e. of basal data)
    // if that's the last datum in the data
    var lastTimestamp = lastDatum.normalEnd || lastDatum.normalTime;
    var first = new Date(data[0].normalTime), last = new Date(lastTimestamp);
    // make sure we encapsulate the domain completely by padding the start and end with twice the duration
    first.setUTCHours(first.getUTCHours() - first.getUTCHours() % opts.fillOpts.duration - (opts.fillOpts.duration * 2));
    last.setUTCHours(last.getUTCHours() + last.getUTCHours() % opts.fillOpts.duration + (opts.fillOpts.duration * 2));
    this.grouped.fill = fillDataFromInterval(first, last);
    return this;
  };

  // two-week view requires background fill rectangles from midnight to midnight
  // for each day from the first through last days where smbg exists at all
  this.adjustFillsForTwoWeekView = function() {
    var fillData = this.grouped.fill;
    var endpoints = getTwoWeekFillEndpoints();
    var startOfTwoWeekFill = endpoints[0], endOfTwoWeekFill = endpoints[1];
    var startOfFill = fillData[0].normalEnd, endOfFill = fillData[fillData.length - 1].normalEnd;
    this.twoWeekData = this.grouped.smbg || [];
    var twoWeekFills = [];
    for (var i = 0; i < this.grouped.fill.length; ++i) {
      var d = this.grouped.fill[i];
      if (d.normalTime >= startOfFill || d.normalTime <= endOfFill) {
        twoWeekFills.push(d);
      }
    }

    // first, fill in two week fills where potentially missing at the end of data domain
    if (endOfTwoWeekFill > endOfFill) {
      var end = new Date(endOfTwoWeekFill);
      // intervals are exclusive of endpoint, so
      // to get last segment, need to extend endpoint out +1
      end.setUTCHours(end.getUTCHours() + 3);
      twoWeekFills = twoWeekFills.concat(
        fillDataFromInterval(new Date(endOfFill),end)
      );
    }
    else {
      // filter out any fills from two week fills that go beyond extent of smbg data
      twoWeekFills = _.reject(twoWeekFills, function(d) {
        return d.normalTime >= endOfTwoWeekFill;
      });
    }

    // similarly, fill in two week fills where potentially missing at the beginning of data domain
    if (startOfTwoWeekFill < startOfFill) {
      twoWeekFills = twoWeekFills.concat(
        fillDataFromInterval(new Date(startOfTwoWeekFill), new Date(startOfFill))
      );
    }
    else {
      // filter out any fills from two week fills that go beyond extent of smbg data
      twoWeekFills = _.reject(twoWeekFills, function(d) {
        return d.normalTime < startOfTwoWeekFill;
      });
    }

    this.twoWeekData = _.sortBy(this.twoWeekData.concat(twoWeekFills), function(d) {
      return d.normalTime;
    });
  };

  this.setBGCategories = function() {
    var units = _.uniq(_.pluck(this.grouped.smbg.concat(this.grouped.cbg), 'units'));
    if (units.length > 1) {
      log(new Error('Your BG data is of mixed units; I have no idea how to display it :('));
      this.bgUnits = null;
    }
    else {
      this.bgUnits = units[0];
    }

    var classes = {
      'very-low': {boundary: 60},
      low: {boundary: 80},
      target: {boundary: 180},
      high: {boundary: 200},
      'very-high': {boundary: 300}
    };

    if (this.bgUnits === 'mmol/L') {
      var GLUCOSE_MM = 18.01559;
      for (var key in classes) {
        if (key === 'units') {
          classes[key] = 'mmol/L';
        }
        else {
          classes[key].boundary = classes[key].boundary/GLUCOSE_MM;
        }
      }
    }
    this.bgClasses = classes;
  };

  log('Items to validate:', data.length);

  var res;
  if (typeof window !== 'undefined') {
    console.time('Validation');
    res = validate.validateAll(data);
    console.timeEnd('Validation');
  }
  else {
    res = validate.validateAll(data);
  }

  log('Valid items:', res.valid.length);
  log('Invalid items:', res.invalid.length);

  data = res.valid;

  this.grouped = _.groupBy(data, function(d) { return d.type; });

  this.diabetesData = _.sortBy(_.flatten([].concat(_.map(opts.diabetesDataTypes, function(type) {
    return this.grouped[type] || [];
  }, this))), function(d) {
    return d.normalTime;
  });

  this.setBGCategories();

  this.basalUtil = new BasalUtil(this.grouped.basal);
  this.bolusUtil = new BolusUtil(this.grouped.bolus);
  this.cbgUtil = new BGUtil(this.grouped.cbg, {
    bgUnits: this.bgUnits,
    categories: this.bgClasses,
    DAILY_MIN: (opts.CBG_PERCENT_FOR_ENOUGH * opts.CBG_MAX_DAILY)
  });
  this.smbgUtil = new BGUtil(this.grouped.smbg, {
    bgUnits: this.bgUnits,
    categories: this.bgClasses,
    DAILY_MIN: opts.SMBG_DAILY_MIN
  });

  if (data.length > 0 && !_.isEmpty(this.diabetesData)) {
    this.settingsUtil = new SettingsUtil(this.grouped.settings || [], [this.diabetesData[0].normalTime, this.diabetesData[this.diabetesData.length - 1].normalTime]);
    this.settingsUtil.getAllSchedules(this.settingsUtil.endpoints[0], this.settingsUtil.endpoints[1]);
    var segmentsBySchedule = this.settingsUtil.annotateBasalSettings(this.basalUtil.actual);
    this.grouped['basal-settings-segment'] = [];
    for (var key in segmentsBySchedule) {
      this.grouped['basal-settings-segment'] = this.grouped['basal-settings-segment'].concat(segmentsBySchedule[key]);
    }
    this.data = _.sortBy(data.concat(this.grouped['basal-settings-segment']), function(d) {
      return d.normalTime;
    });

    this.generateFillData().adjustFillsForTwoWeekView();
    this.data = _.sortBy(this.data.concat(this.grouped.fill), function(d) { return d.normalTime; });
  }
  else {
    this.data = [];
  }

  updateCrossFilters(this.data);

  return checkRequired(this);
}

module.exports = TidelineData;
<|endoftext|>


<commit_before>/**
    ParkingPlan is a program that maps the parking schedules across the streets of the World.
    Copyright (C) <2014>  <Evgeniy Ivlev>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    You can contact me at jenia.ivlev@gmail.com.
**/

//this might be confusing.
//There's the Map object. The one in file Map.js.
//There's also the map from OpenLayers.
//This particular variable, called map, is the OpenLayers' map.

var error_flag = false;
var entry_point;
function Entry_Point(){
    this.get_csrf_cookie();

    var self = this;
	var screen_size = $.mobile.getScreenHeight() - parseInt($("[data-role=content]").css("padding-bottom")) - parseInt($("[data-role=content]").css("padding-top"));
	$("[data-role=content]").css("height", screen_size)
	$('#dialog-page').on("pagebeforehide", function(event, data){
            if(data.nextPage[0].id == "index"){
                $("#dialog-page [data-role=listview]").children().slice(0, $("#dialog-page [data-role=listview]").children().length -4).remove();
                map.highlightctrl.unselectAll()
            }
	})
	$.mobile.pageContainer.on("pagechange", function(event, data){

		if(data.absUrl == undefined){//if it back to the root
		    //map.selectctrl.unselectAll();
		} else if(data.absUrl.search("dialog-page") > -1){
                    if(!error_flag){
			Forbidden_Slot_Array.prototype.add_forbidden_slots.call(map.forbidden_slots_array);

                    }else{
                        error_flag = false;
                    }

		}
	});

   $('#where-am-i').on('click', function(){
        self.find_gps(function(e) {
            var zoom = 16;
            var location = new OpenLayers.LonLat(e.coords.longitude, e.coords.latitude).transform(map.epsg4326,map.epsg900913);
            map.marker.removeMarker(map.marker.markers[0]);
            map.map.setCenter(location, zoom);
            self.place_marker(location);
            map.vectors.removeAllFeatures();
            map.output_layer.removeAllFeatures();
            self.get_streets();
        }, function(e) {

        });

       $.mobile.changePage("#index", {transition : "pop", role : "page"});
    });

    $("#login-list-option").on("click", function(){
        $.mobile.changePage("#login-options-list-page", {transition: 'pop'});
    });

    $("#parking-plan-login").on("click", function(){
        window.location=domain+"/login";
    });
    $("#google-login").on("click", function(){
        window.location=domain+"/login/google-oauth2/";
    });

    $("#get-all-streets").on("click", function(){
	map.vectors.removeAllFeatures();
	map.output_layer.removeAllFeatures();
        self.get_streets();
    });

}
Entry_Point.prototype.loadMapLibrary = function() {

    this.map = new Map(this);

    this.zoomToDefaultPosition();

},

Entry_Point.prototype.get_csrf_cookie = function (){
    call_server(
        domain+"/set_csrf_cookie",
        function(response){
            console.log(response);
            var json = JSON.parse(response);
            csrf_token = json.csrf_token;
            setup_ajax();
        },
        "",
        "GET",
        function(){},
        function(){}
    );

}

Entry_Point.prototype.register_listener = function(call_back){
    this.call_backs.add(call_back);
}

Entry_Point.prototype.notify_listeners = function(){
    this.call_backs.map(function(call_back){
	call_back();
    });
}

Entry_Point.prototype.zoomToDefaultPosition = function() {
    Entry_Point.prototype.zoomToPosition.call(this,16);
},

Entry_Point.prototype.get_streets = function(){
    var $this = $( this ),
    theme = $this.jqmData( "theme" ) || $.mobile.loader.prototype.options.theme,
    msgText = $this.jqmData( "msgtext" ) || $.mobile.loader.prototype.options.text,
    textVisible = $this.jqmData( "textvisible" ) || $.mobile.loader.prototype.options.textVisible,
    textonly = !!$this.jqmData( "textonly" );
    html = $this.jqmData( "html" ) || "";
    $.mobile.loading("show", {
        text: msgText,
        textVisible: textVisible,
        theme: theme,
        textonly: textonly,
        html: html
    })
    var epsg4326 = new OpenLayers.Projection("EPSG:4326");
    var epsg900913 = new OpenLayers.Projection("EPSG:900913");
    var self = this;
    call_server(domain+"/get_all_streets/?extent=" + new OpenLayers.Geometry.Point(map.map.center.lon, map.map.center.lat).transform(epsg900913, epsg4326).toString(),
		function(text){
                    var json = eval('(' + text + ')');
                    Entry_Point.prototype.draw_streets.call(self, json.streets);
                    $.mobile.loading("hide");
                    $.mobile.changePage("#index", {transition : "pop", role : "page"});
                }, "", "GET");
},

Entry_Point.prototype.draw_streets = function(streets, availability_flag){
    var epsg4326 = new OpenLayers.Projection("EPSG:4326");
    var epsg900913 = new OpenLayers.Projection("EPSG:900913");
    var pnts = [];
    var features_streets = [];
    for (var i = 0; i < streets.length; i++){
        for(var j = 0; j < streets[i].coordinates.length; j++){
            pnts.push(new OpenLayers.Geometry.Point(streets[i].coordinates[j][0], streets[i].coordinates[j][1]).transform(epsg4326, epsg900913 ));
        }
        ls = new OpenLayers.Geometry.LineString(pnts);
        ls.pk = streets[i].pk;
        v = new OpenLayers.Feature.Vector(ls);
        map.vectors.addFeatures(v);
        if(availability_flag){
            map.vectors.features[map.vectors.features.length-1].style= {
                                                                            fillColor : "#00FF00",
                                                                            strokeColor: "#00FF00",
                                                                            strokeWidth : 25,
                                                                            strokeOpacity:0.3,
                                                                            fillOpacity: 0.3,
                                                                        };
        }
        pnts = [];
    }
    if(availability_flag){
        map.vectors.redraw();
    }

}

Entry_Point.prototype.zoomToPosition = function(zoom) {
    var fromProjection = new OpenLayers.Projection("EPSG:4326");
    var epsg4326 = new OpenLayers.Projection("EPSG:4326");
    var toProjection = new OpenLayers.Projection("EPSG:900913");
    var epsg900913 = new OpenLayers.Projection("EPSG:900913");
    var lon_lat=new OpenLayers.LonLat( -73.6207, 45.5000).transform(map.epsg4326,map.epsg900913);
    var self = this;
    this.find_gps(function(e) {
        /**
           Uncomment the following line if you want the initial position to be your GPS position
        **/

	//var location = new OpenLayers.LonLat(e.coords.longitude, e.coords.latitude).transform(map.epsg4326,map.epsg900913);

        /**
           Default GPS coordinates made to match the sample data
        **/
        var location = new OpenLayers.LonLat(-73.63961, 45.46610).transform(map.epsg4326,map.epsg900913);
	map.map.setCenter(location, zoom);
        self.place_marker(location);
        self.get_streets();
    }, function(e) {
	map.map.setCenter(lon_lat, zoom);

    });
}

Entry_Point.prototype.find_gps = function(success, failure){
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(success);
    }
}

Entry_Point.prototype.place_marker = function(lonlat){
        var size = new OpenLayers.Size(21,25);
        var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
        var icon = new OpenLayers.Icon('http://www.openlayers.org/dev/img/marker.png', size, offset);
        map.marker.addMarker(new OpenLayers.Marker(lonlat));
}

function nachat(){

            user.construct_user();
            new FetchAvailableParkingSlot();
            var pathname = document.URL;
            var index_url = new RegExp(domain + '/static/index.html$');
            entry_point = new Entry_Point();
            $.mobile.pageContainer.on("pagechange", function(event, data){
                if(!map && data.absUrl.match(index_url)){
                    entry_point = new Entry_Point();
                    Entry_Point.prototype.loadMapLibrary.call(entry_point);
                }
            });
            if(pathname.match(index_url)){
                Entry_Point.prototype.loadMapLibrary.call(entry_point);
            }
    //app.initialize();
}

//NEW CLASS

function find_selected_option(options){
    for (var i=0; i<options.length; i++){
        if(options[i].selected){
            return options[i].value;
        }
    }
    return {};
}

function FetchAvailableParkingSlot(){

    var self = this;
    $("#availability-constraints-dialog [type=button]").on("click", function(){
        map.output_layer.removeAllFeatures();
        map.vectors.removeAllFeatures();
        self.fetch();
    });
    availability_constraints_flag = true;

}

FetchAvailableParkingSlot.prototype.fetch = function(){
    var epsg4326 = new OpenLayers.Projection("EPSG:4326");
    var epsg900913 = new OpenLayers.Projection("EPSG:900913");
    var duration = $("#allowed-duration").find(":selected").text();
    duration = duration.slice(0, duration.length -4);

    var all_inputs = $("#availability-constraints-dialog").find(":input");
    var name;
    var value;
    var submission_string = "";
    for(var i = 0; i<all_inputs.length; i++){
        name = all_inputs[i].name;
        value = all_inputs[i].value;
        submission_string += name + "=" + value + "&";
    }

    submission_string +="allowed-duration=" + duration;
    call_server(
        domain+"/get_available_streets",
        function(text){
                    var streets = eval('(' + text + ')');
                    var availability_flag = true;
                    Entry_Point.prototype.draw_streets.call(entry_point, streets, availability_flag);
                    $.mobile.changePage("#index", {transition : "pop", role : "page"});
        },
        submission_string + "&extent=" + new OpenLayers.Geometry.Point(map.map.center.lon, map.map.center.lat).transform(epsg900913, epsg4326).toString(),
        "GET"
    );
}

<commit_msg>do not create a new Entry_Point when loading index.html Its not needed to create a new Entry_Point when index.html loads because one is immediately created when nachat() executes. Creating new Entry_Point duplicates all the listeners.<commit_after>/**
    ParkingPlan is a program that maps the parking schedules across the streets of the World.
    Copyright (C) <2014>  <Evgeniy Ivlev>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    You can contact me at jenia.ivlev@gmail.com.
**/

//this might be confusing.
//There's the Map object. The one in file Map.js.
//There's also the map from OpenLayers.
//This particular variable, called map, is the OpenLayers' map.

var error_flag = false;
var entry_point;
function Entry_Point(){
    this.get_csrf_cookie();

    var self = this;
	var screen_size = $.mobile.getScreenHeight() - parseInt($("[data-role=content]").css("padding-bottom")) - parseInt($("[data-role=content]").css("padding-top"));
	$("[data-role=content]").css("height", screen_size)
	$('#dialog-page').on("pagebeforehide", function(event, data){
            if(data.nextPage[0].id == "index"){
                $("#dialog-page [data-role=listview]").children().slice(0, $("#dialog-page [data-role=listview]").children().length -4).remove();
                map.highlightctrl.unselectAll()
            }
	})
	$.mobile.pageContainer.on("pagechange", function(event, data){

		if(data.absUrl == undefined){//if it back to the root
		    //map.selectctrl.unselectAll();
		} else if(data.absUrl.search("dialog-page") > -1){
                    if(!error_flag){
			Forbidden_Slot_Array.prototype.add_forbidden_slots.call(map.forbidden_slots_array);

                    }else{
                        error_flag = false;
                    }

		}
	});

   $('#where-am-i').on('click', function(){
        self.find_gps(function(e) {
            var zoom = 16;
            var location = new OpenLayers.LonLat(e.coords.longitude, e.coords.latitude).transform(map.epsg4326,map.epsg900913);
            map.marker.removeMarker(map.marker.markers[0]);
            map.map.setCenter(location, zoom);
            self.place_marker(location);
            map.vectors.removeAllFeatures();
            map.output_layer.removeAllFeatures();
            self.get_streets();
        }, function(e) {

        });

       $.mobile.changePage("#index", {transition : "pop", role : "page"});
    });

    $("#login-list-option").on("click", function(){
        $.mobile.changePage("#login-options-list-page", {transition: 'pop'});
    });

    $("#parking-plan-login").on("click", function(){
        window.location=domain+"/login";
    });
    $("#google-login").on("click", function(){
        window.location=domain+"/login/google-oauth2/";
    });

    $("#get-all-streets").on("click", function(){
	map.vectors.removeAllFeatures();
	map.output_layer.removeAllFeatures();
        self.get_streets();
    });

}
Entry_Point.prototype.loadMapLibrary = function() {

    this.map = new Map(this);

    this.zoomToDefaultPosition();

},

Entry_Point.prototype.get_csrf_cookie = function (){
    call_server(
        domain+"/set_csrf_cookie",
        function(response){
            console.log(response);
            var json = JSON.parse(response);
            csrf_token = json.csrf_token;
            setup_ajax();
        },
        "",
        "GET",
        function(){},
        function(){}
    );

}

Entry_Point.prototype.register_listener = function(call_back){
    this.call_backs.add(call_back);
}

Entry_Point.prototype.notify_listeners = function(){
    this.call_backs.map(function(call_back){
	call_back();
    });
}

Entry_Point.prototype.zoomToDefaultPosition = function() {
    Entry_Point.prototype.zoomToPosition.call(this,16);
},

Entry_Point.prototype.get_streets = function(){
    var $this = $( this ),
    theme = $this.jqmData( "theme" ) || $.mobile.loader.prototype.options.theme,
    msgText = $this.jqmData( "msgtext" ) || $.mobile.loader.prototype.options.text,
    textVisible = $this.jqmData( "textvisible" ) || $.mobile.loader.prototype.options.textVisible,
    textonly = !!$this.jqmData( "textonly" );
    html = $this.jqmData( "html" ) || "";
    $.mobile.loading("show", {
        text: msgText,
        textVisible: textVisible,
        theme: theme,
        textonly: textonly,
        html: html
    })
    var epsg4326 = new OpenLayers.Projection("EPSG:4326");
    var epsg900913 = new OpenLayers.Projection("EPSG:900913");
    var self = this;
    call_server(domain+"/get_all_streets/?extent=" + new OpenLayers.Geometry.Point(map.map.center.lon, map.map.center.lat).transform(epsg900913, epsg4326).toString(),
		function(text){
                    var json = eval('(' + text + ')');
                    Entry_Point.prototype.draw_streets.call(self, json.streets);
                    $.mobile.loading("hide");
                    $.mobile.changePage("#index", {transition : "pop", role : "page"});
                }, "", "GET");
},

Entry_Point.prototype.draw_streets = function(streets, availability_flag){
    var epsg4326 = new OpenLayers.Projection("EPSG:4326");
    var epsg900913 = new OpenLayers.Projection("EPSG:900913");
    var pnts = [];
    var features_streets = [];
    for (var i = 0; i < streets.length; i++){
        for(var j = 0; j < streets[i].coordinates.length; j++){
            pnts.push(new OpenLayers.Geometry.Point(streets[i].coordinates[j][0], streets[i].coordinates[j][1]).transform(epsg4326, epsg900913 ));
        }
        ls = new OpenLayers.Geometry.LineString(pnts);
        ls.pk = streets[i].pk;
        v = new OpenLayers.Feature.Vector(ls);
        map.vectors.addFeatures(v);
        if(availability_flag){
            map.vectors.features[map.vectors.features.length-1].style= {
                                                                            fillColor : "#00FF00",
                                                                            strokeColor: "#00FF00",
                                                                            strokeWidth : 25,
                                                                            strokeOpacity:0.3,
                                                                            fillOpacity: 0.3,
                                                                        };
        }
        pnts = [];
    }
    if(availability_flag){
        map.vectors.redraw();
    }

}

Entry_Point.prototype.zoomToPosition = function(zoom) {
    var fromProjection = new OpenLayers.Projection("EPSG:4326");
    var epsg4326 = new OpenLayers.Projection("EPSG:4326");
    var toProjection = new OpenLayers.Projection("EPSG:900913");
    var epsg900913 = new OpenLayers.Projection("EPSG:900913");
    var lon_lat=new OpenLayers.LonLat( -73.6207, 45.5000).transform(map.epsg4326,map.epsg900913);
    var self = this;
    this.find_gps(function(e) {
        /**
           Uncomment the following line if you want the initial position to be your GPS position
        **/

	//var location = new OpenLayers.LonLat(e.coords.longitude, e.coords.latitude).transform(map.epsg4326,map.epsg900913);

        /**
           Default GPS coordinates made to match the sample data
        **/
        var location = new OpenLayers.LonLat(-73.63961, 45.46610).transform(map.epsg4326,map.epsg900913);
	map.map.setCenter(location, zoom);
        self.place_marker(location);
        self.get_streets();
    }, function(e) {
	map.map.setCenter(lon_lat, zoom);

    });
}

Entry_Point.prototype.find_gps = function(success, failure){
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(success);
    }
}

Entry_Point.prototype.place_marker = function(lonlat){
        var size = new OpenLayers.Size(21,25);
        var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
        var icon = new OpenLayers.Icon('http://www.openlayers.org/dev/img/marker.png', size, offset);
        map.marker.addMarker(new OpenLayers.Marker(lonlat));
}

function nachat(){

            user.construct_user();
            new FetchAvailableParkingSlot();
            var pathname = document.URL;
            var index_url = new RegExp(domain + '/static/index.html$');
            entry_point = new Entry_Point();
            $.mobile.pageContainer.on("pagechange", function(event, data){
                if(!map && data.absUrl.match(index_url)){
                    Entry_Point.prototype.loadMapLibrary.call(entry_point);
                }
            });
            if(pathname.match(index_url)){
                Entry_Point.prototype.loadMapLibrary.call(entry_point);
            }
    //app.initialize();
}

//NEW CLASS

function find_selected_option(options){
    for (var i=0; i<options.length; i++){
        if(options[i].selected){
            return options[i].value;
        }
    }
    return {};
}

function FetchAvailableParkingSlot(){

    var self = this;
    $("#availability-constraints-dialog [type=button]").on("click", function(){
        map.output_layer.removeAllFeatures();
        map.vectors.removeAllFeatures();
        self.fetch();
    });
    availability_constraints_flag = true;

}

FetchAvailableParkingSlot.prototype.fetch = function(){
    var epsg4326 = new OpenLayers.Projection("EPSG:4326");
    var epsg900913 = new OpenLayers.Projection("EPSG:900913");
    var duration = $("#allowed-duration").find(":selected").text();
    duration = duration.slice(0, duration.length -4);

    var all_inputs = $("#availability-constraints-dialog").find(":input");
    var name;
    var value;
    var submission_string = "";
    for(var i = 0; i<all_inputs.length; i++){
        name = all_inputs[i].name;
        value = all_inputs[i].value;
        submission_string += name + "=" + value + "&";
    }

    submission_string +="allowed-duration=" + duration;
    call_server(
        domain+"/get_available_streets",
        function(text){
                    var streets = eval('(' + text + ')');
                    var availability_flag = true;
                    Entry_Point.prototype.draw_streets.call(entry_point, streets, availability_flag);
                    $.mobile.changePage("#index", {transition : "pop", role : "page"});
        },
        submission_string + "&extent=" + new OpenLayers.Geometry.Point(map.map.center.lon, map.map.center.lat).transform(epsg900913, epsg4326).toString(),
        "GET"
    );
}

<|endoftext|>


<commit_before>import _ from 'underscore';
import $ from 'jquery';
import { setDeepValue } from '../utils/object';
import { View } from 'backbone';

export default class baseVw extends View {
  constructor(options = {}) {
    super(options);
    this._childViews = [];
    this._unregisterFromParent = true;
    this._removed = false;
    this._state = {};
    this.setState((options.initialState || {}), { renderOnChange: false });
  }

  _getCheckboxGroupData($fields) {
    const data = [];

    $fields.each((index, field) => {
      if (field.checked) data.push(field.value);
    });

    return data;
  }

  /**
   * This is a way to handle most common scenarios of getting data
   * from your form into a JS object. This function is very much a
   * work in progress. If you have a change that would be appropriate
   * for most forms, feel free to add it here.
   *
   * If you need some custom form parsing that's specific to your form,
   * please override this method in your view.
   * TODO: give example of overriding this function, while still using it
   * for most of your form, but only customizing one field
   *
   * Since form values are pulled in as strings, if you want them to be
   * pulled in as a different type, add a data-var-type attribute to the
   * field, e.g. data-var-type="boolean". As of now, only 'boolean' and
   * 'number' are supported, but feel free to add in more if it makes sense
   * for them to be in such a common function.
   *
   * @param {string or jQuery object} selector - A css selector string used to
   *   obtain the fields to extract data from. The selector will be scoped to
   *   this view (i.e. this.$('<selector>')). The default is
   *   'select[name], input[name], textarea[name]'. Alternatively, you can provide
   *   a jQuery object, which gives you more control (and useful for caching).
   *
   * @return {object} An object created from the data in the form fields
   */
  getFormData(selector) {
    const $formFields = selector instanceof $ ?
      selector : this.$(selector ||
        `select[name], input[name],
        textarea[name]:not([class*="trumbowyg"]),
        div[contenteditable][name]`
      );
    const data = {};

    $formFields.each((index, field) => {
      const $field = $(field);
      const varType = $field.data('var-type');

      let val = $field.val();

      if (field.tagName.toUpperCase() === 'DIV') {
        val = field.innerHTML;
      }

      if (field.type === 'radio' && !field.checked) return;

      if (varType) {
        if (varType === 'number') {
          // If an empty string is provided or if the
          // number evaluates to NaN, we'll leave the value
          // as is, so client side validation can catch it
          // and the user can update it.
          if (val.trim() !== '') {
            const numberFromVal = Number(val);

            if (!isNaN(numberFromVal)) {
              val = numberFromVal;
            }
          }
        } else if (varType === 'boolean') {
          val = val === 'true';
        }
      }

      let name = $field.attr('name');
      const isCheckboxGroup = field.type === 'checkbox' &&
        name.endsWith('[]');
      if (isCheckboxGroup) name = name.slice(0, name.length - 2);

      if (name.indexOf('.') !== -1) {
        let deepVal = val;

        if (isCheckboxGroup) {
          deepVal = this._getCheckboxGroupData($formFields.filter(`[name="${name}"]`));
        } else if (field.type === 'checkbox') {
          deepVal = field.checked;
        }

        // handle nested model
        setDeepValue(data, name, deepVal);
      } else if (isCheckboxGroup) {
        data[name] = this._getCheckboxGroupData($formFields.filter(`[name="${name}"]`));
      } else if (field.type === 'checkbox') {
        data[name] = field.checked;
      } else {
        data[name] = val;
      }
    });

    return data;
  }

  /**
   * Will scroll to the given element. The element must be within this view.
   * @param {string|object} selector - A CSS selector or a DOM element or a jQuery object.
   */
  scrollTo(selector) {
    if (!selector) {
      throw new Error('Please provide a selector');
    }

    if (!(typeof selector === 'string' ||
      _.isElement(selector) || selector instanceof $)) {
      throw new Error('The selector must be a string, DOM element or jQuery object.');
    }

    let $el;

    if (typeof selector === 'string') {
      $el = this.getCachedEl(selector);
    } else if (!(selector instanceof $)) {
      $el = $(selector);
    }

    $el[0].scrollIntoView();
  }

  /**
   * If you are creating child views within your view, call this method
   * to register them. This will ensure that they will have their remove
   * method called if the parent is removed.
   */
  registerChild(childView) {
    if (this._childViews.indexOf(childView) === -1) {
      this._childViews.push(childView);
      childView._parentView = this;
    }
  }

  /**
   * Opposite of registerChild. This method is automatically
   * called by remove. For all practical purposes, you probably
   * won't need to call this method directly.
   */
  unregisterChild(childView) {
    const index = this._childViews.indexOf(childView);

    if (index !== -1) {
      this._childViews.splice(index, 1);
      childView._parentView = null;
    }
  }

  /**
   * Shortcut method to instantiate a view and register it as a child.
   * @param {function} ChildView - The class of the child view (not instance).
   * @param {...*} args - Remaining arguments will be passed into the constuctor
   *   when instantiating the child view.
   * @return {object} The create child view instance.
   */
  createChild(ChildView, ...args) {
    if (typeof ChildView !== 'function') {
      throw new Error('Please provide a ChildView class.');
    }

    const childView = new ChildView(...args);
    this.registerChild(childView);

    return childView;
  }

  delegateEvents() {
    if (this._childViews) {
      this._childViews.forEach((view) => {
        view.delegateEvents();
      });
    }

    super.delegateEvents();
  }

  /**
   * Returns a given jQuery Element or a locally cached version for optimization.
   * NOTE: Ensure that child views call super.render() in their render function to clear the cache
   *       since the DOM elements in the cache will then be stale references.
   * @param {selector} string - The jQuery selector for the Element.
   *
   * @return {element} JQuery The element(s) found in the View's Dom or the View's Cache
   */
  getCachedEl(selector) {
    let element;

    // Ensure we have our cached elements map.
    if (!this._cachedElementMap) {
      this._cachedElementMap = new Map();
    }

    // If the cache has the element, we shall use it.
    if (this._cachedElementMap.has(selector)) {
      element = this._cachedElementMap.get(selector);
    } else {
      // The cache does not not have the element, therefore query with jQuery and cache it.
      element = this.$(selector);
      this._cachedElementMap.set(selector, element);
    }

    return element;
  }

  /**
   * Clears the cached elements map.
   */
  clearCachedElementMap() {
     // Clear the cache map.
    if (this._cachedElementMap) {
      this._cachedElementMap.clear();
    }
  }

  /**
   * Returns this view's state object.
   */
  getState() {
    return this._state;
  }

  /**
   * Sets this view's state object.
   * @param {object} state - The new state data. By default, this is merged into
   *   the existing state. To replace the state use the replace option.
   * @param {object} options
   * @param {boolean} [options.renderOnChange = true] - If true, will re-render the view
   *   if the resulting state changes. Setting this to false should be done very judiciously
   *   since it will result in your view not being in sync with its state.
   * @param {boolean} [options.replace = false] - If true, will replace the entire state
   *   with the given state. Otherwise, the given state will be merged in.
   * @return {object} The create child view instance.
   */
  setState(state = {}, options = {}) {
    const opts = {
      renderOnChange: true,
      replace: false,
      ...options,
    };
    let newState;

    if (typeof state !== 'object') {
      throw new Error('The state must be provided as an object.');
    }

    if (opts.replace) {
      this._state = {};
    } else {
      newState = _.extend({}, this._state, state);
    }

    if (!_.isEqual(this._state, newState)) {
      this._state = newState;
      if (opts.renderOnChange) this.render();
    }

    return this;
  }

  /** It is necessary to call super.render() in child views' render methods if using
   *  getCachedEl()
   *  @param {this} Render requires this to be returned.
   */
  render() {
    this.clearCachedElementMap();
    return this;
  }

  // Will call the remove method of any child views.
  remove() {
    for (let i = 0; i < this._childViews.length; i++) {
      // no need to unregister child from parent,
      // since the parent is also being removed
      this._childViews[i]._unregisterFromParent = false;
      this._childViews[i].remove();
    }

    if (this._parentView && this._unregisterFromParent) {
      this._parentView.unregisterChild(this);
    }

    super.remove();

    this._removed = true;
  }

  isRemoved() {
    return this._removed;
  }
}
<commit_msg>another review tweak<commit_after>import _ from 'underscore';
import $ from 'jquery';
import { setDeepValue } from '../utils/object';
import { View } from 'backbone';

export default class baseVw extends View {
  constructor(options = {}) {
    super(options);
    this._childViews = [];
    this._unregisterFromParent = true;
    this._removed = false;
    this._state = {};
    this.setState((options.initialState || {}), { renderOnChange: false });
  }

  _getCheckboxGroupData($fields) {
    const data = [];

    $fields.each((index, field) => {
      if (field.checked) data.push(field.value);
    });

    return data;
  }

  /**
   * This is a way to handle most common scenarios of getting data
   * from your form into a JS object. This function is very much a
   * work in progress. If you have a change that would be appropriate
   * for most forms, feel free to add it here.
   *
   * If you need some custom form parsing that's specific to your form,
   * please override this method in your view.
   * TODO: give example of overriding this function, while still using it
   * for most of your form, but only customizing one field
   *
   * Since form values are pulled in as strings, if you want them to be
   * pulled in as a different type, add a data-var-type attribute to the
   * field, e.g. data-var-type="boolean". As of now, only 'boolean' and
   * 'number' are supported, but feel free to add in more if it makes sense
   * for them to be in such a common function.
   *
   * @param {string or jQuery object} selector - A css selector string used to
   *   obtain the fields to extract data from. The selector will be scoped to
   *   this view (i.e. this.$('<selector>')). The default is
   *   'select[name], input[name], textarea[name]'. Alternatively, you can provide
   *   a jQuery object, which gives you more control (and useful for caching).
   *
   * @return {object} An object created from the data in the form fields
   */
  getFormData(selector) {
    const $formFields = selector instanceof $ ?
      selector : this.$(selector ||
        `select[name], input[name],
        textarea[name]:not([class*="trumbowyg"]),
        div[contenteditable][name]`
      );
    const data = {};

    $formFields.each((index, field) => {
      const $field = $(field);
      const varType = $field.data('var-type');

      let val = $field.val();

      if (field.tagName.toUpperCase() === 'DIV') {
        val = field.innerHTML;
      }

      if (field.type === 'radio' && !field.checked) return;

      if (varType) {
        if (varType === 'number') {
          // If an empty string is provided or if the
          // number evaluates to NaN, we'll leave the value
          // as is, so client side validation can catch it
          // and the user can update it.
          if (val.trim() !== '') {
            const numberFromVal = Number(val);

            if (!isNaN(numberFromVal)) {
              val = numberFromVal;
            }
          }
        } else if (varType === 'boolean') {
          val = val === 'true';
        }
      }

      const name = $field.attr('name');
      const isCheckboxGroup = field.type === 'checkbox' &&
        name.endsWith('[]');
      const checkboxGroupName = name.slice(0, name.length - 2);

      if (name.indexOf('.') !== -1) {
        let deepVal = val;
        let deepName = name;

        if (isCheckboxGroup) {
          deepVal = this._getCheckboxGroupData($formFields.filter(`[name="${name}"]`));
          deepName = checkboxGroupName;
        } else if (field.type === 'checkbox') {
          deepVal = field.checked;
        }

        // handle nested model
        setDeepValue(data, deepName, deepVal);
      } else if (isCheckboxGroup) {
        data[checkboxGroupName] =
          this._getCheckboxGroupData($formFields.filter(`[name="${name}"]`));
      } else if (field.type === 'checkbox') {
        data[name] = field.checked;
      } else {
        data[name] = val;
      }
    });

    return data;
  }

  /**
   * Will scroll to the given element. The element must be within this view.
   * @param {string|object} selector - A CSS selector or a DOM element or a jQuery object.
   */
  scrollTo(selector) {
    if (!selector) {
      throw new Error('Please provide a selector');
    }

    if (!(typeof selector === 'string' ||
      _.isElement(selector) || selector instanceof $)) {
      throw new Error('The selector must be a string, DOM element or jQuery object.');
    }

    let $el;

    if (typeof selector === 'string') {
      $el = this.getCachedEl(selector);
    } else if (!(selector instanceof $)) {
      $el = $(selector);
    }

    $el[0].scrollIntoView();
  }

  /**
   * If you are creating child views within your view, call this method
   * to register them. This will ensure that they will have their remove
   * method called if the parent is removed.
   */
  registerChild(childView) {
    if (this._childViews.indexOf(childView) === -1) {
      this._childViews.push(childView);
      childView._parentView = this;
    }
  }

  /**
   * Opposite of registerChild. This method is automatically
   * called by remove. For all practical purposes, you probably
   * won't need to call this method directly.
   */
  unregisterChild(childView) {
    const index = this._childViews.indexOf(childView);

    if (index !== -1) {
      this._childViews.splice(index, 1);
      childView._parentView = null;
    }
  }

  /**
   * Shortcut method to instantiate a view and register it as a child.
   * @param {function} ChildView - The class of the child view (not instance).
   * @param {...*} args - Remaining arguments will be passed into the constuctor
   *   when instantiating the child view.
   * @return {object} The create child view instance.
   */
  createChild(ChildView, ...args) {
    if (typeof ChildView !== 'function') {
      throw new Error('Please provide a ChildView class.');
    }

    const childView = new ChildView(...args);
    this.registerChild(childView);

    return childView;
  }

  delegateEvents() {
    if (this._childViews) {
      this._childViews.forEach((view) => {
        view.delegateEvents();
      });
    }

    super.delegateEvents();
  }

  /**
   * Returns a given jQuery Element or a locally cached version for optimization.
   * NOTE: Ensure that child views call super.render() in their render function to clear the cache
   *       since the DOM elements in the cache will then be stale references.
   * @param {selector} string - The jQuery selector for the Element.
   *
   * @return {element} JQuery The element(s) found in the View's Dom or the View's Cache
   */
  getCachedEl(selector) {
    let element;

    // Ensure we have our cached elements map.
    if (!this._cachedElementMap) {
      this._cachedElementMap = new Map();
    }

    // If the cache has the element, we shall use it.
    if (this._cachedElementMap.has(selector)) {
      element = this._cachedElementMap.get(selector);
    } else {
      // The cache does not not have the element, therefore query with jQuery and cache it.
      element = this.$(selector);
      this._cachedElementMap.set(selector, element);
    }

    return element;
  }

  /**
   * Clears the cached elements map.
   */
  clearCachedElementMap() {
     // Clear the cache map.
    if (this._cachedElementMap) {
      this._cachedElementMap.clear();
    }
  }

  /**
   * Returns this view's state object.
   */
  getState() {
    return this._state;
  }

  /**
   * Sets this view's state object.
   * @param {object} state - The new state data. By default, this is merged into
   *   the existing state. To replace the state use the replace option.
   * @param {object} options
   * @param {boolean} [options.renderOnChange = true] - If true, will re-render the view
   *   if the resulting state changes. Setting this to false should be done very judiciously
   *   since it will result in your view not being in sync with its state.
   * @param {boolean} [options.replace = false] - If true, will replace the entire state
   *   with the given state. Otherwise, the given state will be merged in.
   * @return {object} The create child view instance.
   */
  setState(state = {}, options = {}) {
    const opts = {
      renderOnChange: true,
      replace: false,
      ...options,
    };
    let newState;

    if (typeof state !== 'object') {
      throw new Error('The state must be provided as an object.');
    }

    if (opts.replace) {
      this._state = {};
    } else {
      newState = _.extend({}, this._state, state);
    }

    if (!_.isEqual(this._state, newState)) {
      this._state = newState;
      if (opts.renderOnChange) this.render();
    }

    return this;
  }

  /** It is necessary to call super.render() in child views' render methods if using
   *  getCachedEl()
   *  @param {this} Render requires this to be returned.
   */
  render() {
    this.clearCachedElementMap();
    return this;
  }

  // Will call the remove method of any child views.
  remove() {
    for (let i = 0; i < this._childViews.length; i++) {
      // no need to unregister child from parent,
      // since the parent is also being removed
      this._childViews[i]._unregisterFromParent = false;
      this._childViews[i].remove();
    }

    if (this._parentView && this._unregisterFromParent) {
      this._parentView.unregisterChild(this);
    }

    super.remove();

    this._removed = true;
  }

  isRemoved() {
    return this._removed;
  }
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';

class Projects extends Component {
  render() {
    let recentProjects = [
      ['Roadmap', 'https://github.com/pebutler3/roadmap'],
      ['Heron', 'https://github.com/getblackboard/heron'],
      ['Wiki Search', 'http://codepen.io/pebutler3/pen/AXkJzy'],
      ['Minimal Theme', 'https://minimal.mybrightsites.com/']
    ]
    return (

Recent Projects

          {recentProjects.map(project =>
	⌁ {project[0]}
)}

    );
  }
}

export default Projects;
<commit_msg>Added indevelopment // added stack info<commit_after>import React, { Component } from 'react';

class Projects extends Component {
  render() {
    let recentProjects = [
      ['Roadmap', 'https://github.com/pebutler3/roadmap', 'React'],
      ['Heron', 'https://github.com/getblackboard/heron', 'SCSS/Flexbox'],
      ['Wiki Search', 'http://codepen.io/pebutler3/pen/AXkJzy', 'SCSS/JS/Jquery'],
      ['Minimal Theme', 'https://minimal.mybrightsites.com/','HTML/CSS/JS/Liquid']
    ]

    let inDevelopment = [
      ['CAP Management', 'http://www.capmanagement.com','Wordpress']
    ]

    return (

Recent Projects

          {recentProjects.map(project =>
	{project[0]} - {project[2]}
)}

In Development

            {inDevelopment.map(project =>
	{project[0]} - {project[2]}
)}

    );
  }
}

export default Projects;
<|endoftext|>


<commit_before>//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Basic page definition and formatting.
//>>label: Page Creation
//>>group: Core

define( [ "jquery", "../jquery.mobile.widget", "../jquery.mobile.core" ], function( jQuery ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, undefined ) {
$.mobile.widgets = {};

var originalWidget = $.widget;

$.widget = (function( orig ) {
	return function() {
		var constructor = orig.apply( this, arguments ),
			name = constructor.prototype.widgetName;

		constructor.initSelector = ( ( constructor.prototype.initSelector !== undefined ) ?
			constructor.prototype.initSelector : ":jqmData(role='" + name + "')" );

		$.mobile.widgets[ name ] = constructor;

		return constructor;
	};
})( $.widget );

// Make sure $.widget still has bridge and extend methods
$.extend( $.widget, originalWidget );

// For backcompat remove in 1.5
$.mobile.document.on( "create", function( event ){
	$( event.target ).enhanceWithin();
});

$.widget( "mobile.page", {
	options: {
		theme: "a",
		domCache: false,
		keepNativeDefault: ":jqmData(role='none'), :jqmData(role='nojs')",
		contentTheme: null
	},

	// DEPRECATED for > 1.4
	// TODO remove at 1.5
	_createWidget: function() {
		$.Widget.prototype._createWidget.apply( this, arguments );
		this._trigger( "init" );
	},

	_create: function() {
		var attrPrefix = "data-" + $.mobile.ns,
			self = this;
		// If false is returned by the callbacks do not create the page
		if ( this._trigger( "beforecreate" ) === false ) {
			return false;
		}

		if ( this.options.role ) {
			this.element.attr( "data-" + $.mobile.ns + "role", this.options.role );
		}

		this.element
			.attr( "tabindex", "0" )
			.addClass( "ui-page ui-page-theme-" + this.options.theme );

		this._on( this.element, {
			pagebeforehide: "removeContainerBackground",
			pagebeforeshow: "_handlePageBeforeShow"
		});
		this.element.find( "[" + attrPrefix + "role='content']" ).each( function() {
			var $this = $( this ),
				theme = this.getAttribute( attrPrefix + "theme" ) || undefined;
				self.options.contentTheme = theme || self.options.contentTheme || ( self.element.jqmData("role") === "dialog" &&  self.options.theme );
				$this.addClass( "ui-content" );
				if ( self.options.contentTheme ) {
					$this.addClass( "ui-body-" + ( self.options.contentTheme ) );
				}
				// Add ARIA role
				$this.attr( "role", "main" ).addClass( "ui-content" );
		});

		this.element.enhanceWithin();

		if( $.mobile.getAttribute( this.element[0], "role", $.mobile.ns ) === "dialog" && $.mobile.dialog ){
			this.element.dialog();
		}
	},

	bindRemove: function( callback ) {
		var page = this.element;

		// when dom caching is not enabled or the page is embedded bind to remove the page on hide
		if ( !page.data( "mobile-page" ).options.domCache &&
			page.is( ":jqmData(external-page='true')" ) ) {

			// TODO use _on - that is, sort out why it doesn't work in this case
			page.bind( "pagehide.remove", callback || function(/* e */) {
				var $this = $( this ),
					prEvent = new $.Event( "pageremove" );

				$this.trigger( prEvent );

				if ( !prEvent.isDefaultPrevented() ) {
					$this.removeWithDependents();
				}
			});
		}
	},

	_setOptions: function( o ) {
		if ( o.theme !== undefined ) {
			this.element.removeClass( "ui-body-" + this.options.theme ).addClass( "ui-body-" + o.theme );
		}

		if ( o.contentTheme !== undefined ) {
			this.element.find( "[data-" + $.mobile.ns + "='content']" ).removeClass( "ui-body-" + this.options.contentTheme )
				.addClass( "ui-body-" + o.contentTheme );
		}
	},

	_handlePageBeforeShow: function(/* e */) {
		this.setContainerBackground();
	},

	removeContainerBackground: function() {
		var classes = ( $.mobile.pageContainer.attr( "class" ) || "" ).split( " " ),
			overlayTheme = null,
			matches;

		while ( classes.length > 0 ) {
			overlayTheme = classes.pop();
			matches = ( new RegExp( "^ui-overlay-([a-z])$" ) ).exec( overlayTheme );
			if ( matches && matches.length > 1 ) {
				overlayTheme = matches[ 1 ];
				break;
			} else {
				overlayTheme = null;
			}
		}

		$.mobile.pageContainer.removeClass( "ui-overlay-" + overlayTheme );
	},

	// set the page container background to the page theme
	setContainerBackground: function( theme ) {
		if ( this.options.theme ) {
			$.mobile.pageContainer.addClass( "ui-overlay-" + ( theme || this.options.theme ) );
		}
	},

	keepNativeSelector: function() {
		var options = this.options,
			keepNativeDefined = options.keepNative && $.trim( options.keepNative );

		if ( keepNativeDefined && options.keepNative !== options.keepNativeDefault ) {
			return [options.keepNative, options.keepNativeDefault].join( ", " );
		}

		return options.keepNativeDefault;
	}
});
})( jQuery );
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");
<commit_msg>Page: fix usage of $.mobile.getAttribute in checking if page is a dialog<commit_after>//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Basic page definition and formatting.
//>>label: Page Creation
//>>group: Core

define( [ "jquery", "../jquery.mobile.widget", "../jquery.mobile.core" ], function( jQuery ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, undefined ) {
$.mobile.widgets = {};

var originalWidget = $.widget;

$.widget = (function( orig ) {
	return function() {
		var constructor = orig.apply( this, arguments ),
			name = constructor.prototype.widgetName;

		constructor.initSelector = ( ( constructor.prototype.initSelector !== undefined ) ?
			constructor.prototype.initSelector : ":jqmData(role='" + name + "')" );

		$.mobile.widgets[ name ] = constructor;

		return constructor;
	};
})( $.widget );

// Make sure $.widget still has bridge and extend methods
$.extend( $.widget, originalWidget );

// For backcompat remove in 1.5
$.mobile.document.on( "create", function( event ){
	$( event.target ).enhanceWithin();
});

$.widget( "mobile.page", {
	options: {
		theme: "a",
		domCache: false,
		keepNativeDefault: ":jqmData(role='none'), :jqmData(role='nojs')",
		contentTheme: null
	},

	// DEPRECATED for > 1.4
	// TODO remove at 1.5
	_createWidget: function() {
		$.Widget.prototype._createWidget.apply( this, arguments );
		this._trigger( "init" );
	},

	_create: function() {
		var attrPrefix = "data-" + $.mobile.ns,
			self = this;
		// If false is returned by the callbacks do not create the page
		if ( this._trigger( "beforecreate" ) === false ) {
			return false;
		}

		if ( this.options.role ) {
			this.element.attr( "data-" + $.mobile.ns + "role", this.options.role );
		}

		this.element
			.attr( "tabindex", "0" )
			.addClass( "ui-page ui-page-theme-" + this.options.theme );

		this._on( this.element, {
			pagebeforehide: "removeContainerBackground",
			pagebeforeshow: "_handlePageBeforeShow"
		});
		this.element.find( "[" + attrPrefix + "role='content']" ).each( function() {
			var $this = $( this ),
				theme = this.getAttribute( attrPrefix + "theme" ) || undefined;
				self.options.contentTheme = theme || self.options.contentTheme || ( self.element.jqmData("role") === "dialog" &&  self.options.theme );
				$this.addClass( "ui-content" );
				if ( self.options.contentTheme ) {
					$this.addClass( "ui-body-" + ( self.options.contentTheme ) );
				}
				// Add ARIA role
				$this.attr( "role", "main" ).addClass( "ui-content" );
		});

		this.element.enhanceWithin();

		if( $.mobile.getAttribute( this.element[0], "role", true ) === "dialog" && $.mobile.dialog ){
			this.element.dialog();
		}
	},

	bindRemove: function( callback ) {
		var page = this.element;

		// when dom caching is not enabled or the page is embedded bind to remove the page on hide
		if ( !page.data( "mobile-page" ).options.domCache &&
			page.is( ":jqmData(external-page='true')" ) ) {

			// TODO use _on - that is, sort out why it doesn't work in this case
			page.bind( "pagehide.remove", callback || function(/* e */) {
				var $this = $( this ),
					prEvent = new $.Event( "pageremove" );

				$this.trigger( prEvent );

				if ( !prEvent.isDefaultPrevented() ) {
					$this.removeWithDependents();
				}
			});
		}
	},

	_setOptions: function( o ) {
		if ( o.theme !== undefined ) {
			this.element.removeClass( "ui-body-" + this.options.theme ).addClass( "ui-body-" + o.theme );
		}

		if ( o.contentTheme !== undefined ) {
			this.element.find( "[data-" + $.mobile.ns + "='content']" ).removeClass( "ui-body-" + this.options.contentTheme )
				.addClass( "ui-body-" + o.contentTheme );
		}
	},

	_handlePageBeforeShow: function(/* e */) {
		this.setContainerBackground();
	},

	removeContainerBackground: function() {
		var classes = ( $.mobile.pageContainer.attr( "class" ) || "" ).split( " " ),
			overlayTheme = null,
			matches;

		while ( classes.length > 0 ) {
			overlayTheme = classes.pop();
			matches = ( new RegExp( "^ui-overlay-([a-z])$" ) ).exec( overlayTheme );
			if ( matches && matches.length > 1 ) {
				overlayTheme = matches[ 1 ];
				break;
			} else {
				overlayTheme = null;
			}
		}

		$.mobile.pageContainer.removeClass( "ui-overlay-" + overlayTheme );
	},

	// set the page container background to the page theme
	setContainerBackground: function( theme ) {
		if ( this.options.theme ) {
			$.mobile.pageContainer.addClass( "ui-overlay-" + ( theme || this.options.theme ) );
		}
	},

	keepNativeSelector: function() {
		var options = this.options,
			keepNativeDefined = options.keepNative && $.trim( options.keepNative );

		if ( keepNativeDefined && options.keepNative !== options.keepNativeDefault ) {
			return [options.keepNative, options.keepNativeDefault].join( ", " );
		}

		return options.keepNativeDefault;
	}
});
})( jQuery );
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");
<|endoftext|>


<commit_before>(function(ADL){

  // global variables
  var baseuri = "http://example.com/";
  // ADL verbs
  var verbs = ['answered','asked','attempted','attended','commented','completed','exited','experienced','failed','imported','initialized','interacted','launched','mastered','passed','preferred','progressed','registered','responded','resumed','scored','shared','suspended','terminated','voided'];
  // uri regex pattern
  var re_uri = /[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi;

  // Merge two JSON object
  function mergeJSON(obj1, obj2, result) {
    result = {};
    for(var key in obj1) result[key]=obj1[key];
    for(var key in obj2) result[key]=obj2[key];
    return result;
  }

  XAPIRemarks = function() {

    /*
     * Convert a Remark String into an array
     * @param {string} remark formated string
     * @return {array} javascript array with xAPI Statement properties
     */
    this.remarkToArray = function(remark) {
      var re = /(<.+>) (<.+>) (<.+>)(\s?(\(.+\)))?(\s?(\{.+\}))?(\s?(\[.+\]))?/;
      var raw = remark.match(re);
      if (raw) {
        var arr = [];
        var i=0;
        //console.log(raw);
        raw.forEach(function(val) {
          // throw out "duplicates" created by the regex groupings
          if (i != 0 && i != 4 && i != 6 && i != 8) {
            // throw out empty groups
            if (val != undefined)
              arr.push(val);
          }
          i++;
        });
        return arr;
      }
    };

    /*
     * Convert an array with xAPI Statement properties
     * @param {array} array of xAPI Statement properties
     * @return {object} an xAPI Statement Object
     */
    this.remarkArrayToStatement = function(array) {
      //console.log(array);
      if (array.length > 3) {
        var avo = array.slice(0,3);
        var ex  = array.slice(3);
      } else {
        var avo = array;
      }
      var actor = avo[0].slice(1).slice(0,-1);
      var verb = avo[1].slice(1).slice(0,-1);
      var object = avo[2].slice(1).slice(0,-1);

      // Check if full URI or in ADL verb list
      if (verbs.indexOf(verb) != -1) {
        verburi = 'http://adlnet.gov/expapi/verbs/' + verb;
      } else if (verb.match(re_uri) == null) {
        verburi = baseuri + 'verbs/' + verb;
      } else {
        verburi = verb;
        verb = verburi.split(/\//).pop();
      }

      // Check if full URI or needs to be made into one
      if (object.match(re_uri) == null) {
        objecturi = baseuri + 'activities/' + encodeURI(object);
      } else {
        objecturi = object;
      }

      var stmt = {
        'actor': {
          'mbox': 'mailto:' + actor,
          'objectType': 'Agent'
        },
        'verb': {
          'display': {
            'en-US': verb
          },
          'id': verburi
        },
        'object': {
          'id': objecturi,
          'objectType': 'Activity'
        }
      };
      // If more than an Actor, Verb and Object exist
      if (ex) {
        var stmt_ex = {};
        ex.forEach(function(o) {
          var type = o.substring(0,1);
          switch (type) {
            // result
            case "(":
              // turn it into JSON
              obj = JSON.parse(o.replace(/\(/g,"{").replace(/\)/g,"}").replace(/([sdrwc]{1}): (\[|"|true|false)/g,'"$1": $2').trim());
              stmt_ex = { 'result': {} };
              for(var key in obj) {
                switch (key) {
                  case 's':
                    var s = obj[key];
                    stmt_ex.result.score = {
                      'raw': s[0],
                      'min': s[1],
                      'max': s[2]
                    };
                  break;
                  case 'w': // success / win (s taken for score)
                    var w = obj[key];
                    stmt_ex.result.sucess = w;
                  break;
                  case 'c':
                    var c = obj[key];
                    stmt_ex.result.completion = c;
                  break;
                  case 'r':
                    var r = obj[key];
                    stmt_ex.result.response = r;
                  break;
                  case 'd':
                    var d = obj[key];
                    stmt_ex.result.duration = d;
                  break;
                  default:
                }
              }

            break;
            // context
            case "{":
              obj = JSON.parse(o.replace(/\(/g,"{").replace(/\)/g,"}").replace(/([pg]{1}): (\[|")/g,'"$1": $2').trim());
              stmt_ex = { 'context': { 'contextActivities' : {} } };
              for(var key in obj) {
                switch (key) {
                  case 'p':
                    var ps = obj[key];
                    var parent_arr = [];
                    ps.forEach(function(p) {

                      if (p.match(re_uri) == null) {
                        puri = baseuri + 'activities/' + encodeURI(p);
                      } else {
                        puri = p;
                        p = puri.split(/\//).pop();
                      }

                      parent_arr.push({
                       "definition": {
                            "name": {
                                "en-US": p
                            }
                        },
                        'id': puri,
                        'objectType': 'Activity'
                      });
                    });
                    stmt_ex.context.contextActivities['parent'] = parent_arr;
                  break;
                  case 'g':
                    var gs = obj[key];
                    var grouping_arr = [];
                    gs.forEach(function(g) {

                      if (g.match(re_uri) == null) {
                        guri = baseuri + 'activities/' + encodeURI(g);
                      } else {
                        guri = g;
                        g = puri.split(/\//).pop();
                      }

                      grouping_arr.push({
                       "definition": {
                            "name": {
                                "en-US": g
                            }
                        },
                        'id': guri,
                        'objectType': 'Activity'
                      });
                    });
                    stmt_ex.context.contextActivities['grouping'] = grouping_arr;
                  break;
                  default:
                }
              }
            break;
            // attachments
            case "[":
            break;
            default:
          }
          stmt = mergeJSON(stmt, stmt_ex);
        });
      }
      return stmt;
    };

  };

  ADL.XAPIRemarks = new XAPIRemarks;

}(window.ADL = window.ADL || {}));
<commit_msg>fixed sucess typo<commit_after>(function(ADL){

  // global variables
  var baseuri = "http://example.com/";
  // ADL verbs
  var verbs = ['answered','asked','attempted','attended','commented','completed','exited','experienced','failed','imported','initialized','interacted','launched','mastered','passed','preferred','progressed','registered','responded','resumed','scored','shared','suspended','terminated','voided'];
  // uri regex pattern
  var re_uri = /[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi;

  // Merge two JSON object
  function mergeJSON(obj1, obj2, result) {
    result = {};
    for(var key in obj1) result[key]=obj1[key];
    for(var key in obj2) result[key]=obj2[key];
    return result;
  }

  XAPIRemarks = function() {

    /*
     * Convert a Remark String into an array
     * @param {string} remark formated string
     * @return {array} javascript array with xAPI Statement properties
     */
    this.remarkToArray = function(remark) {
      var re = /(<.+>) (<.+>) (<.+>)(\s?(\(.+\)))?(\s?(\{.+\}))?(\s?(\[.+\]))?/;
      var raw = remark.match(re);
      if (raw) {
        var arr = [];
        var i=0;
        //console.log(raw);
        raw.forEach(function(val) {
          // throw out "duplicates" created by the regex groupings
          if (i != 0 && i != 4 && i != 6 && i != 8) {
            // throw out empty groups
            if (val != undefined)
              arr.push(val);
          }
          i++;
        });
        return arr;
      }
    };

    /*
     * Convert an array with xAPI Statement properties
     * @param {array} array of xAPI Statement properties
     * @return {object} an xAPI Statement Object
     */
    this.remarkArrayToStatement = function(array) {
      //console.log(array);
      if (array.length > 3) {
        var avo = array.slice(0,3);
        var ex  = array.slice(3);
      } else {
        var avo = array;
      }
      var actor = avo[0].slice(1).slice(0,-1);
      var verb = avo[1].slice(1).slice(0,-1);
      var object = avo[2].slice(1).slice(0,-1);

      // Check if full URI or in ADL verb list
      if (verbs.indexOf(verb) != -1) {
        verburi = 'http://adlnet.gov/expapi/verbs/' + verb;
      } else if (verb.match(re_uri) == null) {
        verburi = baseuri + 'verbs/' + verb;
      } else {
        verburi = verb;
        verb = verburi.split(/\//).pop();
      }

      // Check if full URI or needs to be made into one
      if (object.match(re_uri) == null) {
        objecturi = baseuri + 'activities/' + encodeURI(object);
      } else {
        objecturi = object;
      }

      var stmt = {
        'actor': {
          'mbox': 'mailto:' + actor,
          'objectType': 'Agent'
        },
        'verb': {
          'display': {
            'en-US': verb
          },
          'id': verburi
        },
        'object': {
          'id': objecturi,
          'objectType': 'Activity'
        }
      };
      // If more than an Actor, Verb and Object exist
      if (ex) {
        var stmt_ex = {};
        ex.forEach(function(o) {
          var type = o.substring(0,1);
          switch (type) {
            // result
            case "(":
              // turn it into JSON
              obj = JSON.parse(o.replace(/\(/g,"{").replace(/\)/g,"}").replace(/([sdrwc]{1}): (\[|"|true|false)/g,'"$1": $2').trim());
              stmt_ex = { 'result': {} };
              for(var key in obj) {
                switch (key) {
                  case 's':
                    var s = obj[key];
                    stmt_ex.result.score = {
                      'raw': s[0],
                      'min': s[1],
                      'max': s[2]
                    };
                  break;
                  case 'w': // success / win (s taken for score)
                    var w = obj[key];
                    stmt_ex.result.success = w;
                  break;
                  case 'c':
                    var c = obj[key];
                    stmt_ex.result.completion = c;
                  break;
                  case 'r':
                    var r = obj[key];
                    stmt_ex.result.response = r;
                  break;
                  case 'd':
                    var d = obj[key];
                    stmt_ex.result.duration = d;
                  break;
                  default:
                }
              }

            break;
            // context
            case "{":
              obj = JSON.parse(o.replace(/\(/g,"{").replace(/\)/g,"}").replace(/([pg]{1}): (\[|")/g,'"$1": $2').trim());
              stmt_ex = { 'context': { 'contextActivities' : {} } };
              for(var key in obj) {
                switch (key) {
                  case 'p':
                    var ps = obj[key];
                    var parent_arr = [];
                    ps.forEach(function(p) {

                      if (p.match(re_uri) == null) {
                        puri = baseuri + 'activities/' + encodeURI(p);
                      } else {
                        puri = p;
                        p = puri.split(/\//).pop();
                      }

                      parent_arr.push({
                       "definition": {
                            "name": {
                                "en-US": p
                            }
                        },
                        'id': puri,
                        'objectType': 'Activity'
                      });
                    });
                    stmt_ex.context.contextActivities['parent'] = parent_arr;
                  break;
                  case 'g':
                    var gs = obj[key];
                    var grouping_arr = [];
                    gs.forEach(function(g) {

                      if (g.match(re_uri) == null) {
                        guri = baseuri + 'activities/' + encodeURI(g);
                      } else {
                        guri = g;
                        g = puri.split(/\//).pop();
                      }

                      grouping_arr.push({
                       "definition": {
                            "name": {
                                "en-US": g
                            }
                        },
                        'id': guri,
                        'objectType': 'Activity'
                      });
                    });
                    stmt_ex.context.contextActivities['grouping'] = grouping_arr;
                  break;
                  default:
                }
              }
            break;
            // attachments
            case "[":
            break;
            default:
          }
          stmt = mergeJSON(stmt, stmt_ex);
        });
      }
      return stmt;
    };

  };

  ADL.XAPIRemarks = new XAPIRemarks;

}(window.ADL = window.ADL || {}));
<|endoftext|>