<commit_before>enyo.kind({
	name: "AppView",
	kind: "View",
	controllerKind: "AppController",
	components:[
		{name:"upperPanels", kind: "Panels", index:0, arrangerKind: "CollapsingArranger", realtimeFit: false, wrap: false, classes:"panels enyo-fit", draggable:false, onTransitionFinish:"controller.upperTransition", components:[
			{kind:"MenuView", classes:"menu-container"},
			{name:"lowerPanels", kind:"Panels", index:1, arrangerKind: "CollapsingRightArranger", wrap: false, realtimeFit: true, classes:"main-container enyo-border-box", draggable:true, onTransitionFinish:"controller.lowerTransition", components:[
				{layoutKind:"FittableRowsLayout", fit:true, components:[
					{kind:"GameView", classes:"game-container", fit:true},
					{kind:"ChatView", classes:"chat-container"},
					{kind:"onyx.Toolbar", style:"padding-top:4px; padding-bottom:4px;", components:[
						{kind:"onyx.IconButton", src:"assets/onyx-profile.png", ontap:"controller.toggleSocial", style:"float:right"},
						{kind:"onyx.IconButton", src:"assets/onyx-menu.png", ontap:"controller.toggleMenu"}

					]}
				]},
				{kind:"SocialView", classes:"social-container"}
			]}

		]}
	]
});
<commit_msg>Added simple names to the views for easier access via enyo.stage<commit_after>enyo.kind({
	name: "AppView",
	kind: "View",
	controllerKind: "AppController",
	components:[
		{name:"upperPanels", kind: "Panels", index:0, arrangerKind: "CollapsingArranger", realtimeFit: false, wrap: false, classes:"panels enyo-fit", draggable:false, onTransitionFinish:"controller.upperTransition", components:[
			{name:"menu", kind:"MenuView", classes:"menu-container"},
			{name:"lowerPanels", kind:"Panels", index:1, arrangerKind: "CollapsingRightArranger", wrap: false, realtimeFit: true, classes:"main-container enyo-border-box", draggable:true, onTransitionFinish:"controller.lowerTransition", components:[
				{layoutKind:"FittableRowsLayout", fit:true, components:[
					{name:"game", kind:"GameView", classes:"game-container", fit:true},
					{name:"chat", kind:"ChatView", classes:"chat-container"},
					{kind:"onyx.Toolbar", style:"padding-top:4px; padding-bottom:4px;", components:[
						{kind:"onyx.IconButton", src:"assets/onyx-profile.png", ontap:"controller.toggleSocial", style:"float:right"},
						{kind:"onyx.IconButton", src:"assets/onyx-menu.png", ontap:"controller.toggleMenu"}

					]}
				]},
				{name:"social", kind:"SocialView", classes:"social-container"}
			]}

		]}
	]
});
<|endoftext|>


<commit_before>/*
 * confirm-button directive
 * ------------------------
 *
 * Add the confirm-button attribute to a button to make a confirmation popover appear before
 * performing the specified action. Requires AngularUI and Bootstrap.
 *
 * Example usage:
 * <button type="button" confirm-button="delete($index)" message="Are you sure?"></button>
 *
 * In the above example, delete($index) will *not* immediately be called when clicking the button.
 * Instead, a confirmation popover will appear first with the message "Are you sure?", and the
 * buttons "Yes" and "No". Only if the user clicks "Yes" will delete($index) actually be called.
 *
 * Additional options configurable via attributes:
 *     - title="Confirm": Changes the title text on the popover
 *     - yes="Yep": Changes the text of the "Yes" button
 *     - no="Nope": Changes the text of the "No" button
 *     - classes="mypopover warning": CSS classes to apply to the popover (separated by space)
 *     - placement="bottom": Changes the popover placement
 *     - placement-callback="getPopoverPlacement()": A more flexible method for determining the
 *          placement of the popover. getPopoverPlacement should be a function that returns a
 *          function, which in turn returns a string (one of either "left", "top", "right", or
 *          "bottom"). This can be used to, for example, have the popover appear to the left
 *          on small screens, and to the right on big screens:
 *              $scope.popoverPlacementCallback = function () {
 *                  return function () {
 *                      return ($(window).width() > 1024) ? "right" : "left";
 *                  };
 *              };
 *
 * This was borrowed and slightly modified from here:
 * http://wegnerdesign.com/blog/angular-js-directive-tutorial-on-attribute-bootstrap-confirm-button/
 */
angular.module('swot').directive('confirmButton', function ($document, $parse) {
    return {
        restrict: 'A',
        scope: { placementCallback: '&placementCallback' },
        link: function (scope, element, attrs) {
            var buttonId = Math.floor(Math.random() * 10000000000),
                message = attrs.message || "Are you sure?",
                yep = attrs.yes || "Yes",
                nope = attrs.no || "No",
                title = attrs.title || "Confirm",
                classes = attrs.classes || "",
                placement = attrs.placement || "bottom";

            var html = "
" +
                            "
" + message + "
" +
                            "<button class=\"confirmbutton-yes btn btn-danger\">" + yep + "</button>" +
                            "<button class=\"confirmbutton-no btn\">" + nope + "</button>" +
                        "
";

            element.popover({
                content: html,
                html: true,
                trigger: "manual",
                title: title,
                placement: (angular.isDefined(attrs.placementCallback) ? scope.placementCallback() : placement)
            });

            element.bind('click', function(e) {
                var dontBubble = true;
                e.stopPropagation();

                element.popover('show');

                var pop = $("#button-" + buttonId);

                pop.closest(".popover").click(function(e) {
                    if (dontBubble) {
                        e.stopPropagation();
                    }
                });

                pop.find('.confirmbutton-yes').click(function(e) {
                    dontBubble = false;
                    var func = $parse(attrs.confirmButton);
                    scope.$apply(function () {
                        func(scope);
                    });
                });

                pop.find('.confirmbutton-no').click(function(e) {
                    dontBubble = false;
                    $document.off('click.confirmbutton.' + buttonId);
                    element.popover('hide');
                });

                $document.on('click.confirmbutton.' + buttonId, ":not(.popover, .popover *)", function() {
                    $document.off('click.confirmbutton.' + buttonId);
                    element.popover('hide');
                });
            });
        }
    };
});
<commit_msg>Fix question deletion<commit_after>/*
 * confirm-button directive
 * ------------------------
 *
 * Add the confirm-button attribute to a button to make a confirmation popover appear before
 * performing the specified action. Requires AngularUI and Bootstrap.
 *
 * Example usage:
 * <button type="button" confirm-button="delete($index)" message="Are you sure?"></button>
 *
 * In the above example, delete($index) will *not* immediately be called when clicking the button.
 * Instead, a confirmation popover will appear first with the message "Are you sure?", and the
 * buttons "Yes" and "No". Only if the user clicks "Yes" will delete($index) actually be called.
 *
 * Additional options configurable via attributes:
 *     - title="Confirm": Changes the title text on the popover
 *     - yes="Yep": Changes the text of the "Yes" button
 *     - no="Nope": Changes the text of the "No" button
 *     - classes="mypopover warning": CSS classes to apply to the popover (separated by space)
 *     - placement="bottom": Changes the popover placement
 *     - placement-callback="getPopoverPlacement()": A more flexible method for determining the
 *          placement of the popover. getPopoverPlacement should be a function that returns a
 *          function, which in turn returns a string (one of either "left", "top", "right", or
 *          "bottom"). This can be used to, for example, have the popover appear to the left
 *          on small screens, and to the right on big screens:
 *              $scope.popoverPlacementCallback = function () {
 *                  return function () {
 *                      return ($(window).width() > 1024) ? "right" : "left";
 *                  };
 *              };
 *
 * This was borrowed and slightly modified from here:
 * http://wegnerdesign.com/blog/angular-js-directive-tutorial-on-attribute-bootstrap-confirm-button/
 */
angular.module('swot').directive('confirmButton', function ($document, $parse) {
    return {
        restrict: 'A',
        scope: {
            confirmAction: '&confirmButton',
            placementCallback: '&'
        },
        link: function (scope, element, attrs) {
            var buttonId = Math.floor(Math.random() * 10000000000),
                message = attrs.message || "Are you sure?",
                yep = attrs.yes || "Yes",
                nope = attrs.no || "No",
                title = attrs.title || "Confirm",
                classes = attrs.classes || "",
                placement = attrs.placement || "bottom";

            attrs.buttonId = buttonId;

            var html = "
" +
                            "
" + message + "
" +
                            "<button class=\"confirmbutton-yes btn btn-danger\">" + yep + "</button>" +
                            "<button class=\"confirmbutton-no btn\">" + nope + "</button>" +
                        "
";

            element.popover({
                content: html,
                html: true,
                trigger: "manual",
                title: title,
                placement: (angular.isDefined(attrs.placementCallback) ? scope.placementCallback() : placement)
            });

            element.bind('click', function(e) {
                var dontBubble = true;
                e.stopPropagation();

                element.popover('show');

                var pop = $("#button-" + buttonId);

                pop.closest(".popover").click(function(e) {
                    if (dontBubble) {
                        e.stopPropagation();
                    }
                });

                pop.find('.confirmbutton-yes').click(function(e) {
                    dontBubble = false;
                    scope.$apply(scope.confirmAction);
                });

                pop.find('.confirmbutton-no').click(function(e) {
                    dontBubble = false;
                    $document.off('click.confirmbutton.' + buttonId);
                    element.popover('hide');
                });

                $document.on('click.confirmbutton.' + buttonId, ":not(.popover, .popover *)", function() {
                    $document.off('click.confirmbutton.' + buttonId);
                    element.popover('hide');
                });
            });
        }
    };
});
<|endoftext|>


<commit_before>'use strict';
var turf = require('turf');
var _ = require('underscore');
var rbush = require('rbush');
var flatten = require('geojson-flatten');

