<commit_before>/**
 * @package: google-map
 * @FileType: javascript
 * @author RC Adhikari <http://rcadhikari.blogspot.co.uk>
 * Date: 25/08/2015 15:35
 */

// Set as a global variable;
var marker;
var address;
var postcode;
var tmpLat = 28.2
var tmpLng = 83.98166700000002;
var marker_icon = {url: "http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=N|F7584C|000000"};

function initMap() {
    var map = new google.maps.Map(document.getElementById('map'), {
        zoom: 6,
        //center: {lat: 28.2, lng: 83.98166700000002 }
        center: {lat: tmpLat, lng: tmpLng}
    });
    var geocoder = new google.maps.Geocoder();

    // Initial pre-population the marker on the map
    var pre_load = 1; // This is a pre-population of marker on the map status.
    geocodeAddress(geocoder, pre_load);

    // Do the map work once
    document.getElementById('locate_on_map').addEventListener('click', function() {
        pre_load = 0;
        geocodeAddress(geocoder, pre_load);
    });
}

/**
 * Function to manipulate the Google Map Locator
 * @param geocoder object This is a geocoder object
 */
function geocodeAddress(geocoder, pre_load) {
    address = document.getElementById('address').value;
    postcode = document.getElementById('postcode').value;
    var fullAddress = address + ' ' + postcode;

    geocoder.geocode({'address': fullAddress}, function(results, status) {
        if (status === google.maps.GeocoderStatus.OK) {
            var result = results[0].geometry.location;
            locateAddressMarker(result, pre_load);
        } else {
            if (pre_load == false) {
            alert('Geocode was not successful for the following reason: ' + status);
        }
        }
    });
}

/**
 * @param result This is the object return by google api after the passing the address via api param.
 */