module.exports = function(tileLayers, tile, writeData, done) {
  var layer = tileLayers.osm.osm;
  var highways = {};
  var bboxes = [];
  var bboxLayer = turf.bboxPolygon(turf.extent(layer));
  bboxLayer.geometry.type = 'LineString';
  bboxLayer.geometry.coordinates = bboxLayer.geometry.coordinates[0];
  var bufferLayer = turf.buffer(bboxLayer, 0.01, 'miles').features[0];
  var majorRoads = {
    'motorway': true,
    'trunk': true,
    'primary': true,
    'secondary': true,
    'tertiary': true,
    'motorway_link': true,
    'trunk_link': true,
    'primary_link': true,
    'secondary_link': true,
    'tertiary_link': true
  };
  var minorRoads = {
    'unclassified': true,
    'residential': true,
    'living_street': true,
    'service': true,
    'road': true
  };
  var pathRoads = {
    'pedestrian': true,
    'track': true,
    'footway': true,
    'path': true,
    'cycleway': true,
    'steps': true
  };
  var preserveType = {};
  preserveType = _.extend(preserveType, majorRoads);
  preserveType = _.extend(preserveType, minorRoads);
  // preserveType = _.extend(preserveType, pathRoads);
  var osmlint = 'impossibleoneways';
  for (var i = 0; i < layer.features.length; i++) {
    var val = layer.features[i];
    var id = val.properties._osm_way_id;
    //Value LineString highways
    if (val.geometry.type === 'Polygon' && val.properties.highway) {
      val.geometry.coordinates = val.geometry.coordinates[0];
      val.geometry.type = 'LineString';
    }
    if (val.geometry.type === 'LineString' && val.properties.highway) {
      var coordsWayL = val.geometry.coordinates;
      var isClippedL = false;
      if (turf.inside(turf.point(coordsWayL[0]), bufferLayer) || turf.inside(turf.point(coordsWayL[coordsWayL.length - 1]), bufferLayer)) {
        isClippedL = true;
      }
      var idWayL = id + 'L';
      for (var j = 0; j < coordsWayL.length; j++) {
        var positionL;
        if (j === 0) {
          positionL = 'first';
        } else if (j === (coordsWayL.length - 1)) {
          positionL = 'end';
        } else {
          positionL = 'midle';
        }
        var propsL = {
          id: idWayL,
          position: positionL,
          isClipped: isClippedL
        };
        var itemL = coordsWayL[j].reverse().concat(coordsWayL[j].reverse());
        itemL.push(propsL);
        bboxes.push(itemL);
      }
      highways[idWayL] = val;
    } else if (val.geometry.type === 'MultiLineString' && val.properties.highway) { //MultiLineString evaluation
      var arrayWays = flatten(val);
      for (var f = 0; f < arrayWays.length; f++) {
        if (arrayWays[f].geometry.type === 'LineString') {
          var coordsWayM = arrayWays[f].geometry.coordinates;
          var isClippedM = false;
          if (turf.inside(turf.point(coordsWayM[0]), bufferLayer) || turf.inside(turf.point(coordsWayM[coordsWayM.length - 1]), bufferLayer)) {
            isClippedM = true;
          }
          var idWayM = id + 'M' + f;
          for (var t = 0; t < coordsWayM.length; t++) {
            var positionM;
            if (t === 0) {
              positionM = 'first';
            } else if (t === (coordsWayM.length - 1)) {
              positionM = 'end';
            } else {
              positionM = 'midle';
            }
            var propsM = {
              id: idWayM,
              position: positionM,
              isClipped: isClippedM
            };
            var itemM = coordsWayM[t].reverse().concat(coordsWayM[t].reverse());
            itemM.push(propsM);
            bboxes.push(itemM);
            highways[idWayM] = arrayWays[f];
          }
        }
      }
    }
  }

  var highwaysTree = rbush(bboxes.length);
  highwaysTree.load(bboxes);
  var features = {};
  for (var key in highways) {
    var valueHighway = highways[key];
    var firstCoor = valueHighway.geometry.coordinates[0];
    var endCoor = valueHighway.geometry.coordinates[valueHighway.geometry.coordinates.length - 1];
    var access;
    (valueHighway.properties.access && valueHighway.properties.access !== 'no') ? access = false: access = true;
    if (valueHighway.properties.oneway && valueHighway.properties.oneway !== 'no' && preserveType[valueHighway.properties.highway] && _.intersection(firstCoor, endCoor).length !== 2 && access) {
      // evaluate the first node of road
      var overlapsFirstcoor = highwaysTree.search(firstCoor.reverse().concat(firstCoor.reverse()));
      if (overlapsFirstcoor.length === 1 && !overlapsFirstcoor[0][4].isClipped) {
        // valueHighway.properties._osmlint = osmlint;
        // features[valueHighway.properties._osm_way_id] = valueHighway;
        // var firstPointNoExit = turf.point(firstCoor);
        // firstPointNoExit.properties = {
        //   _fromWay: valueHighway.properties._osm_way_id,
        //   _osmlint: osmlint,
        //   _type: classification(majorRoads, minorRoads, pathRoads, valueHighway.properties.highway)
        // };
        // features[firstCoor.join('-')] = firstPointNoExit;
      } else {
        var isExitFirst = false;
        var flagFirst = [];
        for (var u = 0; u < overlapsFirstcoor.length; u++) {
          var connectRoad = highways[overlapsFirstcoor[u][4].id];
          flagFirst.push(connection(overlapsFirstcoor[u][4].position, connectRoad.properties.oneway));
          if ((valueHighway.properties._osm_way_id === connectRoad.properties._osm_way_id && overlapsFirstcoor[u][4].isClipped) || (overlapsFirstcoor[u][4].position === 'midle' || connectRoad.properties.oneway === 'no' || typeof connectRoad.properties.oneway === 'undefined')) {
            isExitFirst = true;
          }
        }
        var connectionFirst = _.uniq(flagFirst);
        if (!isExitFirst && (connectionFirst[0] === 'output' || connectionFirst[0] === 'input') && connectionFirst.length === 1) {
          valueHighway.properties._osmlint = osmlint;
          features[valueHighway.properties._osm_way_id] = valueHighway;
          var firstPointNoConnection = turf.point(firstCoor);
          firstPointNoConnection.properties = {
            _fromWay: valueHighway.properties._osm_way_id,
            _osmlint: osmlint,
            _type: classification(majorRoads, minorRoads, pathRoads, valueHighway.properties.highway)
          };
          features[firstCoor.join('-')] = firstPointNoConnection;
        }
      }
      // evaluate the end node of road
      var overlapsEndcoor = highwaysTree.search(endCoor.reverse().concat(endCoor.reverse()));
      if (overlapsEndcoor.length === 1 && !overlapsEndcoor[0][4].isClipped) {
        valueHighway.properties._osmlint = osmlint;
        features[valueHighway.properties._osm_way_id] = valueHighway;
        var endPointNoExit = turf.point(endCoor);
        endPointNoExit.properties = {
          _fromWay: valueHighway.properties._osm_way_id,
          _osmlint: osmlint,
          _type: classification(majorRoads, minorRoads, pathRoads, valueHighway.properties.highway)
        };
        features[endCoor.join('-')] = endPointNoExit;
      } else {
        var isExitEnd = false;
        var flagEnd = [];
        for (var m = 0; m < overlapsEndcoor.length; m++) {
          var connectRoadEnd = highways[overlapsEndcoor[m][4].id];
          flagEnd.push(connection(overlapsEndcoor[m][4].position, connectRoadEnd.properties.oneway));
          if ((valueHighway.properties._osm_way_id === connectRoadEnd.properties._osm_way_id && overlapsEndcoor[m][4].isClipped) || (overlapsEndcoor[m][4].position === 'midle' || connectRoadEnd.properties.oneway === 'no' || typeof connectRoadEnd.properties.oneway === 'undefined')) {
            isExitEnd = true;
          }
        }
        var connectionEnd = _.uniq(flagEnd);
        if (!isExitEnd && (connectionEnd[0] === 'output' || connectionEnd[0] === 'input') && connectionEnd.length === 1) {
          valueHighway.properties._osmlint = osmlint;
          features[valueHighway.properties._osm_way_id] = valueHighway;
          var endPointNoConnection = turf.point(endCoor);
          endPointNoConnection.properties = {
            _fromWay: valueHighway.properties._osm_way_id,
            _osmlint: osmlint,
            _type: classification(majorRoads, minorRoads, pathRoads, valueHighway.properties.highway)
          };
          features[endCoor.join('-')] = endPointNoConnection;
        }
      }
    }
  }

  var result = _.values(features);
  if (result.length > 0) {
    var fc = turf.featurecollection(result);
    writeData(JSON.stringify(fc) + '\n');
  }

  done(null, null);

};

function connection(position, oneway) {
  if (position === 'first' && oneway === -1) {
    return 'input';
  } else if (position === 'first' && (oneway === 'yes' || oneway === 1)) {
    return 'output';
  } else if (position === 'end' && (oneway === 'yes' || oneway === 1)) {
    return 'input';
  } else if (position === 'end' && oneway === -1) {
    return 'output';
  } else {
    return 'connection';
  }
}

function classification(major, minor, path, highway) {
  if (major[highway]) {
    return 'major';
  } else if (minor[highway]) {
    return 'minor';
  } else if (path[highway]) {
    return 'path';
  }
}<commit_msg>avoid links roads which has access=no<commit_after>'use strict';
var turf = require('turf');
var _ = require('underscore');
var rbush = require('rbush');
var flatten = require('geojson-flatten');

module.exports = function(tileLayers, tile, writeData, done) {
  var layer = tileLayers.osm.osm;
  var highways = {};
  var bboxes = [];
  var bboxLayer = turf.bboxPolygon(turf.extent(layer));
  bboxLayer.geometry.type = 'LineString';
  bboxLayer.geometry.coordinates = bboxLayer.geometry.coordinates[0];
  var bufferLayer = turf.buffer(bboxLayer, 0.01, 'miles').features[0];
  var majorRoads = {
    'motorway': true,
    'trunk': true,
    'primary': true,
    'secondary': true,
    'tertiary': true,
    'motorway_link': true,
    'trunk_link': true,
    'primary_link': true,
    'secondary_link': true,
    'tertiary_link': true
  };
  var minorRoads = {
    'unclassified': true,
    'residential': true,
    'living_street': true,
    'service': true,
    'road': true
  };
  var pathRoads = {
    'pedestrian': true,
    'track': true,
    'footway': true,
    'path': true,
    'cycleway': true,
    'steps': true
  };
  var noaccess = {
    'motorway_link': true,
    'trunk_link': true,
    'primary_link': true,
    'secondary_link': true,
    'tertiary_link': true
  };
  var preserveType = {};
  preserveType = _.extend(preserveType, majorRoads);
  preserveType = _.extend(preserveType, minorRoads);
  // preserveType = _.extend(preserveType, pathRoads);
  var osmlint = 'impossibleoneways';
  for (var i = 0; i < layer.features.length; i++) {
    var val = layer.features[i];
    var id = val.properties._osm_way_id;
    //Value LineString highways
    if (val.geometry.type === 'Polygon' && val.properties.highway) {
      val.geometry.coordinates = val.geometry.coordinates[0];
      val.geometry.type = 'LineString';
    }
    if (val.geometry.type === 'LineString' && val.properties.highway) {
      var coordsWayL = val.geometry.coordinates;
      var isClippedL = false;
      if (turf.inside(turf.point(coordsWayL[0]), bufferLayer) || turf.inside(turf.point(coordsWayL[coordsWayL.length - 1]), bufferLayer)) {
        isClippedL = true;
      }
      var idWayL = id + 'L';
      for (var j = 0; j < coordsWayL.length; j++) {
        var positionL;
        if (j === 0) {
          positionL = 'first';
        } else if (j === (coordsWayL.length - 1)) {
          positionL = 'end';
        } else {
          positionL = 'midle';
        }
        var propsL = {
          id: idWayL,
          position: positionL,
          isClipped: isClippedL
        };
        var itemL = coordsWayL[j].reverse().concat(coordsWayL[j].reverse());
        itemL.push(propsL);
        bboxes.push(itemL);
      }
      highways[idWayL] = val;
    } else if (val.geometry.type === 'MultiLineString' && val.properties.highway) { //MultiLineString evaluation
      var arrayWays = flatten(val);
      for (var f = 0; f < arrayWays.length; f++) {
        if (arrayWays[f].geometry.type === 'LineString') {
          var coordsWayM = arrayWays[f].geometry.coordinates;
          var isClippedM = false;
          if (turf.inside(turf.point(coordsWayM[0]), bufferLayer) || turf.inside(turf.point(coordsWayM[coordsWayM.length - 1]), bufferLayer)) {
            isClippedM = true;
          }
          var idWayM = id + 'M' + f;
          for (var t = 0; t < coordsWayM.length; t++) {
            var positionM;
            if (t === 0) {
              positionM = 'first';
            } else if (t === (coordsWayM.length - 1)) {
              positionM = 'end';
            } else {
              positionM = 'midle';
            }
            var propsM = {
              id: idWayM,
              position: positionM,
              isClipped: isClippedM
            };
            var itemM = coordsWayM[t].reverse().concat(coordsWayM[t].reverse());
            itemM.push(propsM);
            bboxes.push(itemM);
            highways[idWayM] = arrayWays[f];
          }
        }
      }
    }
  }

  var highwaysTree = rbush(bboxes.length);
  highwaysTree.load(bboxes);
  var features = {};
  for (var key in highways) {
    var valueHighway = highways[key];
    var firstCoor = valueHighway.geometry.coordinates[0];
    var endCoor = valueHighway.geometry.coordinates[valueHighway.geometry.coordinates.length - 1];
    if (valueHighway.properties.oneway && valueHighway.properties.oneway !== 'no' && preserveType[valueHighway.properties.highway] && _.intersection(firstCoor, endCoor).length !== 2 && !(valueHighway.properties.access && valueHighway.properties.access === 'no' && noaccess[valueHighway.properties.highway])) {
      // evaluate the first node of road
      var overlapsFirstcoor = highwaysTree.search(firstCoor.reverse().concat(firstCoor.reverse()));
      if (overlapsFirstcoor.length === 1 && !overlapsFirstcoor[0][4].isClipped) {
        // valueHighway.properties._osmlint = osmlint;
        // features[valueHighway.properties._osm_way_id] = valueHighway;
        // var firstPointNoExit = turf.point(firstCoor);
        // firstPointNoExit.properties = {
        //   _fromWay: valueHighway.properties._osm_way_id,
        //   _osmlint: osmlint,
        //   _type: classification(majorRoads, minorRoads, pathRoads, valueHighway.properties.highway)
        // };
        // features[firstCoor.join('-')] = firstPointNoExit;
      } else {
        var isExitFirst = false;
        var flagFirst = [];
        for (var u = 0; u < overlapsFirstcoor.length; u++) {
          var connectRoad = highways[overlapsFirstcoor[u][4].id];
          flagFirst.push(connection(overlapsFirstcoor[u][4].position, connectRoad.properties.oneway));
          if ((valueHighway.properties._osm_way_id === connectRoad.properties._osm_way_id && overlapsFirstcoor[u][4].isClipped) || (overlapsFirstcoor[u][4].position === 'midle' || connectRoad.properties.oneway === 'no' || typeof connectRoad.properties.oneway === 'undefined')) {
            isExitFirst = true;
          }
        }
        var connectionFirst = _.uniq(flagFirst);
        if (!isExitFirst && (connectionFirst[0] === 'output' || connectionFirst[0] === 'input') && connectionFirst.length === 1) {
          valueHighway.properties._osmlint = osmlint;
          features[valueHighway.properties._osm_way_id] = valueHighway;
          var firstPointNoConnection = turf.point(firstCoor);
          firstPointNoConnection.properties = {
            _fromWay: valueHighway.properties._osm_way_id,
            _osmlint: osmlint,
            _type: classification(majorRoads, minorRoads, pathRoads, valueHighway.properties.highway)
          };
          features[firstCoor.join('-')] = firstPointNoConnection;
        }
      }
      // evaluate the end node of road
      var overlapsEndcoor = highwaysTree.search(endCoor.reverse().concat(endCoor.reverse()));
      if (overlapsEndcoor.length === 1 && !overlapsEndcoor[0][4].isClipped) {
        valueHighway.properties._osmlint = osmlint;
        features[valueHighway.properties._osm_way_id] = valueHighway;
        var endPointNoExit = turf.point(endCoor);
        endPointNoExit.properties = {
          _fromWay: valueHighway.properties._osm_way_id,
          _osmlint: osmlint,
          _type: classification(majorRoads, minorRoads, pathRoads, valueHighway.properties.highway)
        };
        features[endCoor.join('-')] = endPointNoExit;
      } else {
        var isExitEnd = false;
        var flagEnd = [];
        for (var m = 0; m < overlapsEndcoor.length; m++) {
          var connectRoadEnd = highways[overlapsEndcoor[m][4].id];
          flagEnd.push(connection(overlapsEndcoor[m][4].position, connectRoadEnd.properties.oneway));
          if ((valueHighway.properties._osm_way_id === connectRoadEnd.properties._osm_way_id && overlapsEndcoor[m][4].isClipped) || (overlapsEndcoor[m][4].position === 'midle' || connectRoadEnd.properties.oneway === 'no' || typeof connectRoadEnd.properties.oneway === 'undefined')) {
            isExitEnd = true;
          }
        }
        var connectionEnd = _.uniq(flagEnd);
        if (!isExitEnd && (connectionEnd[0] === 'output' || connectionEnd[0] === 'input') && connectionEnd.length === 1) {
          valueHighway.properties._osmlint = osmlint;
          features[valueHighway.properties._osm_way_id] = valueHighway;
          var endPointNoConnection = turf.point(endCoor);
          endPointNoConnection.properties = {
            _fromWay: valueHighway.properties._osm_way_id,
            _osmlint: osmlint,
            _type: classification(majorRoads, minorRoads, pathRoads, valueHighway.properties.highway)
          };
          features[endCoor.join('-')] = endPointNoConnection;
        }
      }
    }
  }

  var result = _.values(features);
  if (result.length > 0) {
    var fc = turf.featurecollection(result);
    writeData(JSON.stringify(fc) + '\n');
  }

  done(null, null);

};

function connection(position, oneway) {
  if (position === 'first' && oneway === -1) {
    return 'input';
  } else if (position === 'first' && (oneway === 'yes' || oneway === 1)) {
    return 'output';
  } else if (position === 'end' && (oneway === 'yes' || oneway === 1)) {
    return 'input';
  } else if (position === 'end' && oneway === -1) {
    return 'output';
  } else {
    return 'connection';
  }
}

function classification(major, minor, path, highway) {
  if (major[highway]) {
    return 'major';
  } else if (minor[highway]) {
    return 'minor';
  } else if (path[highway]) {
    return 'path';
  }
}<|endoftext|>


<commit_before>/**
 * @author      Created by Marcus Spiegel <marcus.spiegel@gmail.com> on 2011-03-25.
 * @link        https://github.com/mashpie/i18n-node
 * @license     http://opensource.org/licenses/MIT
 *
 * @version     0.4.0
 */

// dependencies and "private" vars
var vsprintf = require('sprintf').vsprintf,
    fs = require('fs'),
    url = require('url'),
    path = require('path'),
    debug = require('debug')('i18n:debug'),
    warn = require('debug')('i18n:warn'),
    error = require('debug')('i18n:error'),
    locales = {},
    api = ['__', '__n', 'getLocale', 'setLocale', 'getCatalog'],
    pathsep = path.sep || '/', // ---> means win support will be available in node 0.8.x and above
    defaultLocale, updateFiles, cookiename, extension, directory;

// public exports
var i18n = exports;

i18n.version = '0.4.0';

i18n.configure = function i18nConfigure(opt) {

  // you may register helpers in global scope, up to you
  if (typeof opt.register === 'object') {
    applyAPItoObject(opt.register);
  }

  // sets a custom cookie name to parse locale settings from
  cookiename = (typeof opt.cookie === 'string') ? opt.cookie : null;

  // where to store json files
  directory = (typeof opt.directory === 'string') ? opt.directory : __dirname + pathsep + 'locales';

  // write new locale information to disk
  updateFiles = (typeof opt.updateFiles === 'boolean') ? opt.updateFiles : true;

  // where to store json files
  extension = (typeof opt.extension === 'string') ? opt.extension : '.json';

  // setting defaultLocale
  defaultLocale = (typeof opt.defaultLocale === 'string') ? opt.defaultLocale : 'en';

  // implicitly read all locales
  if (typeof opt.locales === 'object') {
    opt.locales.forEach(function (l) {
      read(l);
    });
  }
};

i18n.init = function i18nInit(request, response, next) {
  if (typeof request === 'object') {
    guessLanguage(request);

    if (typeof response === 'object') {
      applyAPItoObject(request, response);

      // register locale to res.locals so hbs helpers know this.locale
      if (!response.locale) response.locale = request.locale;

      if (response.locals) {
        applyAPItoObject(request, response.locals);

        // register locale to res.locals so hbs helpers know this.locale
        if (!response.locals.locale) response.locals.locale = request.locale;
      }
    }
  }

  if (typeof next === 'function') {
    next();
  }
};

i18n.__ = function i18nTranslate(phrase) {
  // get translated message with locale from scope (deprecated) or object
  var msg = translate(getLocaleFromObject(this), phrase);

  // if we have extra arguments with strings to get replaced,
  // an additional substition injects those strings afterwards
  if (arguments.length > 1) {
    msg = vsprintf(msg, Array.prototype.slice.call(arguments, 1));
  }
  return msg;
};

i18n.__n = function i18nTranslatePlural(singular, plural, count) {
  // get translated message with locale from scope (deprecated) or object
  var msg = translate(getLocaleFromObject(this), singular, plural);

  // parse translation and replace all digets '%d' by `count`
  // this also replaces extra strings '%%s' to parseble '%s' for next step
  // simplest 2 form implementation of plural, like https://developer.mozilla.org/en/docs/Localization_and_Plurals#Plural_rule_.231_.282_forms.29
  if (parseInt(count, 10) > 1) {
    msg = vsprintf(msg.other, [count]);
  } else {
    msg = vsprintf(msg.one, [count]);
  }

  // if we have extra arguments with strings to get replaced,
  // an additional substition injects those strings afterwards
  if (arguments.length > 3) {
    msg = vsprintf(msg, Array.prototype.slice.call(arguments, 3));
  }

  return msg;
};

i18n.setLocale = function i18nSetLocale(locale_or_request, locale) {
  var target_locale = locale_or_request,
      request;

  // called like setLocale(req, 'en')
  if (locale_or_request && typeof locale === 'string' && locales[locale]) {
    request = locale_or_request;
    target_locale = locale;
  }

  // called like req.setLocale('en')
  if (locale === undefined && typeof this.locale === 'string' && typeof locale_or_request === 'string') {
    request = this;
    target_locale = locale_or_request;
  }

  if (locales[target_locale]) {

    // called like setLocale('en')
    if (request === undefined) {
      defaultLocale = target_locale;
    }
    else {
      request.locale = target_locale;
    }
  }
  return i18n.getLocale(request);
};

i18n.getLocale = function i18nGetLocale(request) {

  // called like getLocale(req)
  if (request && request.locale) {
    return request.locale;
  }

  // called like req.getLocale()
  if (request === undefined && typeof this.locale === 'string') {
    return this.locale;
  }

  // called like getLocale()
  return defaultLocale;
};

i18n.getCatalog = function i18nGetCatalog(locale_or_request, locale) {
  var target_locale = locale_or_request;

  // called like getCatalog(req)
  if (typeof locale_or_request === 'object' && typeof locale_or_request.locale === 'string') {
    target_locale = locale_or_request.locale;
  }

  // called like getCatalog(req, 'en')
  if (typeof locale_or_request === 'object' && typeof locale === 'string') {
    target_locale = locale;
  }

  // called like req.getCatalog()
  if (locale === undefined && typeof this.locale === 'string') {
    target_locale = this.locale;
  }

  // called like req.getCatalog('en')
  if (locale === undefined && typeof locale_or_request === 'string') {
    target_locale = locale_or_request;
  }

  // called like getCatalog()
  if (target_locale === undefined || target_locale === '') {
    return locales;
  }

  if (locales[target_locale]) {
    return locales[target_locale];
  } else {
    logWarn('No catalog found for "' + target_locale + '"');
    return false;
  }
};