function locateAddressMarker(result, pre_load)
{
    // If older value exist, override the existing one;
    if (pre_load == 1) {
        //Google Parameter changed: Lat: G; Lng: K;
        result.H = tmpLat;
        result.L = tmpLng;
    }

    // After searching the address, set the resulted latitude/longitude values into the text fields.
    document.getElementById('latitude').value = lat = result.H; // Set the latitude value
    document.getElementById('longitude').value = lng = result.L; // Set the longitude value

    // Set Marker Character and Color;
    var marker_icon = {url: "http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=N|F7584C|000000"};

    // Marker Address Information Variable
    fullAddress = postcode;
    if (address != "") {
        addressTmp = address.replace(/,/g , "
");
        fullAddress = addressTmp + ' ' + fullAddress;
    }
    var contentString = fullAddress;

    var map = new google.maps.Map(document.getElementById('map'), {
        zoom: 15, // increase the zoom
        center: {lat: lat, lng: lng}
    });
    // Set the Center;
    map.setCenter(result);
    marker = new google.maps.Marker({
        map: map,
        position: result,
        draggable: true,
        animation: google.maps.Animation.DROP,
        icon: marker_icon
    });
    marker.addListener('click', toggleBounce);

    // Adding the location info whilst clicking marker
    var infoWindow = new google.maps.InfoWindow({
        content: contentString
    });
    google.maps.event.addListener(marker, "click", function(event) {
        infoWindow.open(map, marker);
    });

    // When dragging the marker, update the the latitude/longitude values into the text fields.
    google.maps.event.addListener(marker, "dragend", function(event) {
        document.getElementById('latitude').value = event.latLng.lat();
        document.getElementById('longitude').value = event.latLng.lng();
    });
}

// Toggle the marker when clicked and bouncing until set timeout
function toggleBounce() {
    if (marker.getAnimation() !== null) {
        marker.setAnimation(null);
    } else {
        marker.setAnimation(google.maps.Animation.BOUNCE);

        // Set the timeout for marker bouncing
        setTimeout(function(){ marker.setAnimation(null); }, 750);
    }
}

/** TODO: The below functions is for multiple marker in the google map. */
function LoadMultiAddressOnGoogleMap(markers) {
    var mapOptions = {
        //center: new google.maps.LatLng(markers[0].lat, markers[0].lng),
        center: {lat: tmpLat, lng: tmpLng},
        //center: {lat: 53.282872, lng: -3.8294799999999896},
        zoom: 6,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

    //Create and open InfoWindow.
    var infoWindow = new google.maps.InfoWindow();

    for (var i = 0; i < markers.length; i++) {
        var data = markers[i];
        var myLatlng = new google.maps.LatLng(data.lat, data.lng);

        var marker = new google.maps.Marker({
            map: map,
            position: myLatlng,
            //animation: google.maps.Animation.DROP,
            icon: marker_icon
        });

        //Attach click event to the marker.
        (function (marker, data) {
            google.maps.event.addListener(marker, "click", function (e) {
                //Wrap the content inside an HTML DIV in order to set height and width of InfoWindow.
                infoWindow.setContent("
" +  data.title + "
" + data.description + "
");
                infoWindow.open(map, marker);
            });
        })(marker, data);
    }
}
<commit_msg>Adding Script for Google Drop Pin Map<commit_after>/**
 * @package: google-map
 * @FileType: javascript
 * @author RC Adhikari <http://rcadhikari.blogspot.co.uk>
 * Date: 25/08/2015 15:35
 */

// Set as a global variable;
var marker;
var address;
var postcode;
var tmpLat = 28.2
var tmpLng = 83.98166700000002;
var marker_icon = {url: "http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=N|F7584C|000000"};

function initMap() {
    var map = new google.maps.Map(document.getElementById('map'), {
        zoom: 6,
        //center: {lat: 28.2, lng: 83.98166700000002 }
        center: {lat: tmpLat, lng: tmpLng}
    });
    var geocoder = new google.maps.Geocoder();

    // Initial pre-population the marker on the map
    var pre_load = 1; // This is a pre-population of marker on the map status.
    geocodeAddress(geocoder, pre_load);

    // Do the map work once
    document.getElementById('locate_on_map').addEventListener('click', function() {
        pre_load = 0;
        geocodeAddress(geocoder, pre_load);
    });
}

/**
 * Function to manipulate the Google Map Locator
 * @param geocoder object This is a geocoder object
 */
function geocodeAddress(geocoder, pre_load) {
    address = document.getElementById('address').value;
    postcode = document.getElementById('postcode').value;
    var fullAddress = address + ' ' + postcode;

    geocoder.geocode({'address': fullAddress}, function(results, status) {
        if (status === google.maps.GeocoderStatus.OK) {
            var result = results[0].geometry.location;
            locateAddressMarker(result, pre_load);
        } else {
            if (pre_load == false) {
            alert('Geocode was not successful for the following reason: ' + status);
        }
        }
    });
}

/**
 * @param result This is the object return by google api after the passing the address via api param.
 */
function locateAddressMarker(result, pre_load)
{
    // Fetching the keys from result object;
    var geo_keys = Object.keys(result);
    var result_lat_key = geo_keys[0];
    var result_lng_key = geo_keys[1];
    // console.log(geo_keys);

    // If older value exist, override the existing one;
    if (pre_load == 1) {
        //Google Parameter changed: Lat: G; Lng: K;
        result[result_lat_key] = tmpLat;
        result[result_lng_key] = tmpLng;
    }
    //console.log( 'pre_load: '+pre_load+' tmpLat1: ' + result[result_lat_key] + ' tmpLng1: '+ result[result_lng_key]);

    // After searching the address, set the resulted latitude/longitude values into the text fields.
    document.getElementById('latitude').value = lat = result[result_lat_key]; // Set the latitude value
    document.getElementById('longitude').value = lng = result[result_lng_key]; // Set the longitude value

    // Set Marker Character and Color;
    var marker_icon = {url: "http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=N|F7584C|000000"};

    // Marker Address Information Variable
    fullAddress = postcode;
    if (address != "") {
        addressTmp = address.replace(/,/g , "
");
        fullAddress = addressTmp + ' ' + fullAddress;
    }
    var contentString = fullAddress;

    var map = new google.maps.Map(document.getElementById('map'), {
        zoom: 15, // increase the zoom
        center: {lat: lat, lng: lng}
    });
    // Set the Center;
    map.setCenter(result);
    marker = new google.maps.Marker({
        map: map,
        position: result,
        draggable: true,
        animation: google.maps.Animation.DROP,
        icon: marker_icon
    });
    marker.addListener('click', toggleBounce);

    // Adding the location info whilst clicking marker
    var infoWindow = new google.maps.InfoWindow({
        content: contentString
    });
    google.maps.event.addListener(marker, "click", function(event) {
        infoWindow.open(map, marker);
    });

    // When dragging the marker, update the the latitude/longitude values into the text fields.
    google.maps.event.addListener(marker, "dragend", function(event) {
        document.getElementById('latitude').value = event.latLng.lat();
        document.getElementById('longitude').value = event.latLng.lng();
    });
}

// Toggle the marker when clicked and bouncing until set timeout
function toggleBounce() {
    if (marker.getAnimation() !== null) {
        marker.setAnimation(null);
    } else {
        marker.setAnimation(google.maps.Animation.BOUNCE);

        // Set the timeout for marker bouncing
        setTimeout(function(){ marker.setAnimation(null); }, 750);
    }
}

/** TODO: The below functions is for multiple marker in the google map. */
function LoadMultiAddressOnGoogleMap(markers) {
    var mapOptions = {
        //center: new google.maps.LatLng(markers[0].lat, markers[0].lng),
        center: {lat: tmpLat, lng: tmpLng},
        //center: {lat: 53.282872, lng: -3.8294799999999896},
        zoom: 6,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

    //Create and open InfoWindow.
    var infoWindow = new google.maps.InfoWindow();

    for (var i = 0; i < markers.length; i++) {
        var data = markers[i];
        var myLatlng = new google.maps.LatLng(data.lat, data.lng);

        var marker = new google.maps.Marker({
            map: map,
            position: myLatlng,
            //animation: google.maps.Animation.DROP,
            icon: marker_icon
        });

        //Attach click event to the marker.
        (function (marker, data) {
            google.maps.event.addListener(marker, "click", function (e) {
                //Wrap the content inside an HTML DIV in order to set height and width of InfoWindow.
                infoWindow.setContent("
" +  data.title + "
" + data.description + "
");
                infoWindow.open(map, marker);
            });
        })(marker, data);
    }
}
<|endoftext|>


<commit_before>(function (global) {
  var room = 'c3ce9e42-0f7e-11e4-8261-b2227cce2b54'
  var element = null

  function toArray(arr) {
    return Array.prototype.slice.call(arr)
  }

  function extend(target) {
    var origins = toArray(arguments).slice(1)
    origins.forEach(function (origin) {
      for (var key in origin) {
        if (origin.hasOwnProperty(key)) {
          target[key] = origin[key]
        }
      }
    }}
    return target
  }

  function throttle(fn, ms) {
    var time = new Date().getTime()
    return function () {
      if ((new Date().getTime() - time) > ms) {
        time = new Date().getTime()
        return fn.apply(null, arguments)
      }
    }
  }

  function Webmotely(options) {
    this.options = extend({}, this.options, options)
    this.con = Primus.connect(this.options.server)
    this._connect()
    this._init()
  }

  Webmotely.prototype.options = {
    server: 'ws://localhost:3000'
  }

  Webmotely.prototype._connect = function () {
    var primus = this.con
    var cursor = false
    primus.once('open', function () {
      primus.write({ action: 'join', room: room, type: 'client' })
      primus.on('joinroom', function (room, spark) {
        console.log(spark.id + ' joined to room ' + room)
      })
      primus.on('data', function (data) {
        if (!cursor) {
          cursor = create()
          info = createInfo()
        }
        update(cursor, data)
      })
    })
  }

  Webmotely.prototype.send = function (data) {
    this.con.write({ room: room, data: data })
  }

  Webmotely.prototype.leave = function () {
    this.con.write({ action: 'leave', room: room })
  }

  Webmotely.prototype._init = function () {
    var self = this.con
    document.onreadystatechange = function () {
      if (document.readyState === 'complete') {
        window.onresize = function () {
          var w = window,
              d = document,
              e = d.documentElement,
              g = d.getElementsByTagName('body')[0]
          var data = {
            type: 'resize',
            width: w.innerWidth || e.clientWidth || g.clientWidth,
            height: w.innerHeight || e.clientHeight|| g.clientHeight
          }
          self.write({ room: room, data: data })
        }
      }
    }
  }

  function create() {
    var div = document.createElement('div')
    div.style.position = 'fixed'
    div.style.zIndex = 10000
    div.style.top = '-50px'
    div.innerHTML = ''
    document.body.appendChild(div)
    return div
  }

  function createInfo() {
    var div = document.createElement('div')
    div.style.position = 'fixed'
    div.style.zIndex = 10000
    div.style.bottom = '5px'
    div.style.left = '5px'
    div.style.padding = '7px'
    div.style.background = '#CCC'
    div.style.opacity = '0.8'
    div.style.borderRadius = '12px'
    div.style.webkitBorderRadius = '12px'
    div.style.mozBorderRadius = '12px'
    div.innerHTML = 'Webmotely is enabled - Disable'
    document.body.appendChild(div)
    return div
  }

  function triggerMouseEvent(el, type, data) {
    var ev = document.createEvent('MouseEvent')
    ev.initMouseEvent(
        type, true /* bubble */,
        true /* cancelable */,
        window, null,
        data.x, data.y, 0, 0, /* coordinates */
        false, false, false, false, /* modifier keys */
        0 /* left */, null
    )
    if (el.tagName === 'INPUT') {
      el.focus()
    }
    el.dispatchEvent(ev)
  }

  function triggerClick(data) {
    var el = document.elementFromPoint(data.x, data.y)
    triggerMouseEvent(el, 'click', data)
  }

  function triggerScroll(x, y) {
    window.scrollTo(x, y)
  }

  function dispatchEvent(el, type) {
    if (el.fireEvent) {
      el.fireEvent('on' + type)
    } else {
      var evObj = document.createEvent('Events')
      evObj.initEvent(type, true, false)
      el.dispatchEvent(evObj)
    }
  }

  function triggers(data) {
    var el = document.elementFromPoint(data.x, data.y)
    if (el) {
      if (el !== element) {
        if (element !== null) {
          triggerMouseEvent(element, 'mouseleave', data)
        }
        triggerMouseEvent(el, 'mouseenter', data)
        element = el
      }
      triggerMouseEvent(el, 'mouseover', data)
    }
  }

  function triggerKey(data) {
    var el = document.elementFromPoint(data.elX, data.elY)
    if (data.value && el) {
      if (el.tagName !== 'INPUT') {
        if (el = el.querySelector('input')) {
          el.value = data.value
        }
      } else {
        el.value = data.value
      }
    }
  }

  function triggerEvent(data) {
    var el = document.elementFromPoint(data.x, data.y)
    if (el) {
      if (data.type === 'focus') {
        var ev = new FocusEvent(data.type)
      } else {
        var ev = new Event(data.type)
      }
      el.dispatchEvent(ev)
    }
  }

  function update(cursor, data) {
    cursor.style.display = 'none'

    switch (data.type) {
      case 'mousemove':
        cursor.style.top = data.y + 'px'
        cursor.style.left = data.x + 'px'
        break;
      case 'click':
        triggerClick(data)
        break;
      case 'scroll':
        triggerScroll(data.pageX, data.pageY)
        break;
      case 'keyup':
        triggerKey(data)
        break
      default:
        triggerEvent(data)
        break;
    }

    triggers(data)
    cursor.style.display = 'block'
  }

  var webmotely = global.webmotely = function (options) {
    return new Webmotely(options)
  }

  webmotely.start = function (options) {
    return webmotely(options)
  }

}(window))
<commit_msg>feat: support options<commit_after>(function (global) {
  var room = 'c3ce9e42-0f7e-11e4-8261-b2227cce2b54'
  var element = null

  function toArray(arr) {
    return Array.prototype.slice.call(arr)
  }

  function extend(target) {
    var origins = toArray(arguments).slice(1)
    origins.forEach(function (origin) {
      for (var key in origin) {
        if (origin.hasOwnProperty(key)) {
          target[key] = origin[key]
        }
      }
    })
    return target
  }

  function throttle(fn, ms) {
    var time = new Date().getTime()
    return function () {
      if ((new Date().getTime() - time) > ms) {
        time = new Date().getTime()
        return fn.apply(null, arguments)
      }
    }
  }

  function Webmotely(options) {
    this.options = extend({}, this.options, options)
    this.con = Primus.connect(this.options.server)
    this._connect()
    this._init()
  }

  Webmotely.prototype.options = {
    server: 'ws://localhost:3000'
  }

  Webmotely.prototype._connect = function () {
    var primus = this.con
    var cursor = false
    primus.once('open', function () {
      primus.write({ action: 'join', room: room, type: 'client' })
      primus.on('joinroom', function (room, spark) {
        console.log(spark.id + ' joined to room ' + room)
      })
      primus.on('data', function (data) {
        if (!cursor) {
          cursor = create()
          info = createInfo()
        }
        update(cursor, data)
      })
    })
  }

  Webmotely.prototype.send = function (data) {
    this.con.write({ room: room, data: data })
  }

  Webmotely.prototype.leave = function () {
    this.con.write({ action: 'leave', room: room })
  }

  Webmotely.prototype._init = function () {
    var self = this.con
    document.onreadystatechange = function () {
      if (document.readyState === 'complete') {
        window.onresize = function () {
          var w = window,
              d = document,
              e = d.documentElement,
              g = d.getElementsByTagName('body')[0]
          var data = {
            type: 'resize',
            width: w.innerWidth || e.clientWidth || g.clientWidth,
            height: w.innerHeight || e.clientHeight|| g.clientHeight
          }
          self.write({ room: room, data: data })
        }
      }
    }
  }

  function create() {
    var div = document.createElement('div')
    div.style.position = 'fixed'
    div.style.zIndex = 10000
    div.style.top = '-50px'
    div.innerHTML = ''
    document.body.appendChild(div)
    return div
  }

  function createInfo() {
    var div = document.createElement('div')
    div.style.position = 'fixed'
    div.style.zIndex = 10000
    div.style.bottom = '5px'
    div.style.left = '5px'
    div.style.padding = '7px'
    div.style.background = '#CCC'
    div.style.opacity = '0.8'
    div.style.borderRadius = '12px'
    div.style.webkitBorderRadius = '12px'
    div.style.mozBorderRadius = '12px'
    div.innerHTML = 'Webmotely is enabled - Disable'
    document.body.appendChild(div)
    return div
  }

  function triggerMouseEvent(el, type, data) {
    var ev = document.createEvent('MouseEvent')
    ev.initMouseEvent(
        type, true /* bubble */,
        true /* cancelable */,
        window, null,
        data.x, data.y, 0, 0, /* coordinates */
        false, false, false, false, /* modifier keys */
        0 /* left */, null
    )
    if (el.tagName === 'INPUT') {
      el.focus()
    }
    el.dispatchEvent(ev)
  }

  function triggerClick(data) {
    var el = document.elementFromPoint(data.x, data.y)
    triggerMouseEvent(el, 'click', data)
  }

  function triggerScroll(x, y) {
    window.scrollTo(x, y)
  }

  function dispatchEvent(el, type) {
    if (el.fireEvent) {
      el.fireEvent('on' + type)
    } else {
      var evObj = document.createEvent('Events')
      evObj.initEvent(type, true, false)
      el.dispatchEvent(evObj)
    }
  }

  function triggers(data) {
    var el = document.elementFromPoint(data.x, data.y)
    if (el) {
      if (el !== element) {
        if (element !== null) {
          triggerMouseEvent(element, 'mouseleave', data)
        }
        triggerMouseEvent(el, 'mouseenter', data)
        element = el
      }
      triggerMouseEvent(el, 'mouseover', data)
    }
  }

  function triggerKey(data) {
    var el = document.elementFromPoint(data.elX, data.elY)
    if (data.value && el) {
      if (el.tagName !== 'INPUT') {
        if (el = el.querySelector('input')) {
          el.value = data.value
        }
      } else {
        el.value = data.value
      }
    }
  }

  function triggerEvent(data) {
    var el = document.elementFromPoint(data.x, data.y)
    if (el) {
      if (data.type === 'focus') {
        var ev = new FocusEvent(data.type)
      } else {
        var ev = new Event(data.type)
      }
      el.dispatchEvent(ev)
    }
  }

  function update(cursor, data) {
    cursor.style.display = 'none'

    switch (data.type) {
      case 'mousemove':
        cursor.style.top = data.y + 'px'
        cursor.style.left = data.x + 'px'
        break;
      case 'click':
        triggerClick(data)
        break;
      case 'scroll':
        triggerScroll(data.pageX, data.pageY)
        break;
      case 'keyup':
        triggerKey(data)
        break
      default:
        triggerEvent(data)
        break;
    }

    triggers(data)
    cursor.style.display = 'block'
  }

  var webmotely = global.webmotely = function (options) {
    return new Webmotely(options)
  }

  webmotely.start = function (options) {
    return webmotely(options)
  }

}(window))
<|endoftext|>


<commit_before>module.exports = {
  // Where to render the table of contents.
  tocSelector: '.js-toc',
  // Where to grab the headings to build the table of contents.
  contentSelector: '.js-toc-content',
  // Which headings to grab inside of the contentSelector element.
  headingSelector: 'h1, h2, h3',
  // Headings that match the ignoreSelector will be skipped.
  ignoreSelector: '.js-toc-ignore',
  // Main class to add to links.
  linkClass: 'toc-link',
  // Extra classes to add to links.
  extraLinkClasses: '',
  // Class to add to active links,
  // the link corresponding to the top most heading on the page.
  activeLinkClass: 'is-active-link',
  // Main class to add to lists.
  listClass: 'toc-list',
  // Extra classes to add to lists.
  extraListClasses: '',
  // Class that gets added when a list should be collapsed.
  isCollapsedClass: 'is-collapsed',
  // Class that gets added when a list should be able
  // to be collapsed but isn't necessarily collpased.
  collapsibleClass: 'is-collapsible',
  // Class to add to list items.
  listItemClass: 'toc-list-item',
  // How many heading levels should not be collpased.
  // For example, number 6 will show everything since
  // there are only 6 heading levels and number 0 will collpase them all.
  // The sections that are hidden will open
  // and close as you scroll to headings within them.
  collapseDepth: 0,
  // Smooth scrolling enabled.
  smoothScroll: true,
  // Smooth scroll duration.
  smoothScrollDuration: 420,
  // Callback for scroll end (requires: smoothScroll).
  scrollEndCallback: function (e) {},
  // Headings offset between the headings and the top of the document (this is meant for minor adjustments).
  headingsOffset: 0,
  // Timeout between events firing to make sure it's
  // not too rapid (for performance reasons).
  throttleTimeout: 50,
  // Element to add the positionFixedClass to.
  positionFixedSelector: null,
  // Fixed position class to add to make sidebar fixed after scrolling
  // down past the fixedSidebarOffset.
  positionFixedClass: 'is-position-fixed',
  // fixedSidebarOffset can be any number but by default is set
  // to auto which sets the fixedSidebarOffset to the sidebar
  // element's offsetTop from the top of the document on init.
  fixedSidebarOffset: 'auto',
  // includeHtml can be set to true to include the HTML markup from the
  // heading node instead of just including the textContent.
  includeHtml: false
}
<commit_msg>make headings offset 1<commit_after>module.exports = {
  // Where to render the table of contents.
  tocSelector: '.js-toc',
  // Where to grab the headings to build the table of contents.
  contentSelector: '.js-toc-content',
  // Which headings to grab inside of the contentSelector element.
  headingSelector: 'h1, h2, h3',
  // Headings that match the ignoreSelector will be skipped.
  ignoreSelector: '.js-toc-ignore',
  // Main class to add to links.
  linkClass: 'toc-link',
  // Extra classes to add to links.
  extraLinkClasses: '',
  // Class to add to active links,
  // the link corresponding to the top most heading on the page.
  activeLinkClass: 'is-active-link',
  // Main class to add to lists.
  listClass: 'toc-list',
  // Extra classes to add to lists.
  extraListClasses: '',
  // Class that gets added when a list should be collapsed.
  isCollapsedClass: 'is-collapsed',
  // Class that gets added when a list should be able
  // to be collapsed but isn't necessarily collpased.
  collapsibleClass: 'is-collapsible',
  // Class to add to list items.
  listItemClass: 'toc-list-item',
  // How many heading levels should not be collpased.
  // For example, number 6 will show everything since
  // there are only 6 heading levels and number 0 will collpase them all.
  // The sections that are hidden will open
  // and close as you scroll to headings within them.
  collapseDepth: 0,
  // Smooth scrolling enabled.
  smoothScroll: true,
  // Smooth scroll duration.
  smoothScrollDuration: 420,
  // Callback for scroll end (requires: smoothScroll).
  scrollEndCallback: function (e) {},
  // Headings offset between the headings and the top of the document (this is meant for minor adjustments).
  headingsOffset: 1,
  // Timeout between events firing to make sure it's
  // not too rapid (for performance reasons).
  throttleTimeout: 50,
  // Element to add the positionFixedClass to.
  positionFixedSelector: null,
  // Fixed position class to add to make sidebar fixed after scrolling
  // down past the fixedSidebarOffset.
  positionFixedClass: 'is-position-fixed',
  // fixedSidebarOffset can be any number but by default is set
  // to auto which sets the fixedSidebarOffset to the sidebar
  // element's offsetTop from the top of the document on init.
  fixedSidebarOffset: 'auto',
  // includeHtml can be set to true to include the HTML markup from the
  // heading node instead of just including the textContent.
  includeHtml: false
}
<|endoftext|>


<commit_before>$( document ).ready(function() {

    //nav to site
    //window.location.replace('http://www.oszimt.de/stundenplan/KPlan1.php?Klasse=OG+3');
    //are there checkboxes here?
    //if yes check all and click button, then collect data
    //if no collect data

    $.getJSON('http://whateverorigin.org/get?url=' + encodeURIComponent('http://www.oszimt.de/stundenplan/KPlan1.php?Klasse=OG+3') + '&callback=?', function(data){
	alert(data.contents);
    });

    // check boxes
    $(':checkbox').prop('checked', true);

    //click button
    $( ":submit" ).click(function() {
	alert( "Handler for .click() called." );
    });

//data collection
var json = [];
$( "table.plan td.plan_inhalt > table" ).map(function(index) {
	    var obj = {},
			$td = $(this).find('td');
			//console.log($td);
			//$td = $(this).$("td");
			info = $td.parent().parent().parent();
	if (info.hasClass("kplan_inhalt_bg_normal")) {
		obj["Fach"] = $td.eq(0).text();
		//TODO add woche
		obj["Raum"] = $td.eq(1).text();
		obj["Lehrer"] = $td.eq(2).text();
	} else if (info.hasClass("kplan_inhalt_bg_vertretung")) {
		obj["Fach"] = $td.eq(1).text();
	    obj["Raum"] = $td.eq(2).text();
		obj["Lehrer"] = $td.eq(3).text();
		obj["Vertetung"] = true;
	} else if (info.hasClass("kplan_inhalt_bg_ausfall")) {
	    //LEHRER NISCHT GEFUNDEN....
	    // naja trotzdem adden...
	    	obj["Fach"] = $td.eq(1).text();
		obj["Raum"] = $td.eq(2).text();
		obj["Lehrer"] = $td.eq(3).text();
		obj["Vertetung"] = true;
	}
    json.push(obj);

  //return index +": "+$(this).toArray().join(",");
  //return $(this).append("|").text();
  //console.log( index + ": " + $( this ).text() );
  //var y = $("td").each(function(index){
	//return index +": "+$(this).text();
  //});
  //return y;

 });
 //});
//console.log(x.toString());
console.log(json);

//console.debug(x);

});

//now.... push to db?
<commit_msg>cleanup<commit_after>$( document ).ready(function() {

//do navigation with phantomjs

//data collection
var json = [];
$( "table.plan td.plan_inhalt > table" ).map(function(index) {
	    var obj = {},
			$td = $(this).find('td');
			info = $td.parent().parent().parent();
	if (info.hasClass("kplan_inhalt_bg_normal")) {
		obj["Fach"] = $td.eq(0).text();
		//TODO add wochenlogik
		obj["Raum"] = $td.eq(1).text();
		obj["Lehrer"] = $td.eq(2).text();
	} else if (info.hasClass("kplan_inhalt_bg_vertretung")) {
		obj["Fach"] = $td.eq(1).text();
	    obj["Raum"] = $td.eq(2).text();
		obj["Lehrer"] = $td.eq(3).text();
		obj["Vertetung"] = true;
	} else if (info.hasClass("kplan_inhalt_bg_ausfall")) {
	    //LEHRER NISCHT GEFUNDEN....
	    // naja trotzdem adden...
	    	obj["Fach"] = $td.eq(1).text();
		obj["Raum"] = $td.eq(2).text();
		obj["Lehrer"] = $td.eq(3).text();
		obj["Vertetung"] = true;
	}
    json.push(obj);
 });
console.log(json);
});

//now.... push to db?
<|endoftext|>


<commit_before>/*
 * Constructs parent-child JSON by iterating over the OUs from API after level-order sorting.
*/
function constructD3JSON(sortedOUs) {
    // initialize root OU
    var outputJson = {};
    outputJson['name'] = 'root';
    outputJson['description'] = 'The root organizational unit.';
    outputJson['orgUnitPath'] = '/';
    outputJson['parentOrgUnitPath'] = '';
    outputJson['blockInheritance'] = false;
    outputJson['children'] = [];

    for (var i = 0; i < sortedOUs.length; i++) {
        addToJSON(sortedOUs[i], outputJson);
    }
    return outputJson;
}

/*
 * Adds each OU to the output JSON.
*/
function addToJSON(ou, outputJson) {
    var parentOrgUnitPath = ou['parentOrgUnitPath'];

    ou.children = [];

    if (parentOrgUnitPath === '/') {
        // can add directly as child of root
        outputJson['children'].push(ou);
        return;
    }

    var parentArr = parentOrgUnitPath.split('/');
    // first element of split will always be empty string
    parentArr.shift();

    var currentLevel = outputJson['children'];
    // keep searching deeper until we've reached the OU's direct parent
    while (parentArr.length !== 0) {
        var parentQuery = parentArr.shift(); // pops off highest level parent
        // scan this level's OUs for the queried parent
        for (orgUnit of currentLevel) {
            if (orgUnit['name'] == parentQuery) {
                currentLevel = orgUnit['children'];
                break;
            }
        }
    }

    // once reached direct parent, append the OU to children
    currentLevel.push(ou);
}

/*
 * Returns a list of OUs matching the name search criterion.
*/
function searchOU(searchName) {
    var ouSearchMatches = [];
    var searchNameStd = searchName.trim().toLowerCase();

    for (ouElem of orgUnits) {
        var ouName = ouElem['name'].trim().toLowerCase();

        if (ouName.includes(searchNameStd)) {
            ouSearchMatches.push(ouElem);
        }
    }
    return ouSearchMatches;
}

/*
 * Computes an org unit's depth using the number of slashes in its path.
*/
function computeDepth(orgUnit) {
    // +1, as the root OU is considered layer 1
    return (orgUnit['orgUnitPath'].match(/\//g) || []).length + 1;
}

/*
 * Compare function; sorts by by file depth, with parents first.
*/
function ouDepthSort(ou1, ou2) {
    ouDepth1 = computeDepth(ou1);
    ouDepth2 = computeDepth(ou2);
    return ouDepth1 - ouDepth2;
}

/*
 * Given an OU, finds all its parents. Used for Search display.
*/
async function retrieveOUParents(searchedOU) {
    // assemble the matching query's parents
    var limitedOUs = [];
    var parentOrgUnitPath = searchedOU['parentOrgUnitPath'];
    var parentArr = parentOrgUnitPath.split('/');
    // first elem is always empty
    parentArr.shift();

    // need to match OUs by paths (which are unique) rather than by names
    var pathSoFar = '';

    while (parentArr.length != 0) {
        pathSoFar = pathSoFar + '/' + parentArr.shift();

        for (unit of orgUnits) {
            if (unit['orgUnitPath'] == pathSoFar) {
                limitedOUs.push(unit);
                break;
            }
        }
    }

    limitedOUs.push(searchedOU);
    return limitedOUs;
}<commit_msg>resolved error<commit_after>/*
 * Constructs parent-child JSON by iterating over the OUs from API after level-order sorting.
*/
function constructD3JSON(sortedOUs) {
    // initialize root OU
    var outputJson = {};
    outputJson['name'] = 'root';
    outputJson['description'] = 'The root organizational unit.';
    outputJson['orgUnitPath'] = '/';
    outputJson['parentOrgUnitPath'] = '';
    outputJson['blockInheritance'] = false;
    outputJson['children'] = [];

    for (var i = 0; i < sortedOUs.length; i++) {
        addToJSON(sortedOUs[i], outputJson);
    }
    return outputJson;
}

/*
 * Adds each OU to the output JSON.
*/
function addToJSON(ou, outputJson) {
    var parentOrgUnitPath = ou['parentOrgUnitPath'];

    ou.children = [];

    if (parentOrgUnitPath === '/') {
        // can add directly as child of root
        outputJson['children'].push(ou);
        return;
    }

    var parentArr = parentOrgUnitPath.split('/');
    // first element of split will always be empty string
    parentArr.shift();

    var currentLevel = outputJson['children'];
    // keep searching deeper until we've reached the OU's direct parent
    while (parentArr.length !== 0) {
        var parentQuery = parentArr.shift(); // pops off highest level parent
        // scan this level's OUs for the queried parent
        for (orgUnit of currentLevel) {
            if (orgUnit['name'] == parentQuery) {
                currentLevel = orgUnit['children'];
                break;
            }
        }
    }

    // once reached direct parent, append the OU to children
    currentLevel.push(ou);
}

/*
 * Returns a list of OUs matching the name search criterion.
*/
function searchOU(searchName) {
    var ouSearchMatches = [];
    var searchNameStd = searchName.trim().toLowerCase();

    for (ouElem of orgUnits) {
        var ouName = ouElem['name'].trim().toLowerCase();

        if (ouName.includes(searchNameStd)) {
            ouSearchMatches.push(ouElem);
        }
    }
    return ouSearchMatches;
}

/*
 * Computes an org unit's depth using the number of slashes in its path.
*/
function computeDepth(orgUnit) {
    // +1, as the root OU is considered layer 1
    return (orgUnit['orgUnitPath'].match(/\//g) || []).length + 1;
}

/*
 * Compare function; sorts by by file depth, with parents first.
*/
function ouDepthSort(ou1, ou2) {
    ouDepth1 = computeDepth(ou1);
    ouDepth2 = computeDepth(ou2);
    return ouDepth1 - ouDepth2;
}

/*
 * Given an OU, finds all its parents. Used for Search display.
*/
function retrieveOUParents(searchedOU) {
    // assemble the matching query's parents
    var limitedOUs = [];
    var parentOrgUnitPath = searchedOU['parentOrgUnitPath'];
    var parentArr = parentOrgUnitPath.split('/');
    // first elem is always empty
    parentArr.shift();

    // need to match OUs by paths (which are unique) rather than by names
    var pathSoFar = '';

    while (parentArr.length != 0) {
        pathSoFar = pathSoFar + '/' + parentArr.shift();

        for (unit of orgUnits) {
            if (unit['orgUnitPath'] == pathSoFar) {
                limitedOUs.push(unit);
                break;
            }
        }
    }

    limitedOUs.push(searchedOU);
    return limitedOUs;
}<|endoftext|>


<commit_before>/* document.addEventListener('DOMContentLoaded', function() {
    alert("Ready!");
}, false); */

$(document).ready(function(){
	// Send an AJAX request, to retrieve all articles, as soon as page loads
	$.ajax({
		url: '/writeajax',
		type: 'GET',

		success: function(received_data){
			var data = JSON.parse(received_data);
			//console.log(received_data);

			for (var i=0; i<data.length; i++) {
				var datum = data[i];
				var title = datum.kind + '/' + datum['link'];
				// If title is not null
				if (datum.title) {
					title = title + '  (' + datum.title  + ')';
				}

				var one_article = $('
' +
					'
' + title + '
' +
					'
' +
						'
' + datum['kind'] + '
' +
						'last edited: ' + datum['lastEdited'] +
					'
' +
					'
' + datum['description'] + '
' +
					'
');
				one_article.data('id', datum.id);
				$('#display-articles').append(one_article);
			}

		},
		error: function(e){
			console.log('Error' + e);
		}
	});

	// Click on previous article title should lead to writedown page
	$('#display-articles').on('click', '.each-article-title', function() {
		window.location.href = '../writedown?id='+$(this).parent().data('id');
	});

	// Check Availability of links
	$('#check-avail').on('click', 'a', function() {
		// Read off the form values
		var link = $('#choose-article-link').val()
		var kind = $('#choose-article-kind').val()
		// if link is empty, do nothing
		if (link) {
			$.ajax({
				url: '/writecheck',
				type: 'GET',
				data: {"link":link, "kind":kind},

				success: function(received_data){
					var data = JSON.parse(received_data);
					if (data.result) {
						// available

						$('#check-avail').find('div').html('Available');
					}

					else {
						$('#check-avail').find('div').html('Not Available');
					}

					// Fade away result after 5s
					setTimeout(function() {
						$('#check-avail').find('div').html('');
					}, 5000)
				},
				error: function(e){
					console.log('Error' + e);
				}
			});
		}
	});

	// Form Submit for a new article
	$('#new-article-form').submit(function(e) {
		// Prevent auto refresh
		e.preventDefault();
		var link = $('#choose-article-link').val()
		var kind = $('#choose-article-kind').val()
		// if link is empty, do nothing
		if (link) {
			$.ajax({
				url: '/write',
				type: 'POST',
				data: {"link":link, "kind":kind},

				success: function(received_data){
					var data = JSON.parse(received_data);
					if (data.result) {
						// New article successful
						$('#check-avail').find('div').html('Link Available');
						// Forward to writedown
						window.location.href = '../writedown?id='+data.id;
					}

					else {
						$('#check-avail').find('div').html('Link Not Available');
					}

					// Fade away result after 5s
					setTimeout(function() {
						$('#check-avail').find('div').html('');
					}, 5000)
				},
				error: function(e){
					console.log('Error' + e);
				}
			});
		}
	})
})
<commit_msg>Red input link field if submit without value<commit_after>/* document.addEventListener('DOMContentLoaded', function() {
    alert("Ready!");
}, false); */

$(document).ready(function(){
	// Send an AJAX request, to retrieve all articles, as soon as page loads
	$.ajax({
		url: '/writeajax',
		type: 'GET',

		success: function(received_data){
			var data = JSON.parse(received_data);
			//console.log(received_data);

			for (var i=0; i<data.length; i++) {
				var datum = data[i];
				var title = datum.kind + '/' + datum['link'];
				// If title is not null
				if (datum.title) {
					title = title + '  (' + datum.title  + ')';
				}

				var one_article = $('
' +
					'
' + title + '
' +
					'
' +
						'
' + datum['kind'] + '
' +
						'last edited: ' + datum['lastEdited'] +
					'
' +
					'
' + datum['description'] + '
' +
					'
');
				one_article.data('id', datum.id);
				$('#display-articles').append(one_article);
			}

		},
		error: function(e){
			console.log('Error' + e);
		}
	});

	// Click on previous article title should lead to writedown page
	$('#display-articles').on('click', '.each-article-title', function() {
		window.location.href = '../writedown?id='+$(this).parent().data('id');
	});

	// Check Availability of links
	$('#check-avail').on('click', 'a', function() {
		// Read off the form values
		var link = $('#choose-article-link').val()
		var kind = $('#choose-article-kind').val()
		// if link is empty, do nothing
		if (link) {
			$.ajax({
				url: '/writecheck',
				type: 'GET',
				data: {"link":link, "kind":kind},

				success: function(received_data){
					var data = JSON.parse(received_data);
					if (data.result) {
						// available
						$('#check-avail').find('div').html('Available');
					}

					else {
						$('#check-avail').find('div').html('Not Available');
					}

					// Fade away result after 5s
					setTimeout(function() {
						$('#check-avail').find('div').html('');
					}, 5000);
				},
				error: function(e){
					console.log('Error' + e);
				}
			});
		}
		// if link is empty show red around the input field
		else {
			$('#choose-article-link').parent().addClass('has-error');
			// remove red backlining after 5s
			setTimeout(function() {
				$('#choose-article-link').parent().removeClass('has-error');
			}, 5000);
		}
	});

	// Form Submit for a new article
	$('#new-article-form').submit(function(e) {
		// Prevent auto refresh
		e.preventDefault();
		var link = $('#choose-article-link').val()
		var kind = $('#choose-article-kind').val()
		// if link is empty, do nothing
		if (link) {
			$.ajax({
				url: '/write',
				type: 'POST',
				data: {"link":link, "kind":kind},

				success: function(received_data){
					var data = JSON.parse(received_data);
					if (data.result) {
						// New article successful
						$('#check-avail').find('div').html('Link Available');
						// Forward to writedown
						window.location.href = '../writedown?id='+data.id;
					}

					else {
						$('#check-avail').find('div').html('Link Not Available');
					}

					// Fade away result after 5s
					setTimeout(function() {
						$('#check-avail').find('div').html('');
					}, 5000)
				},
				error: function(e){
					console.log('Error' + e);
				}
			});
		}
		// if link is empty show red around the input field
		else {
			$('#choose-article-link').parent().addClass('has-error');
			// remove red backlining after 5s
			setTimeout(function() {
				$('#choose-article-link').parent().removeClass('has-error');
			}, 5000);
		}
	})
})
<|endoftext|>


<commit_before>/* global EMPWorldWind */

/**
 *
 * @param {object} args
 * @param {object} args.engine
 * @param {object} args.engine.properties
 * @param {boolean} [args.engine.properties.debug]
 * @param {object} [args.engine.properties.layers]
 * @param {string} [args.engine.properties.elevationData]
 * @param {WMSDescriptor[]|TileServiceDescriptor[]} [args.engine.properties.defaultLayers] List of URL of the base layers
 * @returns {{resourceList: Array, fnCreateInstance: createWorldWindInstance}}
 */
function initializeWorldwind(args) {
  args.engine = args.engine || {};
  args.engine.properties = args.engine.properties || {};
  args.engine.properties.layers = args.engine.properties.layers || {};
  args.engine.properties.defaultLayers = args.engine.properties.defaultLayers || [];

  var resourceList = [];

  function createWorldWindInstance(instArgs) {
    var i;

    try {
      instArgs.mapInstance.engine = new emp.engineDefs.worldWindMapEngine({
        mapInstance: instArgs.mapInstance
      });

      var container = document.getElementById(instArgs.mapInstance.container.get());

      var wwCanvas = document.createElement("canvas");
      wwCanvas.setAttribute("id", instArgs.mapInstance.mapInstanceId + "_canvas");
      wwCanvas.style.height = "100%";
      wwCanvas.style.width = "100%";
      container.appendChild(wwCanvas);

      // TODO pass in an elevationModel that uses local dat
      var wwd = new WorldWind.WorldWindow(wwCanvas.id);

      // Tell the World Window that we want deep picking.
      wwd.deepPicking = true;

      // Always add a default layer
      var blueMarbleDefault = new WorldWind.BMNGOneImageLayer();
      blueMarbleDefault.minActiveAltitude = 0; // Don't let it disappear in case no other layers exist
      wwd.addLayer(blueMarbleDefault);

      // Add some image layers to the World Window"s globe.
      var numLayers = args.engine.properties.defaultLayers.length;

      for (i = 0; i < numLayers; i++) {
        var layer,
          descriptor = args.engine.properties.defaultLayers[i];

        if (!descriptor.type) {
          window.console.warn('No type specified for layer data; skipping it');
          continue;
        }

        switch (descriptor.type.toLowerCase()) {
          case "wms":
            // Handle defaults
            descriptor.sector = descriptor.sector || WorldWind.Sector.FULL_SPHERE;
            descriptor.levelZeroDelta = descriptor.levelZeroDelta || new WorldWind.Location(45, 45);
            descriptor.numLevels = descriptor.numLevels || 15;
            descriptor.format = descriptor.format || "image/png";
            descriptor.size = descriptor.size || 256;

            layer = new WorldWind.WmsLayer(descriptor);
            break;
          case "arcgis93rest":
          case "wmts":
          default:
          // Not yet supported
        }

        // Add the layer
        if (layer) {
          wwd.addLayer(layer);
        }
      }

      // Add a compass, a coordinates display and some view controls to the World Window.
      if (args.engine.properties.layers.compass) {
        wwd.addLayer(new WorldWind.CompassLayer());
      }
      if (args.engine.properties.layers.coordinates) {
        wwd.addLayer(new WorldWind.CoordinatesDisplayLayer(wwd));
      }
      if (args.engine.properties.layers.controls) {
        wwd.addLayer(new WorldWind.ViewControlsLayer(wwd));
      }

      var empWorldWind = new EMPWorldWind.Map(wwd);
      empWorldWind.initialize(instArgs);
      instArgs.mapInstance.engine.initialize.succeed(empWorldWind);
    } catch (err) {
      instArgs.mapInstance.engine.initialize.fail(err);
      window.console.log("+++++++++++++error initializing engine: " + err);
    }
  }

  if (args.engine.properties.debug === true) {
    resourceList = [
      "worldwind.js",
      "worldwind-map-engine.js",
      "EMPWorldWind.js",
      "data/EMPWorldWind.data.js",
      "data/EMPWorldWind.data.EmpLayer.js",
      "data/EMPWorldWind.data.EmpWMSLayer.js",
      "data/EMPWorldWind.data.EmpFeature.js",
      "utils/EMPWorldWind.constants.js",
      "utils/EMPWorldWind.utils.js",
      "controllers/editors/EMPWorldWind.editors.primitiveBuilders.js",
      "controllers/editors/EMPWorldWind.editors.EditorController.js",
      "controllers/eventHandlers/EMPWorldWind.eventHandlers.js",
      "controllers/eventHandlers/EMPWorldWind.eventHandlers.mouse.js",
      "controllers/eventHandlers/EMPWorldWind.eventHandlers.touch.js",
      "controllers/eventHandlers/EMPWorldWind.eventHandlers.drag.js",
      "controllers/eventHandlers/EMPWorldWind.eventHandlers.pointer.js"
    ];
  } else {
    resourceList = [
      "worldwind.min.js",
      "emp3-worldwind.min.js"
    ];
  }

  return {
    resourceList: resourceList,
    fnCreateInstance: createWorldWindInstance
  };
}

emp.instanceManager.registerMapEngine({
    mapEngineId: emp.constant.mapEngineId.WORLD_WIND,
    fnInitialize: initializeWorldwind
  }
);

/**
 * @typedef {object} WMSDescriptor
 * @property {string} service
 * @property {string} layerNames comma separated list
 * @property {WorldWind.Sector} sector
 * @property {WorldWind.Location} levelZeroDelta
 * @property {number} numLevels
 * @property {string} format example 'image/png'
 * @property {number} size
 * @property {string} [coordinateSystem]
 * @property {string} [styleNames]
 */

/**
 * @typedef {object} TileServiceDescriptor
 * @property {WorldWind.Sector} [sector=WorldWind.Sector.FULL_SPHERE]
 * @property {WorldWind.Location} [levelZeroTileData = '45,45']
 * @property {number} [numLevels=5]
 * @property {string} [imageFormat ='image/jpeg']
 * @property {number} [tileWidth=256]
 * @property {number} [tileHeight=256]
 */
<commit_msg>fixed some complexity issues<commit_after>/* global EMPWorldWind */

/**
 *
 * @param {object} args
 * @param {object} args.engine
 * @param {object} args.engine.properties
 * @param {boolean} [args.engine.properties.debug]
 * @param {object} [args.engine.properties.layers]
 * @param {string} [args.engine.properties.elevationData]
 * @param {WMSDescriptor[]|TileServiceDescriptor[]} [args.engine.properties.defaultLayers] List of URL of the base layers
 * @returns {{resourceList: Array, fnCreateInstance: createWorldWindInstance}}
 */
function initializeWorldwind(args) {
  args.engine = args.engine || {};
  args.engine.properties = args.engine.properties || {};
  args.engine.properties.layers = args.engine.properties.layers || {};
  args.engine.properties.defaultLayers = args.engine.properties.defaultLayers || [];

  /**
   * Generates the correct list of resource files
   * @param args
   * @private
   */
  function _generateResourceList(args) {
    var debug, resourceList;

    try {
      debug = args.engine.properties.debug;
    } catch (err) {
      debug = false;
    }

    if (debug) {
      resourceList = [
        "worldwind.js",
        "worldwind-map-engine.js",
        "EMPWorldWind.js",
        "data/EMPWorldWind.data.js",
        "data/EMPWorldWind.data.EmpLayer.js",
        "data/EMPWorldWind.data.EmpWMSLayer.js",
        "data/EMPWorldWind.data.EmpFeature.js",
        "utils/EMPWorldWind.constants.js",
        "utils/EMPWorldWind.utils.js",
        "controllers/editors/EMPWorldWind.editors.primitiveBuilders.js",
        "controllers/editors/EMPWorldWind.editors.EditorController.js",
        "controllers/eventHandlers/EMPWorldWind.eventHandlers.js",
        "controllers/eventHandlers/EMPWorldWind.eventHandlers.mouse.js",
        "controllers/eventHandlers/EMPWorldWind.eventHandlers.touch.js",
        "controllers/eventHandlers/EMPWorldWind.eventHandlers.drag.js",
        "controllers/eventHandlers/EMPWorldWind.eventHandlers.pointer.js"
      ];
    } else {
      resourceList = [
        "worldwind.min.js",
        "emp3-worldwind.min.js"
      ];
    }
    return resourceList;
  }

  function createWorldWindInstance(instArgs) {
    var empWorldWind, container, wwCanvas, wwd, layers, uiComponents;

    function _addDefaultLayer(wwd) {
      // Always add a default layer
      var blueMarbleDefault = new WorldWind.BMNGOneImageLayer();
      blueMarbleDefault.minActiveAltitude = 0; // Don't let it disappear in case no other layers exist
      wwd.addLayer(blueMarbleDefault);
    }

    function _addConfigLayers(wwd, layers) {
      var i,
        layerDict = {
          "wms": function(descriptor) {
            descriptor.sector = descriptor.sector || WorldWind.Sector.FULL_SPHERE;
            descriptor.levelZeroDelta = descriptor.levelZeroDelta || new WorldWind.Location(45, 45);
            descriptor.numLevels = descriptor.numLevels || 15;
            descriptor.format = descriptor.format || "image/png";
            descriptor.size = descriptor.size || 256;

            return new WorldWind.WmsLayer(descriptor);
          }
        };

      // Add some image layers to the World Window"s globe.
      var numLayers = layers.length;

      for (i = 0; i < numLayers; i++) {
        var layer,
          descriptor = layers[i];

        if (!descriptor.type) {
          window.console.warn('No type specified for layer data; skipping it');
          continue;
        }

        if (layerDict.hasOwnProperty(descriptor.type.toLowerCase())) {
          layer = layerDict[descriptor.type.toLowerCase()](descriptor);
          wwd.addLayer(layer);
        }
      }
    }

    function _addUIComponents(wwd, args) {
      if (args.compass) {
        wwd.addLayer(new WorldWind.CompassLayer());
      }
      if (args.coordinates) {
        wwd.addLayer(new WorldWind.CoordinatesDisplayLayer(wwd));
      }
      if (args.controls) {
        wwd.addLayer(new WorldWind.ViewControlsLayer(wwd));
      }
    }

    // Create WorldWind
    try {
      instArgs.mapInstance.engine = new emp.engineDefs.worldWindMapEngine({
        mapInstance: instArgs.mapInstance
      });

      container = document.getElementById(instArgs.mapInstance.container.get());

      wwCanvas = document.createElement("canvas");
      wwCanvas.setAttribute("id", instArgs.mapInstance.mapInstanceId + "_canvas");
      wwCanvas.style.height = "100%";
      wwCanvas.style.width = "100%";
      container.appendChild(wwCanvas);

      // TODO pass in an elevationModel that uses local dat
      wwd = new WorldWind.WorldWindow(wwCanvas.id);

      // Tell the World Window that we want deep picking.
      wwd.deepPicking = true;

      // Add default and configured layers
      _addDefaultLayer(wwd);

      // Add layers from the config
      try {
        layers = args.engine.properties.defaultLayers;
      } catch (err) {
        layers = [];
      }
      _addConfigLayers(wwd, layers);

      // Add a compass, a coordinates display and some view controls to the World Window.
      try {
        uiComponents = args.engine.properties.layers;
      } catch (err) {
        uiComponents = {
          compass: false,
          coordinates: false,
          controls: false
        };
      }
      _addUIComponents(wwd, uiComponents);

      // Register WorldWind with EMP
      empWorldWind = new EMPWorldWind.Map(wwd);
      empWorldWind.initialize(instArgs);
      instArgs.mapInstance.engine.initialize.succeed(empWorldWind);
    } catch (err) {
      instArgs.mapInstance.engine.initialize.fail(err);
      window.console.log("+++++++++++++error initializing engine: " + err);
    }
  }

  return {
    resourceList: _generateResourceList(args),
    fnCreateInstance: createWorldWindInstance
  };
}

emp.instanceManager.registerMapEngine({
    mapEngineId: emp.constant.mapEngineId.WORLD_WIND,
    fnInitialize: initializeWorldwind
  }
);

/**
 * @typedef {object} WMSDescriptor
 * @property {string} service
 * @property {string} layerNames comma separated list
 * @property {WorldWind.Sector} sector
 * @property {WorldWind.Location} levelZeroDelta
 * @property {number} numLevels
 * @property {string} format example 'image/png'
 * @property {number} size
 * @property {string} [coordinateSystem]
 * @property {string} [styleNames]
 */

/**
 * @typedef {object} TileServiceDescriptor
 * @property {WorldWind.Sector} [sector=WorldWind.Sector.FULL_SPHERE]
 * @property {WorldWind.Location} [levelZeroTileData = '45,45']
 * @property {number} [numLevels=5]
 * @property {string} [imageFormat ='image/jpeg']
 * @property {number} [tileWidth=256]
 * @property {number} [tileHeight=256]
 */
<|endoftext|>


<commit_before>'use strict';

  /**
  * Shared attributes between of the different entities, player and enemies.
  * @method Darwinator.Entity
  * @param {Phaser.Game}  - The current game instance
  * @param {Number}       - [x] The x-value of the pixel
  * @param {Number}       - [y] The y-value of the pixel
  * @param {Array}        - The array containing animations for the sprite
  * @param {Number}       - Entity health
  * @param {Number}       - Entity strength, defaults to 0. Used for increasing damage and health, reducing speed / stamina.
  * @param {Number}       - Entity agility, defaults to 0. Used for increasing speed and stamina.
  * @param {Number}       - Entity intellect, defaults to 0. Used for defining how well the entity aims and critical strike percentage.
  */
Darwinator.Entity = function(game, x, y, key, health, strength, agility, intellect) {
  Phaser.Sprite.call(this, game, x, y, key);

  game.physics.enable(this, Phaser.Physics.ARCADE);

  this.game                     = game;
  this.body.collideWorldBounds  = true;

  this.attributes = {
    strength  : !!strength  ? strength  : 0,
    agility   : !!agility   ? agility   : 0,
    intellect : !!intellect ? intellect : 0
  }

  var baseHealth = !!health ? health : Darwinator.ENTITY_BASE_HEALTH;

  this.health         = baseHealth + this.attributes.strength;
  this.damage         = Darwinator.ENTITY_BASE_DAMAGE  + this.attributes.strength / 3;
  this.speed          = Darwinator.ENTITY_BASE_SPEED   + this.attributes.agility;
  this.stamina        = Darwinator.ENTITY_BASE_STAMINA + this.attributes.agility * 2;
  this.aim            = this.attributes.intellect; // Intended to define how well the enemy aims. 0 = "shitty" aim, 100 = "perfect" aim
  this.criticalStrike = this.attributes.intellect / 100; // Critical strike percentage
  this.currBreath     = this.stamina;

  this.abilityCooldownMs  = Darwinator.ENTITY_ABILITY_COOLDOWN;
  this.lastAbilityUse     = 0;

  this.dodging              = false;
  this.dodgeDurationSeconds = 2;
  this.dodgeTimer           = null;
  this.underAttack          = false;

  // the alive property of Phaser sprites seems to be bugged
  this.dead = false;
};

Darwinator.Entity.prototype = Object.create(Phaser.Sprite.prototype);

Darwinator.Entity.prototype.update = function() {
  if (this.health <= 0 && !this.dead){
    this.kill();
    this.dead = true;
  }
};

Darwinator.Entity.prototype.takeDamage = function(amount) {
  this.health = this.health - amount;
  this.underAttack = true;
};

Darwinator.Entity.prototype.setAnimations = function(anims) {
  anims = anims || [];

  if (anims.length) {
    for (var i = 0; i < anims.length; i++) {
      var tmp = anims[i];
      this.animations.add.apply(this.animations, tmp);
    }
  }
};

Darwinator.Entity.prototype.tryDodge = function() {
  if((Date.now() - this.lastAbilityUse) >= this.abilityCooldownMs){
    this.dodging = true;
    this.underAttack = false;
    this.alpha = 0.5;
    this.lastAbilityUse = Date.now();
    var dodgeCallback = function() {this.dodging = false; this.alpha = 1; };
    this.dodgeTimer = this.game.time.events.add(Phaser.Timer.SECOND * this.dodgeDurationSeconds, dodgeCallback, this);
  }
};

Darwinator.Entity.prototype.tryTeleport = function(x, y, posFunction) {
  if((Date.now() - this.lastAbilityUse) >= this.abilityCooldownMs){
    if(posFunction){
      var pos = posFunction();
      x = pos.x;
      y = pos.y;
    }
    this.reset(x, y, this.health);
    this.lastAbilityUse = Date.now();
  }
};

Darwinator.Entity.prototype.resetAbilities = function(){
  this.lastAbilityUse = 0;

  this.game.time.events.remove(this.dodgeTimer);
  this.alpha        = 1;
  this.dodging      = false;
  this.underAttack  = false;
};
<commit_msg>function documentation<commit_after>'use strict';

  /**
  * Shared attributes between of the different entities, player and enemies.
  * @method Darwinator.Entity
  * @param {Phaser.Game}  - The current game instance
  * @param {Number}       - [x] The x-value of the pixel
  * @param {Number}       - [y] The y-value of the pixel
  * @param {Array}        - The array containing animations for the sprite
  * @param {Number}       - Entity health
  * @param {Number}       - Entity strength, defaults to 0. Used for increasing damage and health, reducing speed / stamina.
  * @param {Number}       - Entity agility, defaults to 0. Used for increasing speed and stamina.
  * @param {Number}       - Entity intellect, defaults to 0. Used for defining how well the entity aims and critical strike percentage.
  */
Darwinator.Entity = function(game, x, y, key, health, strength, agility, intellect) {
  Phaser.Sprite.call(this, game, x, y, key);

  game.physics.enable(this, Phaser.Physics.ARCADE);

  this.game                     = game;
  this.body.collideWorldBounds  = true;

  this.attributes = {
    strength  : !!strength  ? strength  : 0,
    agility   : !!agility   ? agility   : 0,
    intellect : !!intellect ? intellect : 0
  }

  var baseHealth = !!health ? health : Darwinator.ENTITY_BASE_HEALTH;

  this.health         = baseHealth + this.attributes.strength;
  this.damage         = Darwinator.ENTITY_BASE_DAMAGE  + this.attributes.strength / 3;
  this.speed          = Darwinator.ENTITY_BASE_SPEED   + this.attributes.agility;
  this.stamina        = Darwinator.ENTITY_BASE_STAMINA + this.attributes.agility * 2;
  this.aim            = this.attributes.intellect; // Intended to define how well the enemy aims. 0 = "shitty" aim, 100 = "perfect" aim
  this.criticalStrike = this.attributes.intellect / 100; // Critical strike percentage
  this.currBreath     = this.stamina;

  this.abilityCooldownMs  = Darwinator.ENTITY_ABILITY_COOLDOWN;
  this.lastAbilityUse     = 0;

  this.dodging              = false;
  this.dodgeDurationSeconds = 2;
  this.dodgeTimer           = null;
  this.underAttack          = false;

  // the alive property of Phaser sprites seems to be bugged
  this.dead = false;
};

Darwinator.Entity.prototype = Object.create(Phaser.Sprite.prototype);

Darwinator.Entity.prototype.update = function() {
  if (this.health <= 0 && !this.dead){
    this.kill();
    this.dead = true;
  }
};

Darwinator.Entity.prototype.takeDamage = function(amount) {
  this.health = this.health - amount;
  this.underAttack = true;
};

Darwinator.Entity.prototype.setAnimations = function(anims) {
  anims = anims || [];

  if (anims.length) {
    for (var i = 0; i < anims.length; i++) {
      var tmp = anims[i];
      this.animations.add.apply(this.animations, tmp);
    }
  }
};

/**
* Attempt to dodge bullets for this.dodgeDurationSeconds seconds. Does nothing if abilities are on cooldown.
*
* @method Darwinator.Entity#tryDodge
*/
Darwinator.Entity.prototype.tryDodge = function() {
  if((Date.now() - this.lastAbilityUse) >= this.abilityCooldownMs){
    this.dodging = true;
    this.underAttack = false;
    this.alpha = 0.5;
    this.lastAbilityUse = Date.now();
    var dodgeCallback = function() {this.dodging = false; this.alpha = 1; };
    this.dodgeTimer = this.game.time.events.add(Phaser.Timer.SECOND * this.dodgeDurationSeconds, dodgeCallback, this);
  }
};

/**
* Attempt to teleport the entity to a given position. Does nothing if abilities are on cooldown.
*
* @param {Number}     - [x] The x-coordinate.
* @param {Number}     - [y] The y-coordinate.
* @param {Function}   - [posFunction] Optional. A function returning an object with x and y properties.
* @method Darwinator.Entity#tryTeleport
*/
Darwinator.Entity.prototype.tryTeleport = function(x, y, posFunction) {
  if((Date.now() - this.lastAbilityUse) >= this.abilityCooldownMs){
    if(posFunction){
      var pos = posFunction();
      x = pos.x;
      y = pos.y;
    }
    this.reset(x, y, this.health);
    this.lastAbilityUse = Date.now();
  }
};

/**
* Resets ability effects as well as the ability cooldown.
*
* @method Darwinator.Entity#resetAbilities
*/
Darwinator.Entity.prototype.resetAbilities = function(){
  this.lastAbilityUse = 0;

  this.game.time.events.remove(this.dodgeTimer);
  this.alpha        = 1;
  this.dodging      = false;
  this.underAttack  = false;
};
<|endoftext|>


<commit_before>/*---------------------------------------------------------------------------*\
 |  App.js                                                                   |
 |                                                                           |
 |  Copyright © 2017-2021, Rajiv Bakulesh Shah, original author.             |
 |                                                                           |
 |      This program is free software: you can redistribute it and/or modify |
 |      it under the terms of the GNU General Public License as published by |
 |      the Free Software Foundation, either version 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    |
 |      General Public License for more details.                             |
 |                                                                           |
 |      You should have received a copy of the GNU General Public License    |
 |      along with this program.  If not, see:                               |
 |          <http://www.gnu.org/licenses/>                                   |
\*---------------------------------------------------------------------------*/

import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { Provider } from 'react-redux';

import store from '../store';
import About from './About';
import Home from './Home';
import Logo from './Logo';
import Precache from './Precache';

const App = React.memo(function App() {
  return (
    <Provider store={store}>
      <Router>
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/:artistId/:songId" component={Home} />
          <Route exact path="/wtf" component={About} />

          <Route exact path="/gtfo">
            {() => {
              window.location.href = 'http://redirects.spool.video/v1/gtfo';
            }}
          </Route>

          <Route exact path="/porn">
            {() => {
              window.location.href = 'http://redirects.spool.video/v1/porn';
            }}
          </Route>

        </Switch>
        <Route component={Logo} />
      </Router>
      <Precache />
    </Provider>
  );
});

export default App;
<commit_msg>Desperately hack<commit_after>/*---------------------------------------------------------------------------*\
 |  App.js                                                                   |
 |                                                                           |
 |  Copyright © 2017-2021, Rajiv Bakulesh Shah, original author.             |
 |                                                                           |
 |      This program is free software: you can redistribute it and/or modify |
 |      it under the terms of the GNU General Public License as published by |
 |      the Free Software Foundation, either version 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    |
 |      General Public License for more details.                             |
 |                                                                           |
 |      You should have received a copy of the GNU General Public License    |
 |      along with this program.  If not, see:                               |
 |          <http://www.gnu.org/licenses/>                                   |
\*---------------------------------------------------------------------------*/

import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { Provider } from 'react-redux';

import store from '../store';
import About from './About';
import Home from './Home';
import Logo from './Logo';
import Precache from './Precache';

const App = React.memo(function App() {
  return (
    <Provider store={store}>
      <Router>
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/:artistId/:songId" component={Home} />
          <Route exact path="/wtf" component={About} />

          <Route exact path="/gtfo">
            {() => {
              window.location.href = 'http://redirects.spool.video/v1/gtfo';
              return null;
            }}
          </Route>

          <Route exact path="/porn">
            {() => {
              window.location.href = 'http://redirects.spool.video/v1/porn';
              return null;
            }}
          </Route>

        </Switch>
        <Route component={Logo} />
      </Router>
      <Precache />
    </Provider>
  );
});

export default App;
<|endoftext|>


<commit_before>/**
 * @class Oskari.mapframework.bundle.rpc.RemoteProcedureCallInstance
 *
 * Main component and starting point for the RPC functionality.
 *
 * See Oskari.mapframework.bundle.rpc.RemoteProcedureCall for bundle definition.
 *
 */
Oskari.clazz.define(
    'Oskari.mapframework.bundle.rpc.RemoteProcedureCallInstance',
    function () {
        var me = this,
            allowedEvents,
            allowedRequests;

        if (!me.conf) {
            me.conf = {};
        }

        allowedEvents = me.conf.allowedEvents;
        allowedRequests = me.conf.allowedRequests;

        if (allowedEvents === null || allowedEvents === undefined) {
            allowedEvents = {
                AfterMapMoveEvent: true,
                MapClickedEvent: true
            };
        }

        if (allowedRequests === null || allowedRequests === undefined) {
            allowedRequests = {
                MapMoveRequest: true
            };
        }

        me._allowedEvents = allowedEvents;
        me._allowedRequests = allowedRequests;
        me._channel = null;
        me._localization = {};
    }, {
        /**
         * @public @method getName
         *
         *
         * @return {string} the name for the component
         */
        getName: function () {
            return 'RPC';
        },

        /**
         * @public @method start
         * BundleInstance protocol method
         */
        start: function () {
            var me = this,
                conf = this.conf,
                sandboxName = (conf ? conf.sandbox : null) || 'sandbox',
                sandbox = Oskari.getSandbox(sandboxName),
                domain = me.conf.domain,
                domainMatch = function (origin) {
                    return true;
                    // Allow subdomains and different ports
                    /*var ret = origin.indexOf(domain) !== -1,
                        parts;

                    if (ret) {
                        parts = origin.split(domain);
                        if (parts) {
                            ret = /^https?:\/\/([a-zA-Z0-9]+[.])*$/.test(parts[0]);
                            if (ret && parts.length > 1) {
                                ret = /^(:\d+)?$/.test(parts[1]);
                            }
                        } else {
                            // origin must have a protocol
                            ret = false;
                        }
                    }

                    return ret;*/
                },
                channel;

            me.sandbox = sandbox;
            sandbox.register(this);

            if (!Channel) {
                me.sandbox.printWarn('RemoteProcedureCallInstance.startPlugin(): JSChannel not found.');
                return;
            }

            if (domain === null || domain === undefined || !domain.length) {
                me.sandbox.printWarn('RemoteProcedureCallInstance.startPlugin(): missing domain.');
                return;
            }

            if (domain === '*') {
                me.sandbox.printWarn('RemoteProcedureCallInstance.startPlugin(): * is not an allowed domain.');
                return;
            }

            if (window === window.parent) {
                me.sandbox.printWarn('RemoteProcedureCallInstance.startPlugin(): Target window is same as present window - not allowed.');
                return;
            }

            channel = Channel.build({
                window: window.parent,
                origin: '*',
                scope: 'Oskari'
            });

            // Makes it possible to listen to events
            // channel.call({method: 'handleEvent', params: ['MapClickedEvent', true]});
            // TODO OskariRPC.handleEvent
            channel.bind(
                'handleEvent',
                function (trans, name, register) {
                    if (!domainMatch(trans.origin)) {
                        throw {
                            error: 'invalid_origin',
                            message: 'Invalid origin: ' + trans.origin
                        };
                    }
                    if (me._allowedEvents[name]) {
                        if (register) {
                            me._registerEventHandler(name);
                            return "Registered " + name;
                        } else {
                            me._unregisterEventHandler(name);
                            return "Unegistered " + name;
                        }
                    } else {
                        /*throw {
                            error: 'event_not_allowed',
                            message: 'Event not allowed: ' + name
                        };*/
                        return [
                            "Event not allowed: " + name,
                            me._allowedEvents,
                            name,
                            me._allowedEvents[name]
                        ];
                    }
                }
            );

            // Makes it possible to post requests
            // channel.call({method: 'postRequest', params: ['MapMoveRequest', [centerX, centerY, zoom, marker, srsName]]})
            // TODO OskariRPC.postRequest
            channel.bind(
                'postRequest',
                function (trans, name, params) {
                    if (!domainMatch(trans.origin)) {
                        throw {
                            error: 'invalid_origin',
                            message: 'Invalid origin: ' + trans.origin
                        };
                    }
                    if (me._allowedRequests[name]) {
                        var builder = me.sandbox.getRequestBuilder(name),
                            request;
                        if (builder) {
                            request = builder.apply(me, params);
                            me.sandbox.request(me, request);
                        } else {
                            throw {
                                error: 'builder_not_found',
                                message: 'No builder found for: ' + name
                            };
                        }
                    } else {
                        throw {
                            error: 'request_not_allowed',
                            message: 'Request not allowed: ' + name
                        };
                    }
                }
            );

            // bind getSupportedEvents
            channel.bind(
                'getSupportedEvents',
                function (trans) {
                    if (!domainMatch(trans.origin)) {
                        throw {
                            error: 'invalid_origin',
                            message: 'Invalid origin: ' + trans.origin
                        };
                    }
                    return me._allowedEvents;
                }
            );
            // bind getSupportedRequests
            channel.bind(
                'getSupportedRequests',
                function (trans) {
                    if (!domainMatch(trans.origin)) {
                        throw {
                            error: 'invalid_origin',
                            message: 'Invalid origin: ' + trans.origin
                        };
                    }
                    return me._allowedRequests;
                }
            );
            // bind get map position
            // TODO OskariRPC.getMapPosition
            channel.bind(
                'getMapPosition',
                function (trans) {
                    var map = me.sandbox.getMap();
                    if (!domainMatch(trans.origin)) {
                        throw {
                            error: 'invalid_origin',
                            message: 'Invalid origin: ' + trans.origin
                        };
                    }
                    return {
                        centerX: map.getY(),
                        centerY: map.getX(),
                        zoom: map.getZoom(),
                        srsName: map.getSrsName()
                    };
                }
            );

            channel.bind(
                'testOriginCheck',
                function (trans) {
                    return {
                        domain: domain,
                        origin: trans.origin,
                        test: domainMatch(trans.origin)
                    };
                }
            );

            me._channel = channel;
        },

        /**
         * @private @method _registerEventHandler
         *
         * @param {string} eventName Event name
         *
         */
        _registerEventHandler: function (eventName) {
            var me = this;
            if (me.eventHandlers[eventName]) {
                // Event handler already in place
                return;
            }
            me.eventHandlers[eventName] = function (event) {
                if (me._channel) {
                    me._channel.notify({
                        method: eventName,
                        params: me._getParams(event)
                    });
                }
            };
            me.sandbox.registerForEventByName(me, eventName);
        },

        /**
         * @method stop
         * BundleInstance protocol method
         */
        stop: function () {
            var me = this,
                sandbox = this.sandbox,
                p;

            for (p in me.eventHandlers) {
                if (me.eventHandlers.hasOwnProperty(p)) {
                    sandbox.unregisterFromEventByName(me, p);
                }
            }
            for (p in me.requestHandlers) {
                if (me.requestHandlers.hasOwnProperty(p)) {
                    sandbox.removeRequestHandler(p, this);
                }
            }
            sandbox.unregister(this);
            this.sandbox = null;
        },

        init: function () {
            return null;
        },
        /**
         * @method onEvent
         * @param {Oskari.mapframework.event.Event} event a Oskari event object
         * Event is handled forwarded to correct #eventHandlers if found or discarded if not.
         */
        onEvent: function (event) {
            var me = this,
                handler = me.eventHandlers[event.getName()];
            if (!handler) {
                return;
            }

            return handler.apply(this, [event]);
        },
        /**
         * @private @method _getParams
         * Returns event's simple variables as params.
         * This should suffice for simple events.
         * TODO see if this could be done with some library...
         *
         * @param  {Object} event Event
         *
         * @return {Object}       Event params
         */
        _getParams: function (event) {
            var ret = {},
                key,
                //strippedKey,
                value;

            if (event.getParams) {
                ret = event.getParams();
            } else {
                for (key in event) {
                    if (event.hasOwnProperty(key)) {
                        // Skip __name and such
                        if (key.indexOf('__') !== 0) {
                            value = event[key];
                            if (typeof value === 'string' ||
                                typeof value === 'number' ||
                                typeof value === 'boolean') {
                                /* try to make the key a tad cleaner?
                                strippedKey = key;
                                if (key.indexOf('_') === 0) {
                                    strippedKey = key.substring(1);
                                    if (event[strippedKey] === undefined) {
                                        key = strippedKey;
                                    }
                                }*/
                                ret[key] = value;
                            }
                        }
                    }
                }
            }

            return ret;
        },

        /**
         * @method update
         * BundleInstance protocol method
         */
        update: function () {},

        /**
         * @private @method _unregisterEventHandler
         *
         * @param {string} eventName
         *
         */
        _unregisterEventHandler: function (eventName) {
            delete this.eventHandlers[eventName];
            this.sandbox.unregisterFromEventByName(this, eventName);
        }
    }, {
        /**
         * @static @property {String[]} protocol
         */
        'protocol': ['Oskari.bundle.BundleInstance', 'Oskari.mapframework.module.Module']
    }
);
<commit_msg>[AH-1855] trying to get RPC origin check to work<commit_after>/**
 * @class Oskari.mapframework.bundle.rpc.RemoteProcedureCallInstance
 *
 * Main component and starting point for the RPC functionality.
 *
 * See Oskari.mapframework.bundle.rpc.RemoteProcedureCall for bundle definition.
 *
 */
Oskari.clazz.define(
    'Oskari.mapframework.bundle.rpc.RemoteProcedureCallInstance',
    function () {
        var me = this,
            allowedEvents,
            allowedRequests;

        if (!me.conf) {
            me.conf = {};
        }

        allowedEvents = me.conf.allowedEvents;
        allowedRequests = me.conf.allowedRequests;

        if (allowedEvents === null || allowedEvents === undefined) {
            allowedEvents = {
                AfterMapMoveEvent: true,
                MapClickedEvent: true
            };
        }

        if (allowedRequests === null || allowedRequests === undefined) {
            allowedRequests = {
                MapMoveRequest: true
            };
        }

        me._allowedEvents = allowedEvents;
        me._allowedRequests = allowedRequests;
        me._channel = null;
        me._localization = {};
    }, {
        /**
         * @public @method getName
         *
         *
         * @return {string} the name for the component
         */
        getName: function () {
            return 'RPC';
        },

        /**
         * @public @method start
         * BundleInstance protocol method
         */
        start: function () {
            var me = this,
                conf = this.conf,
                sandboxName = (conf ? conf.sandbox : null) || 'sandbox',
                sandbox = Oskari.getSandbox(sandboxName),
                domain = me.conf.domain,
                domainMatch = function (origin) {
                    return true;
                    // Allow subdomains and different ports
                    /*var ret = origin.indexOf(domain) !== -1,
                        parts;

                    if (ret) {
                        parts = origin.split(domain);
                        if (parts) {
                            ret = /^https?:\/\/([a-zA-Z0-9]+[.])*$/.test(parts[0]);
                            if (ret && parts.length > 1) {
                                ret = /^(:\d+)?$/.test(parts[1]);
                            }
                        } else {
                            // origin must have a protocol
                            ret = false;
                        }
                    }

                    return ret;*/
                },
                channel;

            me.sandbox = sandbox;
            sandbox.register(this);

            if (!Channel) {
                me.sandbox.printWarn('RemoteProcedureCallInstance.startPlugin(): JSChannel not found.');
                return;
            }

            if (domain === null || domain === undefined || !domain.length) {
                me.sandbox.printWarn('RemoteProcedureCallInstance.startPlugin(): missing domain.');
                return;
            }

            if (domain === '*') {
                me.sandbox.printWarn('RemoteProcedureCallInstance.startPlugin(): * is not an allowed domain.');
                return;
            }

            if (window === window.parent) {
                me.sandbox.printWarn('RemoteProcedureCallInstance.startPlugin(): Target window is same as present window - not allowed.');
                return;
            }

            channel = Channel.build({
                window: window.parent,
                origin: '*',
                scope: 'Oskari'
            });

            // Makes it possible to listen to events
            // channel.call({method: 'handleEvent', params: ['MapClickedEvent', true]});
            // TODO OskariRPC.handleEvent
            channel.bind(
                'handleEvent',
                function (trans, params) {
                    if (!domainMatch(trans.origin)) {
                        throw {
                            error: 'invalid_origin',
                            message: 'Invalid origin: ' + trans.origin
                        };
                    }
                    if (me._allowedEvents[params[0]]) {
                        if (params[1]) {
                            me._registerEventHandler(params[0]);
                            return "Registered " + params[0];
                        } else {
                            me._unregisterEventHandler(params[0]);
                            return "Unegistered " + params[0];
                        }
                    } else {
                        /*throw {
                            error: 'event_not_allowed',
                            message: 'Event not allowed: ' + params[0]
                        };*/
                        return [
                            "Event not allowed: " + params[0],
                            me._allowedEvents,
                            params[0],
                            me._allowedEvents[params[0]]
                        ];
                    }
                }
            );

            // Makes it possible to post requests
            // channel.call({method: 'postRequest', params: ['MapMoveRequest', [centerX, centerY, zoom, marker, srsName]]})
            // TODO OskariRPC.postRequest
            channel.bind(
                'postRequest',
                function (trans, params) {
                    if (!domainMatch(trans.origin)) {
                        throw {
                            error: 'invalid_origin',
                            message: 'Invalid origin: ' + trans.origin
                        };
                    }
                    if (me._allowedRequests[params[0]]) {
                        var builder = me.sandbox.getRequestBuilder(params[0]),
                            request;
                        if (builder) {
                            request = builder.apply(me, params[1]);
                            me.sandbox.request(me, request);
                        } else {
                            throw {
                                error: 'builder_not_found',
                                message: 'No builder found for: ' + params[0]
                            };
                        }
                    } else {
                        throw {
                            error: 'request_not_allowed',
                            message: 'Request not allowed: ' + params[0]
                        };
                    }
                }
            );

            // bind getSupportedEvents
            channel.bind(
                'getSupportedEvents',
                function (trans) {
                    if (!domainMatch(trans.origin)) {
                        throw {
                            error: 'invalid_origin',
                            message: 'Invalid origin: ' + trans.origin
                        };
                    }
                    return me._allowedEvents;
                }
            );
            // bind getSupportedRequests
            channel.bind(
                'getSupportedRequests',
                function (trans) {
                    if (!domainMatch(trans.origin)) {
                        throw {
                            error: 'invalid_origin',
                            message: 'Invalid origin: ' + trans.origin
                        };
                    }
                    return me._allowedRequests;
                }
            );
            // bind get map position
            // TODO OskariRPC.getMapPosition
            channel.bind(
                'getMapPosition',
                function (trans) {
                    var map = me.sandbox.getMap();
                    if (!domainMatch(trans.origin)) {
                        throw {
                            error: 'invalid_origin',
                            message: 'Invalid origin: ' + trans.origin
                        };
                    }
                    return {
                        centerX: map.getY(),
                        centerY: map.getX(),
                        zoom: map.getZoom(),
                        srsName: map.getSrsName()
                    };
                }
            );

            channel.bind(
                'testOriginCheck',
                function (trans) {
                    return {
                        domain: domain,
                        origin: trans.origin,
                        test: domainMatch(trans.origin)
                    };
                }
            );

            me._channel = channel;
        },

        /**
         * @private @method _registerEventHandler
         *
         * @param {string} eventName Event name
         *
         */
        _registerEventHandler: function (eventName) {
            var me = this;
            if (me.eventHandlers[eventName]) {
                // Event handler already in place
                return;
            }
            me.eventHandlers[eventName] = function (event) {
                if (me._channel) {
                    me._channel.notify({
                        method: eventName,
                        params: me._getParams(event)
                    });
                }
            };
            me.sandbox.registerForEventByName(me, eventName);
        },

        /**
         * @method stop
         * BundleInstance protocol method
         */
        stop: function () {
            var me = this,
                sandbox = this.sandbox,
                p;

            for (p in me.eventHandlers) {
                if (me.eventHandlers.hasOwnProperty(p)) {
                    sandbox.unregisterFromEventByName(me, p);
                }
            }
            for (p in me.requestHandlers) {
                if (me.requestHandlers.hasOwnProperty(p)) {
                    sandbox.removeRequestHandler(p, this);
                }
            }
            sandbox.unregister(this);
            this.sandbox = null;
        },

        init: function () {
            return null;
        },
        /**
         * @method onEvent
         * @param {Oskari.mapframework.event.Event} event a Oskari event object
         * Event is handled forwarded to correct #eventHandlers if found or discarded if not.
         */
        onEvent: function (event) {
            var me = this,
                handler = me.eventHandlers[event.getName()];
            if (!handler) {
                return;
            }

            return handler.apply(this, [event]);
        },
        /**
         * @private @method _getParams
         * Returns event's simple variables as params.
         * This should suffice for simple events.
         * TODO see if this could be done with some library...
         *
         * @param  {Object} event Event
         *
         * @return {Object}       Event params
         */
        _getParams: function (event) {
            var ret = {},
                key,
                //strippedKey,
                value;

            if (event.getParams) {
                ret = event.getParams();
            } else {
                for (key in event) {
                    if (event.hasOwnProperty(key)) {
                        // Skip __name and such
                        if (key.indexOf('__') !== 0) {
                            value = event[key];
                            if (typeof value === 'string' ||
                                typeof value === 'number' ||
                                typeof value === 'boolean') {
                                /* try to make the key a tad cleaner?
                                strippedKey = key;
                                if (key.indexOf('_') === 0) {
                                    strippedKey = key.substring(1);
                                    if (event[strippedKey] === undefined) {
                                        key = strippedKey;
                                    }
                                }*/
                                ret[key] = value;
                            }
                        }
                    }
                }
            }

            return ret;
        },

        /**
         * @method update
         * BundleInstance protocol method
         */
        update: function () {},

        /**
         * @private @method _unregisterEventHandler
         *
         * @param {string} eventName
         *
         */
        _unregisterEventHandler: function (eventName) {
            delete this.eventHandlers[eventName];
            this.sandbox.unregisterFromEventByName(this, eventName);
        }
    }, {
        /**
         * @static @property {String[]} protocol
         */
        'protocol': ['Oskari.bundle.BundleInstance', 'Oskari.mapframework.module.Module']
    }
);
<|endoftext|>