i18n.overrideLocaleFromQuery = function (req) {
  if (req === null) {
    return;
  }
  var urlObj = url.parse(req.url, true);
  if (urlObj.query.locale) {
    logDebug("Overriding locale from query: " + urlObj.query.locale);
    i18n.setLocale(req, urlObj.query.locale.toLowerCase());
  }
};

// ===================
// = private methods =
// ===================
/**
 * registers all public API methods to a given response object when not already declared
 */

function applyAPItoObject(request, response) {

  // attach to itself if not provided
  var object = response || request;
  api.forEach(function (method) {

    // be kind rewind, or better not touch anything already exiting
    if (!object[method]) {
      object[method] = function () {
        return i18n[method].apply(request, arguments);
      };
    }
  });
}

/**
 * guess language setting based on http headers
 */

function guessLanguage(request) {
  if (typeof request === 'object') {
    var language_header = request.headers['accept-language'],
        languages = [],
        regions = [];

    request.languages = [defaultLocale];
    request.regions = [defaultLocale];
    request.language = defaultLocale;
    request.region = defaultLocale;

    if (language_header) {
      language_header.split(',').forEach(function (l) {
        var header = l.split(';', 1)[0],
            lr = header.split('-', 2);
        if (lr[0]) {
          languages.push(lr[0].toLowerCase());
        }
        if (lr[1]) {
          regions.push(lr[1].toLowerCase());
        }
      });

      if (languages.length > 0) {
        request.languages = languages;
        request.language = languages[0];
      }

      if (regions.length > 0) {
        request.regions = regions;
        request.region = regions[0];
      }
    }

    // setting the language by cookie
    if (cookiename && request.cookies && request.cookies[cookiename]) {
      request.language = request.cookies[cookiename];
    }

    i18n.setLocale(request, request.language);
  }
}

/**
 * searches for locale in given object
 */

function getLocaleFromObject(obj) {
  var locale;
  if (obj && obj.scope) {
    locale = obj.scope.locale;
  }
  if (obj && obj.locale) {
    locale = obj.locale;
  }
  return locale;
}

/**
 * read locale file, translate a msg and write to fs if new
 */

function translate(locale, singular, plural) {
  if (locale === undefined) {
    logWarn("WARN: No locale found - check the context of the call to __(). Using " + defaultLocale + " as current locale");
    locale = defaultLocale;
  }

  // attempt to read when defined as valid locale
  if (!locales[locale]) {
    read(locale);
  }

  // fallback to default when missed
  if (!locales[locale]) {
    logWarn("WARN: Locale " + locale + " couldn't be read - check the context of the call to $__. Using " + defaultLocale + " (default) as current locale");
    locale = defaultLocale;
    read(locale);
  }

  if (plural) {
    if (!locales[locale][singular]) {
      locales[locale][singular] = {
        'one': singular,
        'other': plural
      };
      write(locale);
    }
  }

  if (!locales[locale][singular]) {
    locales[locale][singular] = singular;
    write(locale);
  }
  return locales[locale][singular];
}

/**
 * try reading a file
 */

function read(locale) {
  var localeFile = {},
      file = getStorageFilePath(locale);
  try {
    logDebug('read ' + file + ' for locale: ' + locale);
    localeFile = fs.readFileSync(file);
    try {
      // parsing filecontents to locales[locale]
      locales[locale] = JSON.parse(localeFile);
    } catch (parseError) {
      logError('unable to parse locales from file (maybe ' + file + ' is empty or invalid json?): ', e);
    }
  } catch (readError) {
    // unable to read, so intialize that file
    // locales[locale] are already set in memory, so no extra read required
    // or locales[locale] are empty, which initializes an empty locale.json file
    logDebug('initializing ' + file);
    write(locale);
  }
}

/**
 * try writing a file in a created directory
 */

function write(locale) {
  var stats, target, tmp;

  // don't write new locale information to disk if updateFiles isn't true
  if (!updateFiles) {
    return;
  }

  // creating directory if necessary
  try {
    stats = fs.lstatSync(directory);
  } catch (e) {
    logDebug('creating locales dir in: ' + directory);
    fs.mkdirSync(directory, parseInt('755', 8));
  }

  // first time init has an empty file
  if (!locales[locale]) {
    locales[locale] = {};
  }

  // writing to tmp and rename on success
  try {
    target = getStorageFilePath(locale);
    tmp = target + ".tmp";
    fs.writeFileSync(tmp, JSON.stringify(locales[locale], null, "\t"), "utf8");
    stats = fs.statSync(tmp);
    if (stats.isFile()) {
      fs.renameSync(tmp, target);
    } else {
      logError('unable to write locales to file (either ' + tmp + ' or ' + target + ' are not writeable?): ', e);
    }
  } catch (e) {
    logError('unexpected error writing files (either ' + tmp + ' or ' + target + ' are not writeable?): ', e);
  }
}

/**
 * basic normalization of filepath
 */

function getStorageFilePath(locale) {
  // changed API to use .json as default, #16
  var ext = extension || '.json',
      filepath = path.normalize(directory + pathsep + locale + ext),
      filepathJS = path.normalize(directory + pathsep + locale + '.js');
  // use .js as fallback if already existing
  try {
    if (fs.statSync(filepathJS)) {
      logDebug('using existing file ' + filepathJS);
      extension = '.js';
      return filepathJS;
    }
  } catch (e) {
    logDebug('will write to ' + filepath);
  }
  return filepath;
}

/**
 * Logging proxies
 */

function logDebug(msg) {
  debug(msg);
}

function logWarn(msg) {
  warn(msg);
}

function logError(msg) {
  error(msg);
}
<commit_msg>Removed hard coded mod 755 for the `locales` mkdir call.<commit_after>/**
 * @author      Created by Marcus Spiegel <marcus.spiegel@gmail.com> on 2011-03-25.
 * @link        https://github.com/mashpie/i18n-node
 * @license     http://opensource.org/licenses/MIT
 *
 * @version     0.4.0
 */

// dependencies and "private" vars
var vsprintf = require('sprintf').vsprintf,
    fs = require('fs'),
    url = require('url'),
    path = require('path'),
    debug = require('debug')('i18n:debug'),
    warn = require('debug')('i18n:warn'),
    error = require('debug')('i18n:error'),
    locales = {},
    api = ['__', '__n', 'getLocale', 'setLocale', 'getCatalog'],
    pathsep = path.sep || '/', // ---> means win support will be available in node 0.8.x and above
    defaultLocale, updateFiles, cookiename, extension, directory;

// public exports
var i18n = exports;

i18n.version = '0.4.0';

i18n.configure = function i18nConfigure(opt) {

  // you may register helpers in global scope, up to you
  if (typeof opt.register === 'object') {
    applyAPItoObject(opt.register);
  }

  // sets a custom cookie name to parse locale settings from
  cookiename = (typeof opt.cookie === 'string') ? opt.cookie : null;

  // where to store json files
  directory = (typeof opt.directory === 'string') ? opt.directory : __dirname + pathsep + 'locales';

  // write new locale information to disk
  updateFiles = (typeof opt.updateFiles === 'boolean') ? opt.updateFiles : true;

  // where to store json files
  extension = (typeof opt.extension === 'string') ? opt.extension : '.json';

  // setting defaultLocale
  defaultLocale = (typeof opt.defaultLocale === 'string') ? opt.defaultLocale : 'en';

  // implicitly read all locales
  if (typeof opt.locales === 'object') {
    opt.locales.forEach(function (l) {
      read(l);
    });
  }
};

i18n.init = function i18nInit(request, response, next) {
  if (typeof request === 'object') {
    guessLanguage(request);

    if (typeof response === 'object') {
      applyAPItoObject(request, response);

      // register locale to res.locals so hbs helpers know this.locale
      if (!response.locale) response.locale = request.locale;

      if (response.locals) {
        applyAPItoObject(request, response.locals);

        // register locale to res.locals so hbs helpers know this.locale
        if (!response.locals.locale) response.locals.locale = request.locale;
      }
    }
  }

  if (typeof next === 'function') {
    next();
  }
};

i18n.__ = function i18nTranslate(phrase) {
  // get translated message with locale from scope (deprecated) or object
  var msg = translate(getLocaleFromObject(this), phrase);

  // if we have extra arguments with strings to get replaced,
  // an additional substition injects those strings afterwards
  if (arguments.length > 1) {
    msg = vsprintf(msg, Array.prototype.slice.call(arguments, 1));
  }
  return msg;
};

i18n.__n = function i18nTranslatePlural(singular, plural, count) {
  // get translated message with locale from scope (deprecated) or object
  var msg = translate(getLocaleFromObject(this), singular, plural);

  // parse translation and replace all digets '%d' by `count`
  // this also replaces extra strings '%%s' to parseble '%s' for next step
  // simplest 2 form implementation of plural, like https://developer.mozilla.org/en/docs/Localization_and_Plurals#Plural_rule_.231_.282_forms.29
  if (parseInt(count, 10) > 1) {
    msg = vsprintf(msg.other, [count]);
  } else {
    msg = vsprintf(msg.one, [count]);
  }

  // if we have extra arguments with strings to get replaced,
  // an additional substition injects those strings afterwards
  if (arguments.length > 3) {
    msg = vsprintf(msg, Array.prototype.slice.call(arguments, 3));
  }

  return msg;
};

i18n.setLocale = function i18nSetLocale(locale_or_request, locale) {
  var target_locale = locale_or_request,
      request;

  // called like setLocale(req, 'en')
  if (locale_or_request && typeof locale === 'string' && locales[locale]) {
    request = locale_or_request;
    target_locale = locale;
  }

  // called like req.setLocale('en')
  if (locale === undefined && typeof this.locale === 'string' && typeof locale_or_request === 'string') {
    request = this;
    target_locale = locale_or_request;
  }

  if (locales[target_locale]) {

    // called like setLocale('en')
    if (request === undefined) {
      defaultLocale = target_locale;
    }
    else {
      request.locale = target_locale;
    }
  }
  return i18n.getLocale(request);
};

i18n.getLocale = function i18nGetLocale(request) {

  // called like getLocale(req)
  if (request && request.locale) {
    return request.locale;
  }

  // called like req.getLocale()
  if (request === undefined && typeof this.locale === 'string') {
    return this.locale;
  }

  // called like getLocale()
  return defaultLocale;
};

i18n.getCatalog = function i18nGetCatalog(locale_or_request, locale) {
  var target_locale = locale_or_request;

  // called like getCatalog(req)
  if (typeof locale_or_request === 'object' && typeof locale_or_request.locale === 'string') {
    target_locale = locale_or_request.locale;
  }

  // called like getCatalog(req, 'en')
  if (typeof locale_or_request === 'object' && typeof locale === 'string') {
    target_locale = locale;
  }

  // called like req.getCatalog()
  if (locale === undefined && typeof this.locale === 'string') {
    target_locale = this.locale;
  }

  // called like req.getCatalog('en')
  if (locale === undefined && typeof locale_or_request === 'string') {
    target_locale = locale_or_request;
  }

  // called like getCatalog()
  if (target_locale === undefined || target_locale === '') {
    return locales;
  }

  if (locales[target_locale]) {
    return locales[target_locale];
  } else {
    logWarn('No catalog found for "' + target_locale + '"');
    return false;
  }
};

i18n.overrideLocaleFromQuery = function (req) {
  if (req === null) {
    return;
  }
  var urlObj = url.parse(req.url, true);
  if (urlObj.query.locale) {
    logDebug("Overriding locale from query: " + urlObj.query.locale);
    i18n.setLocale(req, urlObj.query.locale.toLowerCase());
  }
};

// ===================
// = private methods =
// ===================
/**
 * registers all public API methods to a given response object when not already declared
 */

function applyAPItoObject(request, response) {

  // attach to itself if not provided
  var object = response || request;
  api.forEach(function (method) {

    // be kind rewind, or better not touch anything already exiting
    if (!object[method]) {
      object[method] = function () {
        return i18n[method].apply(request, arguments);
      };
    }
  });
}

/**
 * guess language setting based on http headers
 */

function guessLanguage(request) {
  if (typeof request === 'object') {
    var language_header = request.headers['accept-language'],
        languages = [],
        regions = [];

    request.languages = [defaultLocale];
    request.regions = [defaultLocale];
    request.language = defaultLocale;
    request.region = defaultLocale;

    if (language_header) {
      language_header.split(',').forEach(function (l) {
        var header = l.split(';', 1)[0],
            lr = header.split('-', 2);
        if (lr[0]) {
          languages.push(lr[0].toLowerCase());
        }
        if (lr[1]) {
          regions.push(lr[1].toLowerCase());
        }
      });

      if (languages.length > 0) {
        request.languages = languages;
        request.language = languages[0];
      }

      if (regions.length > 0) {
        request.regions = regions;
        request.region = regions[0];
      }
    }

    // setting the language by cookie
    if (cookiename && request.cookies && request.cookies[cookiename]) {
      request.language = request.cookies[cookiename];
    }

    i18n.setLocale(request, request.language);
  }
}

/**
 * searches for locale in given object
 */

function getLocaleFromObject(obj) {
  var locale;
  if (obj && obj.scope) {
    locale = obj.scope.locale;
  }
  if (obj && obj.locale) {
    locale = obj.locale;
  }
  return locale;
}

/**
 * read locale file, translate a msg and write to fs if new
 */

function translate(locale, singular, plural) {
  if (locale === undefined) {
    logWarn("WARN: No locale found - check the context of the call to __(). Using " + defaultLocale + " as current locale");
    locale = defaultLocale;
  }

  // attempt to read when defined as valid locale
  if (!locales[locale]) {
    read(locale);
  }

  // fallback to default when missed
  if (!locales[locale]) {
    logWarn("WARN: Locale " + locale + " couldn't be read - check the context of the call to $__. Using " + defaultLocale + " (default) as current locale");
    locale = defaultLocale;
    read(locale);
  }

  if (plural) {
    if (!locales[locale][singular]) {
      locales[locale][singular] = {
        'one': singular,
        'other': plural
      };
      write(locale);
    }
  }

  if (!locales[locale][singular]) {
    locales[locale][singular] = singular;
    write(locale);
  }
  return locales[locale][singular];
}

/**
 * try reading a file
 */

function read(locale) {
  var localeFile = {},
      file = getStorageFilePath(locale);
  try {
    logDebug('read ' + file + ' for locale: ' + locale);
    localeFile = fs.readFileSync(file);
    try {
      // parsing filecontents to locales[locale]
      locales[locale] = JSON.parse(localeFile);
    } catch (parseError) {
      logError('unable to parse locales from file (maybe ' + file + ' is empty or invalid json?): ', e);
    }
  } catch (readError) {
    // unable to read, so intialize that file
    // locales[locale] are already set in memory, so no extra read required
    // or locales[locale] are empty, which initializes an empty locale.json file
    logDebug('initializing ' + file);
    write(locale);
  }
}

/**
 * try writing a file in a created directory
 */

function write(locale) {
  var stats, target, tmp;

  // don't write new locale information to disk if updateFiles isn't true
  if (!updateFiles) {
    return;
  }

  // creating directory if necessary
  try {
    stats = fs.lstatSync(directory);
  } catch (e) {
    logDebug('creating locales dir in: ' + directory);
    fs.mkdirSync(directory);
  }

  // first time init has an empty file
  if (!locales[locale]) {
    locales[locale] = {};
  }

  // writing to tmp and rename on success
  try {
    target = getStorageFilePath(locale);
    tmp = target + ".tmp";
    fs.writeFileSync(tmp, JSON.stringify(locales[locale], null, "\t"), "utf8");
    stats = fs.statSync(tmp);
    if (stats.isFile()) {
      fs.renameSync(tmp, target);
    } else {
      logError('unable to write locales to file (either ' + tmp + ' or ' + target + ' are not writeable?): ', e);
    }
  } catch (e) {
    logError('unexpected error writing files (either ' + tmp + ' or ' + target + ' are not writeable?): ', e);
  }
}

/**
 * basic normalization of filepath
 */

function getStorageFilePath(locale) {
  // changed API to use .json as default, #16
  var ext = extension || '.json',
      filepath = path.normalize(directory + pathsep + locale + ext),
      filepathJS = path.normalize(directory + pathsep + locale + '.js');
  // use .js as fallback if already existing
  try {
    if (fs.statSync(filepathJS)) {
      logDebug('using existing file ' + filepathJS);
      extension = '.js';
      return filepathJS;
    }
  } catch (e) {
    logDebug('will write to ' + filepath);
  }
  return filepath;
}

/**
 * Logging proxies
 */

function logDebug(msg) {
  debug(msg);
}

function logWarn(msg) {
  warn(msg);
}

function logError(msg) {
  error(msg);
}
<|endoftext|>


<commit_before>/**
 * The MIT License
 * Copyright (c) 2014 Essoduke Chang http://essoduke.org
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * Javascript Internationalization (i18n)
 * The easy way to perform i18n to your javascript project..
 *
 * @author Essoduke Chang
 * @see http://app.essoduke.org/i18n/
 * @version 1.0.0
 *
 * Last Modified Tue, 7 January 2014 09:57:20 GMT
 */
var i18n = (function (window, undefined) {

    'use strict';

    /*
     * Check the client timezone to adjust DST
     */
    var DST = function () {
        var rightNow = new Date(),
            temp = '',
            date1 = new Date(rightNow.getFullYear(), 0, 1, 0, 0, 0, 0),
            date2 = new Date(rightNow.getFullYear(), 6, 1, 0, 0, 0, 0),
            date3,
            date4,
            hoursDiffStdTime = 0,
            hoursDiffDaylightTime = 0;
        temp = date1.toGMTString();
        date3 = new Date(temp.substring(0, temp.lastIndexOf(" ") - 1));
        temp = date2.toGMTString();
        date4 = new Date(temp.substring(0, temp.lastIndexOf(" ") - 1));
        hoursDiffStdTime = (date1 - date3) / (1000 * 60 * 60);
        hoursDiffDaylightTime = (date2 - date4) / (1000 * 60 * 60);
        return (hoursDiffDaylightTime !== hoursDiffStdTime) ? true : false;
    },

    //language code
    lang = '',

    // language file's path
    path = '',

    //localize object
    localize = {},

    //default setting
    setting = {
        "UTC" : -4,
        "format": "D, d F Y H:i:s",
        "AM" : "AM",
        "PM": "PM"
    },

    //fetch lauguage string in JSON object
    locale = function (langcode) {

        var result = {},
            xmlhttp = {},
            url = (0 !== path.length ? path.replace(/\/$/, '') + '/' : '') + langcode + '.js';

        //jQuery ajax
        if (window.jQuery) {
            jQuery.ajax({
                url: url,
                async: false,
                cache: true,
                dataType: 'JSON'
            })
            .fail(function (xhr, status, error) {
                console.dir(status);
            })
            .done(function (resp) {
                result = resp;
            });
        } else {
        // XMLHttpRequest
            var callback = function () {
                if (xmlhttp.readyState === 4) {
                    if (xmlhttp.status === 200) {
                        try {
                            if ('function' === typeof JSON.parse) {
                                result = JSON.parse(xmlhttp.responseText);
                            }
                        } catch (ignore) {
                        }
                    }
                }
            };
            if (window.XMLHttpRequest) {
                xmlhttp = new XMLHttpRequest();
                if (xmlhttp.overrideMimeType) {
                    xmlhttp.overrideMimeType('text/xml');
                }
            } else if (window.ActiveXObject) {
                var activexName = ['MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'];
                for (var i = 0; i < activexName.length; i++) {
                    try {
                        xmlhttp = new ActiveXObject(activexName[i]);
                        break;
                    } catch (ignore) {
                    }
                }
            }
            xmlhttp.onreadystatechange = callback;
            xmlhttp.open('GET', url, false);
            xmlhttp.send(null);
        }
        return result;
    };

    /*
     * Datetime format
     */
    Date.prototype.format=function(format){var returnStr='',replace=Date.replaceChars,curChar='';replace.reload();for(var i=0;i<format.length;i++){curChar=format.charAt(i);returnStr+=(replace[curChar]?replace[curChar].call(this):curChar)}return returnStr};

    /*
     * Datetime function object
     * @see http://jacwright.com/projects/javascript/date_format (unavailable)
     * @see http://code.google.com/p/omeglelogger/source/browse/trunk/dateformat.js?spec=svn2&r=2
     */
    Date.replaceChars={reload:function(){Date.replaceChars.shortMonths=localize.hasOwnProperty('shortMonths')?localize.shortMonths:['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];Date.replaceChars.longMonths=localize.hasOwnProperty('longMonths')?localize.longMonths:['January','February','March','April','May','June','July','August','September','October','November','December'];Date.replaceChars.shortDays=localize.hasOwnProperty('shortDays')?localize.shortDays:['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];Date.replaceChars.longDays=localize.hasOwnProperty('longDays')?localize.longDays:['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']},shortMonths:[],longMonths:[],shortDays:[],longDays:[],d:function(){return(this.getUTCDate()<10?'0':'')+this.getUTCDate()},D:function(){return Date.replaceChars.shortDays[this.getUTCDay()]},j:function(){return this.getUTCDate()},l:function(){return Date.replaceChars.longDays[this.getUTCDay()]},N:function(){return this.getDay()+1},S:function(){return(this.getUTCDate()%10===1&&this.getUTCDate()!==11?'st':(this.getUTCDate()%10===2&&this.getUTCDate()!==12?'nd':(this.getUTCDate()%10==3&&this.getUTCDate()!=13?'rd':'th')))},w:function(){return this.getUTCDay()},z:function(){return''},W:function(){return''},F:function(){return Date.replaceChars.longMonths[this.getUTCMonth()]},m:function(){return(this.getUTCMonth()<9?'0':'')+(this.getUTCMonth()+1)},M:function(){return Date.replaceChars.shortMonths[this.getUTCMonth()]},n:function(){return this.getUTCMonth()+1},t:function(){return''},L:function(){return''},o:function(){return''},Y:function(){return this.getUTCFullYear()},y:function(){return(''+this.getUTCFullYear()).substr(2)},a:function(){var set=localize.hasOwnProperty('setting')?localize.setting:setting;return this.getUTCHours()<12?set.AM:set.PM},A:function(){var set=localize.hasOwnProperty('setting')?localize.setting:setting;return this.getUTCHours()<12?set.AM:set.PM},B:function(){return''},g:function(){return this.getUTCHours()%12||12},G:function(){return this.getUTCHours()},h:function(){return((this.getUTCHours()%12||12)<10?'0':'')+(this.getUTCHours()%12||12)},H:function(){return(this.getUTCHours()<10?'0':'')+this.getUTCHours()},i:function(){return(this.getUTCMinutes()<10?'0':'')+this.getUTCMinutes()},s:function(){return(this.getUTCSeconds()<10?'0':'')+this.getUTCSeconds()},e:function(){return''},I:function(){return''},O:function(){return(-this.getTimezoneOffset()<0?'-':'+')+(Math.abs(this.getTimezoneOffset()/60)<10?'0':'')+(Math.abs(this.getTimezoneOffset()/60))+'00'},T:function(){var m=this.getUTCMonth();this.setMonth(0);var result=this.toTimeString().replace(/^.+ \(?([^\)]+)\)?$/,'$1');this.setMonth(m);return result},Z:function(){return-this.getTimezoneOffset()*60},c:function(){return''},r:function(){return this.toString()},U:function(){return this.getUTCTime()/1000}};

    /*
     * Similar the ASP Dateadd function
     */
    var DateAdd=function(interval,number,date){var d;number=parseInt(number,10);if('string'===typeof date){date=date.split(/\D/);--date[1];d=new Date(date.join(','))}d=('object'===typeof d)?d:date;switch(interval){case'y':d.setFullYear(d.getFullYear()+number);break;case'm':d.setMonth(d.getMonth()+number);break;case'd':d.setDate(d.getDate()+number);break;case'w':d.setDate(d.getDate()+7*number);break;case'h':d.setHours(d.getHours()+number);break;case'n':d.setMinutes(d.getMinutes()+number);break;case's':d.setSeconds(d.getSeconds()+number);break;case'l':d.setMilliseconds(d.getMilliseconds()+number);break}return d};

    /*
     * Public functions
     */
    return {

        /*
         * i18n setting
         */
        set: function (options) {
            if (null !== options && 'object' === typeof options) {
                lang = options.hasOwnProperty('lang') ? options.lang : null;
                path = options.hasOwnProperty('path') ? options.path : path;
            }
            localize = locale(lang || (navigator.browserLanguage || navigator.language).toLowerCase());
        },

        /*
         * Core of the datetime replace
         */
        datetime: function (d) {
            var set = localize.hasOwnProperty('setting') ? localize.setting : setting,
                r = set.format ? DateAdd('h', set.UTC, d ? new Date(d) : new Date()) : (d ? new Date(d) : new Date());
            return r.format(set.format);
        },

        /*
         * Core of the strings replace
         */
        _: function (string) {
            try {
                string = string.toString() || '';
                var args = arguments,
                    pattern = (args.length > 0) ? new RegExp('%([1-' + args.length.toString() + '])', 'g') : null,
                    str = localize.hasOwnProperty(string) ? localize[string] : string;
                return String(str).replace(pattern, function (match, index) { return args[index]; });
            } catch (ignore) {
            }
        }
    };
}(window));
<commit_msg>v1.0.1<commit_after>/**
 * The MIT License
 * Copyright (c) 2014 Essoduke Chang http://essoduke.org
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * Javascript Internationalization (i18n)
 * The easy way to perform i18n to your javascript project..
 *
 * @author Essoduke Chang
 * @see http://app.essoduke.org/i18n/
 * @version 1.0.0
 *
 * Last Modified Tue, 7 January 2014 09:57:20 GMT
 */
var i18n = (function (window, undefined) {

    'use strict';

    /*
     * Check the client timezone to adjust DST
     */
    var DST = function () {
        var rightNow = new Date(),
            temp = '',
            date1 = new Date(rightNow.getFullYear(), 0, 1, 0, 0, 0, 0),
            date2 = new Date(rightNow.getFullYear(), 6, 1, 0, 0, 0, 0),
            date3,
            date4,
            hoursDiffStdTime = 0,
            hoursDiffDaylightTime = 0;
        temp = date1.toGMTString();
        date3 = new Date(temp.substring(0, temp.lastIndexOf(" ") - 1));
        temp = date2.toGMTString();
        date4 = new Date(temp.substring(0, temp.lastIndexOf(" ") - 1));
        hoursDiffStdTime = (date1 - date3) / (1000 * 60 * 60);
        hoursDiffDaylightTime = (date2 - date4) / (1000 * 60 * 60);
        return (hoursDiffDaylightTime !== hoursDiffStdTime) ? true : false;
    },

    //language code
    lang = '',

    // language file's path
    path = '',

    //localize object
    localize = {},

    //default setting
    setting = {
        "UTC" : -4,
        "format": "D, d F Y H:i:s",
        "AM" : "AM",
        "PM": "PM"
    },

    //fetch lauguage string in JSON object
    locale = function (langcode) {

        var result = {},
            xmlhttp = {},
            url = (0 !== path.length ? path.replace(/\/$/, '') + '/' : '') + langcode + '.js';

        //jQuery ajax
        if (window.jQuery) {
            jQuery.ajax({
                url: url,
                async: false,
                cache: true,
                dataType: 'JSON'
            })
            .fail(function (xhr, status, error) {
                console.dir(status);
            })
            .done(function (resp) {
                result = resp;
            });
        } else {
        // XMLHttpRequest
            var callback = function () {
                if (xmlhttp.readyState === 4) {
                    if (xmlhttp.status === 200) {
                        try {
                            if ('function' === typeof JSON.parse) {
                                result = JSON.parse(xmlhttp.responseText);
                            }
                        } catch (ignore) {
                        }
                    }
                }
            };
            if (window.XMLHttpRequest) {
                xmlhttp = new XMLHttpRequest();
                if (xmlhttp.overrideMimeType) {
                    xmlhttp.overrideMimeType('text/xml');
                }
            } else if (window.ActiveXObject) {
                var activexName = ['MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'];
                for (var i = 0; i < activexName.length; i++) {
                    try {
                        xmlhttp = new ActiveXObject(activexName[i]);
                        break;
                    } catch (ignore) {
                    }
                }
            }
            xmlhttp.onreadystatechange = callback;
            xmlhttp.open('GET', url, false);
            xmlhttp.send(null);
        }
        return result;
    };

    /*
     * Datetime format
     */
    Date.prototype.format=function(format){var returnStr='',replace=Date.replaceChars,curChar='';replace.reload();for(var i=0;i<format.length;i++){curChar=format.charAt(i);returnStr+=(replace[curChar]?replace[curChar].call(this):curChar)}return returnStr};

    /*
     * Datetime function object
     * @see http://jacwright.com/projects/javascript/date_format (unavailable)
     * @see http://code.google.com/p/omeglelogger/source/browse/trunk/dateformat.js?spec=svn2&r=2
     */
    Date.replaceChars={reload:function(){Date.replaceChars.shortMonths=localize.hasOwnProperty('shortMonths')?localize.shortMonths:['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];Date.replaceChars.longMonths=localize.hasOwnProperty('longMonths')?localize.longMonths:['January','February','March','April','May','June','July','August','September','October','November','December'];Date.replaceChars.shortDays=localize.hasOwnProperty('shortDays')?localize.shortDays:['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];Date.replaceChars.longDays=localize.hasOwnProperty('longDays')?localize.longDays:['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']},shortMonths:[],longMonths:[],shortDays:[],longDays:[],d:function(){return(this.getUTCDate()<10?'0':'')+this.getUTCDate()},D:function(){return Date.replaceChars.shortDays[this.getUTCDay()]},j:function(){return this.getUTCDate()},l:function(){return Date.replaceChars.longDays[this.getUTCDay()]},N:function(){return this.getDay()+1},S:function(){return(this.getUTCDate()%10===1&&this.getUTCDate()!==11?'st':(this.getUTCDate()%10===2&&this.getUTCDate()!==12?'nd':(this.getUTCDate()%10==3&&this.getUTCDate()!=13?'rd':'th')))},w:function(){return this.getUTCDay()},z:function(){return''},W:function(){return''},F:function(){return Date.replaceChars.longMonths[this.getUTCMonth()]},m:function(){return(this.getUTCMonth()<9?'0':'')+(this.getUTCMonth()+1)},M:function(){return Date.replaceChars.shortMonths[this.getUTCMonth()]},n:function(){return this.getUTCMonth()+1},t:function(){return''},L:function(){return''},o:function(){return''},Y:function(){return this.getUTCFullYear()},y:function(){return(''+this.getUTCFullYear()).substr(2)},a:function(){var set=localize.hasOwnProperty('setting')?localize.setting:setting;return this.getUTCHours()<12?set.AM:set.PM},A:function(){var set=localize.hasOwnProperty('setting')?localize.setting:setting;return this.getUTCHours()<12?set.AM:set.PM},B:function(){return''},g:function(){return this.getUTCHours()%12||12},G:function(){return this.getUTCHours()},h:function(){return((this.getUTCHours()%12||12)<10?'0':'')+(this.getUTCHours()%12||12)},H:function(){return(this.getUTCHours()<10?'0':'')+this.getUTCHours()},i:function(){return(this.getUTCMinutes()<10?'0':'')+this.getUTCMinutes()},s:function(){return(this.getUTCSeconds()<10?'0':'')+this.getUTCSeconds()},e:function(){return''},I:function(){return''},O:function(){return(-this.getTimezoneOffset()<0?'-':'+')+(Math.abs(this.getTimezoneOffset()/60)<10?'0':'')+(Math.abs(this.getTimezoneOffset()/60))+'00'},T:function(){var m=this.getUTCMonth();this.setMonth(0);var result=this.toTimeString().replace(/^.+ \(?([^\)]+)\)?$/,'$1');this.setMonth(m);return result},Z:function(){return-this.getTimezoneOffset()*60},c:function(){return''},r:function(){return this.toString()},U:function(){return this.getUTCTime()/1000}};

    /*
     * Similar the ASP Dateadd function
     */
    var DateAdd=function(interval,number,date){var d;number=parseInt(number,10);if('string'===typeof date){date=date.split(/\D/);--date[1];d=new Date(date.join(','))}d=('object'===typeof d)?d:date;switch(interval){case'y':d.setFullYear(d.getFullYear()+number);break;case'm':d.setMonth(d.getMonth()+number);break;case'd':d.setDate(d.getDate()+number);break;case'w':d.setDate(d.getDate()+7*number);break;case'h':d.setHours(d.getHours()+number);break;case'n':d.setMinutes(d.getMinutes()+number);break;case's':d.setSeconds(d.getSeconds()+number);break;case'l':d.setMilliseconds(d.getMilliseconds()+number);break}return d};

    /*
     * Public functions
     */
    return {

        /*
         * i18n setting
         */
        set: function (options) {
            if (null !== options && 'object' === typeof options) {
                lang = options.hasOwnProperty('lang') ? options.lang : null;
                path = options.hasOwnProperty('path') ? options.path : path;
            }
            localize = locale(lang || (navigator.browserLanguage || navigator.language).toLowerCase());
        },

        /*
         * Core of the datetime replace
         */
        datetime: function (d) {
            var set = localize.hasOwnProperty('setting') ? localize.setting : setting,
                r = set.format ? DateAdd('h', set.UTC, d ? new Date(d) : new Date()) : (d ? new Date(d) : new Date());
            return r.format(set.format);
        },

        /*
         * Core of the strings replace
         */
        _: function (string) {
            try {
                string = string.toString() || '';
                var args = arguments,
                    pattern = (args.length > 0) ? new RegExp('%([1-' + args.length.toString() + '])', 'g') : null,
                    str = localize.hasOwnProperty(string) ? localize[string] : string;
                return String(str).replace(pattern, function (match, index) { return args[index]; });
            } catch (ignore) {
                console.dir(ignore.message);
            }
        }
    };
}(window));
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Link } from 'react-router';
import { connect } from 'react-redux';
import { signoutUser } from '../../actions';

class Header extends Component {
  handleSignout() {
    // Grab action createStore
    signoutUser();
  }

  renderLinks() {
    if (this.props.authenticated) {
      // show a link to sign out
      return (

Hi, Human!

            Edit

            Log Out

      );
    // Will need condition for user on signup pages – show nothing
    } else {
      // show a link to sign in or sign up
      return (

            <Link className="header-item" to="/login" className="header-item">
              Already Registered?
            </Link>

              <Link className="button button-direct" to="/login">Log In</Link>

      );
    }
  }

  render() {
    return (

            <Link to="/" className="header-item">

            </Link>

            {this.renderLinks()}

    );
  }
}

function mapStateToProps(state) {
  return { authenticated: state.auth.authenticated };
}

export default connect(mapStateToProps, signoutUser)(Header);
<commit_msg>fixed styling issue on header item<commit_after>import React, { Component } from 'react';
import { Link } from 'react-router';
import { connect } from 'react-redux';
import { signoutUser } from '../../actions';

class Header extends Component {
  handleSignout() {
    // Grab action createStore
    signoutUser();
  }

  renderLinks() {
    if (this.props.authenticated) {
      // show a link to sign out
      return (

Hi, Human!

            Edit

            Log Out

      );
    // Will need condition for user on signup pages – show nothing
    } else {
      // show a link to sign in or sign up
      return (

            <Link className="header-item" to="/login" className="header-item">
              Already Registered?
            </Link>

              <Link className="button button-direct" to="/login">Log In</Link>

      );
    }
  }

  render() {
    return (

            <Link to="/" className="header-item">

            </Link>

            {this.renderLinks()}

    );
  }
}

function mapStateToProps(state) {
  return { authenticated: state.auth.authenticated };
}

export default connect(mapStateToProps, signoutUser)(Header);
<|endoftext|>


<commit_before>(function () {

'use strict';

var dbg = debug('app:ImageCtrl');

angular.module('phoenixeye')
.controller('ImageCtrl', [
	'$scope',
	'$http',
	'ngToast',
	'$stateParams',
	'$timeout',
	'PollSvc',
	'$modal',
	function ImageCtrl($scope, $http, ngToast, $stateParams, $timeout, PollSvc, $modal) {
		dbg('stateParams', $stateParams);

		$scope.image = $stateParams.image;
		$scope.displayedImage = $stateParams.image;
		$scope.displayedHSV = null;
		$scope.displayedLab = null;

		$scope.collapsedPanels = {};

		//poll for jobId if its a fresh submission
		if( $stateParams.jobId ) {
			pollForJob($stateParams.jobId);
		}

		//poll until image metadata gathering is complete
		PollSvc.pollUntil({
			method: 'get',
			url: 'api/images/' + $stateParams.permalink
		}, function (resp) {
			return resp.image.metaComplete;
		}).promise
		.then(function (resp) {
			dbg('image poll resolved', resp);
			$scope.image = resp.image;
			$scope.displayedImage = resp.image;
			getAnalyses();
		});

		$scope.$watch('image', function (newV) {
			if( ! newV ) return;

			$scope.metaList = {};

			if( newV.xmp ) {
				$scope.metaList.xmp = newV.xmp;
			}

			if( newV.exif ) {
				$scope.metaList.exif = newV.exif;
			}

			if( newV.iptc ) {
				$scope.metaList.iptc = newV.iptc;
			}

			if( newV.exif && newV.exif.GPSInfo ) {
				$scope.gps = {
					lat: gpsDMStoDD(newV.exif.GPSInfo.GPSLatitude, newV.exif.GPSInfo.GPSLatitudeRef),
					lng: gpsDMStoDD(newV.exif.GPSInfo.GPSLongitude, newV.exif.GPSInfo.GPSLongitudeRef)
				};
			}
		});

		//get analyses and separate them by type between histograms/analyses
		function getAnalyses() {
			dbg('get analysis start', $scope.image);

			//reset objects
			$scope.analyses = {
				ela: [],
				lg: [],
				avgdist: [],
				copymove: []
			};

			$scope.histograms = {
				hsv: [],
				lab_fast: []
			};

			$http({
				method: 'get',
				url: 'api/analyses/' + $scope.image.id
			})
			.then(function (resp, status) {
				dbg('analyses', resp);
				resp.data.forEach(function (analysis) {
					if( analysis.type == 'hsv' || analysis.type == 'lab_fast' ) {
						$scope.histograms[analysis.type].push(analysis);
					} else {
						$scope.analyses[analysis.type].push(analysis);
					}
				});

				//sort by most recent created date
				for( var type in $scope.analyses ) {
					$scope.analyses[type] = $scope.analyses[type].sort(function (a, b) {
						return a.created < b.created;
					});
				}

				//sort by most recent created date
				for( var type in $scope.histograms ) {
					$scope.histograms[type] = $scope.histograms[type].sort(function (a, b) {
						return a.created < b.created;
					});
				}

				$scope.displayedHSV = $scope.histograms.hsv[0];
				$scope.displayedLab = $scope.histograms.lab_fast[0];

				//get qtables for jpg after analysis complete
				if( $scope.image.type == 'jpg' && Object.keys($scope.image.qtables).length == 0 ) {
					$http({
						method: 'get',
						url: 'api/images/' + $stateParams.permalink
					})
					.then(function (resp) {
						$scope.image = resp.data.image;
					});
				}
			})
			.catch(function (resp, status) {
				dbg('error analyses', resp);
			});
		}

		function pollForJob(jobId) {
			PollSvc.pollUntil({
				method: 'get',
				url: 'api/jobs/' + jobId
			}, function (resp) {
				return resp.job.status == 'complete';
			}).promise.then(function (resp) {
				dbg('job poll resolved', resp);
				getAnalyses();
			});
		}

		//switch displayed image
		$scope.displayImage = function(image) {
			$scope.displayedImage = image;
		};

		function gpsDMStoDD(gpsString, gpsDirection) {
			var parts = gpsString.split(' ');

			var deg = parseFloat(parts[0].replace('deg', '').replace('°', '')) || 0;
			var min = parseFloat(parts[1]) || 0;
			var sec = parseFloat(parts[2]) || 0;
			gpsDirection = gpsDirection || parts[3];

			console.log(deg, min, sec, gpsDirection);
			var dd = deg + min/60 + sec/3600;

			if( gpsDirection ) {
				gpsDirection = gpsDirection[0].toLowerCase();
				if( gpsDirection == 's' || gpsDirection == 'w' ) {
					dd *= -1;
				}
			}
			console.log(dd);
			return dd;
		}

		$scope.requestAnalysis = function() {
			var modal = $modal.open({
				animation: true,
				templateUrl: 'html/partials/requestAnalysis.html',
				controller: 'RequestAnalysisCtrl'
			});

			modal.result.then(function (resp) {
				dbg('requestAnalysis response', resp);

				pollForJob(resp.data.jobId);
			}).catch(function (err) {
				dbg('requestAnalysis fail', err);
			});
		};
	}
]);

})();<commit_msg>get rid of console.logs<commit_after>(function () {

'use strict';

var dbg = debug('app:ImageCtrl');

angular.module('phoenixeye')
.controller('ImageCtrl', [
	'$scope',
	'$http',
	'ngToast',
	'$stateParams',
	'$timeout',
	'PollSvc',
	'$modal',
	function ImageCtrl($scope, $http, ngToast, $stateParams, $timeout, PollSvc, $modal) {
		dbg('stateParams', $stateParams);

		$scope.image = $stateParams.image;
		$scope.displayedImage = $stateParams.image;
		$scope.displayedHSV = null;
		$scope.displayedLab = null;

		$scope.collapsedPanels = {};

		//poll for jobId if its a fresh submission
		if( $stateParams.jobId ) {
			pollForJob($stateParams.jobId);
		}

		//poll until image metadata gathering is complete
		PollSvc.pollUntil({
			method: 'get',
			url: 'api/images/' + $stateParams.permalink
		}, function (resp) {
			return resp.image.metaComplete;
		}).promise
		.then(function (resp) {
			dbg('image poll resolved', resp);
			$scope.image = resp.image;
			$scope.displayedImage = resp.image;
			getAnalyses();
		});

		$scope.$watch('image', function (newV) {
			if( ! newV ) return;

			$scope.metaList = {};

			if( newV.xmp ) {
				$scope.metaList.xmp = newV.xmp;
			}

			if( newV.exif ) {
				$scope.metaList.exif = newV.exif;
			}

			if( newV.iptc ) {
				$scope.metaList.iptc = newV.iptc;
			}

			if( newV.exif && newV.exif.GPSInfo ) {
				$scope.gps = {
					lat: gpsDMStoDD(newV.exif.GPSInfo.GPSLatitude, newV.exif.GPSInfo.GPSLatitudeRef),
					lng: gpsDMStoDD(newV.exif.GPSInfo.GPSLongitude, newV.exif.GPSInfo.GPSLongitudeRef)
				};
			}
		});

		//get analyses and separate them by type between histograms/analyses
		function getAnalyses() {
			dbg('get analysis start', $scope.image);

			//reset objects
			$scope.analyses = {
				ela: [],
				lg: [],
				avgdist: [],
				copymove: []
			};

			$scope.histograms = {
				hsv: [],
				lab_fast: []
			};

			$http({
				method: 'get',
				url: 'api/analyses/' + $scope.image.id
			})
			.then(function (resp, status) {
				dbg('analyses', resp);
				resp.data.forEach(function (analysis) {
					if( analysis.type == 'hsv' || analysis.type == 'lab_fast' ) {
						$scope.histograms[analysis.type].push(analysis);
					} else {
						$scope.analyses[analysis.type].push(analysis);
					}
				});

				//sort by most recent created date
				for( var type in $scope.analyses ) {
					$scope.analyses[type] = $scope.analyses[type].sort(function (a, b) {
						return a.created < b.created;
					});
				}

				//sort by most recent created date
				for( var type in $scope.histograms ) {
					$scope.histograms[type] = $scope.histograms[type].sort(function (a, b) {
						return a.created < b.created;
					});
				}

				$scope.displayedHSV = $scope.histograms.hsv[0];
				$scope.displayedLab = $scope.histograms.lab_fast[0];

				//get qtables for jpg after analysis complete
				if( $scope.image.type == 'jpg' && Object.keys($scope.image.qtables).length == 0 ) {
					$http({
						method: 'get',
						url: 'api/images/' + $stateParams.permalink
					})
					.then(function (resp) {
						$scope.image = resp.data.image;
					});
				}
			})
			.catch(function (resp, status) {
				dbg('error analyses', resp);
			});
		}

		function pollForJob(jobId) {
			PollSvc.pollUntil({
				method: 'get',
				url: 'api/jobs/' + jobId
			}, function (resp) {
				return resp.job.status == 'complete';
			}).promise.then(function (resp) {
				dbg('job poll resolved', resp);
				getAnalyses();
			});
		}

		//switch displayed image
		$scope.displayImage = function(image) {
			$scope.displayedImage = image;
		};

		function gpsDMStoDD(gpsString, gpsDirection) {
			var parts = gpsString.split(' ');

			var deg = parseFloat(parts[0].replace('deg', '').replace('°', '')) || 0;
			var min = parseFloat(parts[1]) || 0;
			var sec = parseFloat(parts[2]) || 0;
			gpsDirection = gpsDirection || parts[3];

			dbg('gps deg,min,sec,direction', deg, min, sec, gpsDirection);

			var dd = deg + min/60 + sec/3600;

			if( gpsDirection ) {
				gpsDirection = gpsDirection[0].toLowerCase();
				if( gpsDirection == 's' || gpsDirection == 'w' ) {
					dd *= -1;
				}
			}

			dbg('gps dd', dd);

			return dd;
		}

		$scope.requestAnalysis = function() {
			var modal = $modal.open({
				animation: true,
				templateUrl: 'html/partials/requestAnalysis.html',
				controller: 'RequestAnalysisCtrl'
			});

			modal.result.then(function (resp) {
				dbg('requestAnalysis response', resp);

				pollForJob(resp.data.jobId);
			}).catch(function (err) {
				dbg('requestAnalysis fail', err);
			});
		};
	}
]);

})();<|endoftext|>


<commit_before>angular.module("application").controller("AddEditFileGenerationScheduleController", [
    "$scope", "$modalInstance", "NotificationService", "StandardAddress", "AddressFormatter", "SmartAdresseSource", "FileGenerationSchedule", "itemId",
    function ($scope, $modalInstance, NotificationService, StandardAddress, AddressFormatter, SmartAdresseSource, FileGenerationSchedule, itemId) {

        $scope.Title = "Tilføj ny lønkørsel";
        $scope.FileGenerationSchedule = {};
        $scope.FileGenerationSchedule.MailNotificationSchedules = [];
        //$scope.FileGenerationSchedule.DateTimestamp;
        $scope.FileGenerationSchedule.Repeat = "false";
        $scope.tempDate = new Date();
        $scope.ShowTextareaValues = [];
        $scope.DeletedMailsIds = [];
        $scope.MailsDates = [];
        $scope.ModalResult = {
            "FileGenerationSchedule" : {},
            "DeletedMailsIds" : []
        };

        if(itemId > 0){
            // FileGenerationSchedule is being edited
            $scope.Title = "Redigér lønkørsel";
            FileGenerationSchedule.getWithEmailNotifications({ id: itemId }).$promise.then(function (res) {
                $scope.FileGenerationSchedule = res;

                $tempDate = new Date(moment.unix($scope.FileGenerationSchedule.DateTimestamp).format("YYYY-MM-DD"));

                angular.forEach($scope.FileGenerationSchedule.MailNotificationSchedules, function(mailnotif, key){
                    $scope.MailsDates.push(new Date(moment.unix(mailnotif.DateTimestamp).format("YYYY-MM-DD")));
                })

                if($scope.FileGenerationSchedule.Repeat == true){
                    $scope.FileGenerationSchedule.Repeat = "true";
                } else {
                    $scope.FileGenerationSchedule.Repeat = "false";
                }
            });
        }

        $scope.dateOptions = {
            format: "dd/MM/yyyy"
        };

        $scope.confirmSave = function () {
            /// <summary>
            /// Saves new MailNotification if fields are properly filled.
            /// </summary>
            var error = false;

            $scope.repeatErrorMessage = "";
            if ($scope.FileGenerationSchedule.Repeat == "") {
                error = true;
                $scope.repeatErrorMessage = "* Du skal udfylde 'Gentag månedligt'.";
            }

            $scope.payDateErrorMessage = "";
            if ($scope.tempDate == undefined) {
                error = true;
                $scope.payDateErrorMessage = "* Du skal vælge en gyldig lønkørselsdato.";
            }

            var result = {};
            if ($scope.FileGenerationSchedule.Repeat == "true") {
                $scope.FileGenerationSchedule.Repeat = true;
            } else {
                $scope.FileGenerationSchedule.Repeat = false;
            }

            angular.forEach($scope.FileGenerationSchedule.MailNotificationSchedules, function(mailnotif, key){
                mailnotif.DateTimestamp = moment($scope.MailsDates[$scope.FileGenerationSchedule.MailNotificationSchedules.indexOf(mailnotif)]).unix();
            })

            $scope.FileGenerationSchedule.DateTimestamp = moment($scope.tempDate).unix();
            if (!error) {
                $scope.ModalResult.FileGenerationSchedule = $scope.FileGenerationSchedule;
                $modalInstance.close($scope.ModalResult);
                NotificationService.AutoFadeNotification("success", "", "Lønkørslen blev oprettet.");
            }

        }

        $scope.cancel = function () {
            /// <summary>
            /// Cancels creation of new MailNotification.
            /// </summary>
            $modalInstance.dismiss('cancel');
            NotificationService.AutoFadeNotification("warning", "", "Oprettelse af lønkørslen blev annulleret.");
        }

        $scope.AddMailNotificationSchedule = function(){
            $scope.FileGenerationSchedule.MailNotificationSchedules.push({DateTimestamp: 0 , CustomText:""});
            $scope.MailsDates.push(new Date());
            $scope.ShowTextareaValues.push(false);
        }

        $scope.RemoveMailNotificationSchedule = function(index){
            if(index > -1){
                if($scope.FileGenerationSchedule.MailNotificationSchedules[index].Id > 0) {
                    $scope.ModalResult.DeletedMailsIds.push($scope.FileGenerationSchedule.MailNotificationSchedules[index].Id);
                }
                $scope.FileGenerationSchedule.MailNotificationSchedules.splice(index, 1);
                $scope.ShowTextareaValues.splice(index, 1);
            }
        }

        $scope.EnableTextarea = function(index){
            $scope.ShowTextareaValues[index] = !$scope.ShowTextareaValues[index];
        }

        $scope.TextareaEnter = function(index){
            $scope.FileGenerationSchedule.MailNotificationSchedules[index].CustomText += "\n";
        }
    }
]);<commit_msg>FileGeneration load datetime selector hot fix<commit_after>angular.module("application").controller("AddEditFileGenerationScheduleController", [
    "$scope", "$modalInstance", "NotificationService", "StandardAddress", "AddressFormatter", "SmartAdresseSource", "FileGenerationSchedule", "itemId",
    function ($scope, $modalInstance, NotificationService, StandardAddress, AddressFormatter, SmartAdresseSource, FileGenerationSchedule, itemId) {

        $scope.Title = "Tilføj ny lønkørsel";
        $scope.FileGenerationSchedule = {};
        $scope.FileGenerationSchedule.MailNotificationSchedules = [];
        //$scope.FileGenerationSchedule.DateTimestamp;
        $scope.FileGenerationSchedule.Repeat = "false";
        $scope.tempDate = new Date();
        $scope.ShowTextareaValues = [];
        $scope.DeletedMailsIds = [];
        $scope.MailsDates = [];
        $scope.ModalResult = {
            "FileGenerationSchedule" : {},
            "DeletedMailsIds" : []
        };

        if(itemId > 0){
            // FileGenerationSchedule is being edited
            $scope.Title = "Redigér lønkørsel";
            FileGenerationSchedule.getWithEmailNotifications({ id: itemId }).$promise.then(function (res) {
                $scope.FileGenerationSchedule = res;

                $scope.tempDate = new Date(moment.unix($scope.FileGenerationSchedule.DateTimestamp).format("YYYY-MM-DD"));

                angular.forEach($scope.FileGenerationSchedule.MailNotificationSchedules, function(mailnotif, key){
                    $scope.MailsDates.push(new Date(moment.unix(mailnotif.DateTimestamp).format("YYYY-MM-DD")));
                })

                if($scope.FileGenerationSchedule.Repeat == true){
                    $scope.FileGenerationSchedule.Repeat = "true";
                } else {
                    $scope.FileGenerationSchedule.Repeat = "false";
                }
            });
        }

        $scope.dateOptions = {
            format: "dd/MM/yyyy"
        };

        $scope.confirmSave = function () {
            /// <summary>
            /// Saves new MailNotification if fields are properly filled.
            /// </summary>
            var error = false;

            $scope.repeatErrorMessage = "";
            if ($scope.FileGenerationSchedule.Repeat == "") {
                error = true;
                $scope.repeatErrorMessage = "* Du skal udfylde 'Gentag månedligt'.";
            }

            $scope.payDateErrorMessage = "";
            if ($scope.tempDate == undefined) {
                error = true;
                $scope.payDateErrorMessage = "* Du skal vælge en gyldig lønkørselsdato.";
            }

            var result = {};
            if ($scope.FileGenerationSchedule.Repeat == "true") {
                $scope.FileGenerationSchedule.Repeat = true;
            } else {
                $scope.FileGenerationSchedule.Repeat = false;
            }

            angular.forEach($scope.FileGenerationSchedule.MailNotificationSchedules, function(mailnotif, key){
                mailnotif.DateTimestamp = moment($scope.MailsDates[$scope.FileGenerationSchedule.MailNotificationSchedules.indexOf(mailnotif)]).unix();
            })

            $scope.FileGenerationSchedule.DateTimestamp = moment($scope.tempDate).unix();
            if (!error) {
                $scope.ModalResult.FileGenerationSchedule = $scope.FileGenerationSchedule;
                $modalInstance.close($scope.ModalResult);
                NotificationService.AutoFadeNotification("success", "", "Lønkørslen blev oprettet.");
            }

        }

        $scope.cancel = function () {
            /// <summary>
            /// Cancels creation of new MailNotification.
            /// </summary>
            $modalInstance.dismiss('cancel');
            NotificationService.AutoFadeNotification("warning", "", "Oprettelse af lønkørslen blev annulleret.");
        }

        $scope.AddMailNotificationSchedule = function(){
            $scope.FileGenerationSchedule.MailNotificationSchedules.push({DateTimestamp: 0 , CustomText:""});
            $scope.MailsDates.push(new Date());
            $scope.ShowTextareaValues.push(false);
        }

        $scope.RemoveMailNotificationSchedule = function(index){
            if(index > -1){
                if($scope.FileGenerationSchedule.MailNotificationSchedules[index].Id > 0) {
                    $scope.ModalResult.DeletedMailsIds.push($scope.FileGenerationSchedule.MailNotificationSchedules[index].Id);
                }
                $scope.FileGenerationSchedule.MailNotificationSchedules.splice(index, 1);
                $scope.ShowTextareaValues.splice(index, 1);
            }
        }

        $scope.EnableTextarea = function(index){
            $scope.ShowTextareaValues[index] = !$scope.ShowTextareaValues[index];
        }

        $scope.TextareaEnter = function(index){
            $scope.FileGenerationSchedule.MailNotificationSchedules[index].CustomText += "\n";
        }
    }
]);<|endoftext|>