<commit_before>const message = require('../helpers/message')
const when = require('../helpers/when')

const generalPrompts = [
  {
    type: 'input',
    name: 'projectthemecolor',
    message: message({
      headline: 'Project Theme Color',
      description: 'Main Theme-Color of the project',
      defaultValue: 'Default: #29b8f2'
    }),
    default: '#29b8f2',
    store: true
  },
  // Filename
  {
    type: 'input',
    name: 'projectcssfilename',
    message: message({
      headline: 'CSS Filename',
      description: '(only the name without .css or .scss)',
      defaultValue: 'Default: style'
    }),
    default: 'style',
    store: false
  },
  // Stylelint
  {
    type: 'confirm',
    name: 'projectstylelint',
    message: message({
      headline: 'Activate Stylelint',
      description: 'Do you want to ativate Stylelint?',
      defaultValue: true
    }),
    default: true
  },
  // Breakpoint Units
  {
    type: 'list',
    name: 'projectbreakpointunit',
    message: message({
      headline: 'Media Query Unit',
      description: 'Which Unit do you prefer for Media Queries?'
    }),
    choices: [
      {
        name: 'em',
        value: 'em'
      },
      {
        name: 'px',
        value: 'px'
      }
    ]
  },
  // Container-Queries
  {
    type: 'confirm',
    name: 'projectcontainerqueries',
    message: message({
      headline: 'Use Container-Queries',
      description: 'Do you want to use container-queries (see https://github.com/ausi/cq-prolyfill)?'
    }),
    default: false
  },
  // File Structure
  {
    type: 'list',
    name: 'projectcssstructure',
    message: message({
      headline: 'CSS Methodologies',
      description: 'CSS Writing Methodologies'
    }),
    choices: [
      {
        name: 'Own Structure',
        value: 'sassOwn'
      },
      {
        name: 'Atomic Design',
        value: 'sassAtomic'
      },
      {
        name: 'ITCSS',
        value: 'sassITCSS'
      }
    ]
  },
  // Critical CSS
  {
    type: 'confirm',
    name: 'projectcritical',
    message: message({
      headline: 'CriticalCSS',
      description: 'Do you wan\'t to automatically create CriticalCSS (Above the fold)?',
      defaultValue: false
    })
  },
  {
    when: when('projectcritical', true),
    type: 'list',
    name: 'projectcriticalinline',
    message: message({
      headline: 'Inline CriticalCSS',
      description: 'Shall the CSS be injected in the index.html-File, or as separate CSS-File?'
    }),
    choices: [
      {
        name: 'Inline',
        value: 'inline'
      },
      {
        name: 'Separate File',
        value: 'separate'
      }
    ]
  }
]

module.exports = generalPrompts
<commit_msg>Fix failing gulp task<commit_after>const message = require('../helpers/message')
const when = require('../helpers/when')

const generalPrompts = [
  {
    type: 'input',
    name: 'projectthemecolor',
    message: message({
      headline: 'Project Theme Color',
      description: 'Main Theme-Color of the project',
      defaultValue: 'Default: #29b8f2'
    }),
    default: '#29b8f2',
    store: true
  },
  // Filename
  {
    type: 'input',
    name: 'projectcssfilename',
    message: message({
      headline: 'CSS Filename',
      description: '(only the name without .css or .scss)',
      defaultValue: 'Default: style'
    }),
    default: 'style',
    store: false
  },
  // Stylelint
  {
    type: 'confirm',
    name: 'projectstylelint',
    message: message({
      headline: 'Activate Stylelint',
      description: 'Do you want to ativate Stylelint?',
      defaultValue: true
    }),
    default: true
  },
  // Breakpoint Units
  {
    type: 'list',
    name: 'projectbreakpointunit',
    message: message({
      headline: 'Media Query Unit',
      description: 'Which Unit do you prefer for Media Queries?'
    }),
    choices: [
      {
        name: 'em',
        value: 'em'
      },
      {
        name: 'px',
        value: 'px'
      }
    ]
  },
  // Container-Queries
  {
    type: 'confirm',
    name: 'projectcontainerqueries',
    message: message({
      headline: 'Use Container-Queries',
      description: 'Do you want to use container-queries (see https://github.com/ausi/cq-prolyfill)?'
    }),
    default: false
  },
  // File Structure
  {
    type: 'list',
    name: 'projectcssstructure',
    message: message({
      headline: 'CSS Methodologies',
      description: 'CSS Writing Methodologies'
    }),
    choices: [
      {
        name: 'Own Structure',
        value: 'sassOwn'
      },
      {
        name: 'Atomic Design',
        value: 'sassAtomic'
      },
      {
        name: 'ITCSS',
        value: 'sassITCSS'
      }
    ]
  },
  // Critical CSS
  {
    type: 'confirm',
    name: 'projectcritical',
    message: message({
      headline: 'CriticalCSS',
      description: 'Do you wan\'t to automatically create CriticalCSS (Above the fold)?',
      defaultValue: false
    }),
    default: false
  },
  {
    when: when('projectcritical', true),
    type: 'list',
    name: 'projectcriticalinline',
    message: message({
      headline: 'Inline CriticalCSS',
      description: 'Shall the CSS be injected in the index.html-File, or as separate CSS-File?'
    }),
    choices: [
      {
        name: 'Inline',
        value: 'inline'
      },
      {
        name: 'Separate File',
        value: 'separate'
      }
    ]
  }
]

module.exports = generalPrompts
<|endoftext|>


<commit_before>/* IO monad taken from monet.js */
/*
The MIT License (MIT)

Copyright (c) 2016 Chris Myers

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.

*/
/* eslint-disable fp/no-this, fp/no-nil, fp/no-mutation, fp/no-throw */
import * as R from 'ramda';

export const IO = (effectFn) => {
  return new IO.fn.init(effectFn)
};

IO.of = (a) => {
  return IO(() => {
    return a;
  })
};

IO.fn = IO.prototype = {
  init: (effectFn) => {
    if (!R.is(Function, effectFn))
      throw 'IO requires a function';
    this.effectFn = effectFn;
  },
  map: (fn) => {
    return IO(function () {
      return fn(this.effectFn());
    })
  },
  bind: (fn) => {
    return IO(() => {
      return fn(this.effectFn())
        .run();
    })
  },
  ap: (ioWithFn) => {
    return ioWithFn.map((fn) => fn(this.effectFn()));
  },
  run: () => this.effectFn()
};

IO.fn.init.prototype = IO.fn;

IO.prototype.perform = IO.prototype.performUnsafeIO = IO.prototype.run;
<commit_msg>Fix eslint issues<commit_after>/* IO monad taken from monet.js */
/*
The MIT License (MIT)

Copyright (c) 2016 Chris Myers

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.

*/
/* eslint-disable fp/no-this, fp/no-nil, fp/no-mutation, fp/no-throw */
import * as R from 'ramda';

export const IO = (effectFn) => {
  return new IO.fn.init(effectFn);
};

IO.of = (a) => {
  return IO(() => {
    return a;
  });
};

IO.fn = IO.prototype = {
  init: (effectFn) => {
    if (!R.is(Function, effectFn))
      throw 'IO requires a function';
    this.effectFn = effectFn;
  },
  map: (fn) => {
    return IO(function () {
      return fn(this.effectFn());
    });
  },
  bind: (fn) => {
    return IO(() => {
      return fn(this.effectFn())
        .run();
    });
  },
  ap: (ioWithFn) => {
    return ioWithFn.map((fn) => fn(this.effectFn()));
  },
  run: () => this.effectFn()
};

IO.fn.init.prototype = IO.fn;

IO.prototype.perform = IO.prototype.performUnsafeIO = IO.prototype.run;
<|endoftext|>


<commit_before>/* eslint-disable */
/**
 * Modified from the Forest2010 layer
 *  https://storage.googleapis.com/wri-public/mapbiomass/tiles/v4{/YYYY}{/z}{/x}{/y}.png
 * @return (extends CanvasLayerClass)
 */
define([
    'd3',
    'uri',
    'abstract/layer/CanvasLayerClass',
    'map/presenters/layers/Forest2010LayerPresenter'
  ], function(d3, UriTemplate, CanvasLayerClass, Presenter) {

    'use strict';

    var BraMapBiomasLayer = CanvasLayerClass.extend({

      options: {
        threshold: 30,
        dataMaxZoom: 12,
        urlTemplate: 'https://storage.googleapis.com/wri-public/mapbiomass/tiles/v4/2000{/z}{/x}{/y}.png'
      },

      init: function(layer, options, map) {
        this.presenter = new Presenter(this);
        this._super(layer, options, map);
        this.threshold = options.threshold || this.options.threshold;
      },

      /**
       * Filters the canvas imgdata.
       * @override
       */
      filterCanvasImgdata: function(imgdata, w, h) {
      var components = 4;
      var zoom = this.map.getZoom();
      var exp = zoom < 11 ? 0.3 + ((zoom - 3) / 20) : 1;

      var myscale = d3.scale.pow()
            .exponent(exp)
            .domain([0,256])
            .range([0,256]);

      for(var i=0; i < w; ++i) {
        for(var j=0; j < h; ++j) {
          var pixelPos = (j*w + i) * components;
          var intensity = imgdata[pixelPos+1];

          imgdata[pixelPos] = 151;
          imgdata[pixelPos + 1] = 189;
          imgdata[pixelPos + 2] = 61;

          imgdata[pixelPos + 3] = zoom < 13 ? myscale(intensity)*0.8 : intensity*0.8;
        }
      }
      },

      setThreshold: function(threshold) {
        this.threshold = threshold;
        this.presenter.updateLayer();
      },

      _getUrl: function(x, y, z) {
        return new UriTemplate(this.options.urlTemplate)
          .fillFromObject({x: x, y: y, z: z, threshold: this.threshold});
      }

    });

    return BraMapBiomasLayer;

  });
<commit_msg>Adds map colour encoding<commit_after>/* eslint-disable */
/**
 * Modified from the Forest2010 layer
 *  https://storage.googleapis.com/wri-public/mapbiomass/tiles/v4{/YYYY}{/z}{/x}{/y}.png
 * @return (extends CanvasLayerClass)
 */
define(
  [
    'd3',
    'uri',
    'abstract/layer/CanvasLayerClass',
    'map/presenters/layers/Forest2010LayerPresenter'
  ],
  function(d3, UriTemplate, CanvasLayerClass, Presenter) {
    'use strict';

    var BraMapBiomasLayer = CanvasLayerClass.extend({
      options: {
        dataMaxZoom: 12,
        urlTemplate:
          'https://storage.googleapis.com/wri-public/mapbiomass/tiles/v4/2016{/z}{/x}{/y}.png'
      },

      init: function(layer, options, map) {
        this.presenter = new Presenter(this);
        this._super(layer, options, map);
      },

      /**
       * Filters the canvas imgdata.
       * @override
       */
      filterCanvasImgdata: function(imgdata, w, h) {
        var components = 4;
        var zoom = this.map.getZoom();
        var exp = zoom < 11 ? 0.3 + (zoom - 3) / 20 : 1;

        var myscale = d3.scale
          .pow()
          .exponent(exp)
          .domain([0, 256])
          .range([0, 256]);

        for (var i = 0; i < w; ++i) {
          for (var j = 0; j < h; ++j) {
            //maps over square
            var pixelPos = (j * w + i) * components;
            var intensity = imgdata[pixelPos + 1];

            imgdata[pixelPos + 3] =
              zoom < 13 ? myscale(intensity) * 256 : intensity * 256;

            //Natural Forest
            if (imgdata[pixelPos] >= 3 && imgdata[pixelPos] <= 5) {
              imgdata[pixelPos] = 22;
              imgdata[pixelPos + 1] = 99;
              imgdata[pixelPos + 2] = 61;
            } else if (imgdata[pixelPos] === 9) {
              //Planted Forest
              imgdata[pixelPos] = 219;
              imgdata[pixelPos + 1] = 132;
              imgdata[pixelPos + 2] = 215;
            } else if (imgdata[pixelPos] === 11) {
              //Non-forest Wetlands
              imgdata[pixelPos] = 41;
              imgdata[pixelPos + 1] = 210;
              imgdata[pixelPos + 2] = 171;
            } else if (imgdata[pixelPos] === 12) {
              //Grassland
              imgdata[pixelPos] = 195;
              imgdata[pixelPos + 1] = 237;
              imgdata[pixelPos + 2] = 97;
            } else if (imgdata[pixelPos] === 13) {
              //Other Non-forest Vegetation
              imgdata[pixelPos] = 110;
              imgdata[pixelPos + 1] = 162;
              imgdata[pixelPos + 2] = 36;
            } else if (imgdata[pixelPos] === 15) {
              //Pasture
              imgdata[pixelPos] = 205;
              imgdata[pixelPos + 1] = 125;
              imgdata[pixelPos + 2] = 40;
            } else if (imgdata[pixelPos] === 18) {
              //Agriculture
              imgdata[pixelPos] = 251;
              imgdata[pixelPos + 1] = 240;
              imgdata[pixelPos + 2] = 171;
            } else if (imgdata[pixelPos] === 21) {
              //Pasture or Agriculture
              imgdata[pixelPos] = 244;
              imgdata[pixelPos + 1] = 214;
              imgdata[pixelPos + 2] = 52;
            } else if (imgdata[pixelPos] >= 22 && imgdata[pixelPos] <= 25) {
              //Non-vegetated Area
              imgdata[pixelPos] = 209;
              imgdata[pixelPos + 1] = 211;
              imgdata[pixelPos + 2] = 211;
            } else if (imgdata[pixelPos] === 26) {
              //ater Bodies
              imgdata[pixelPos] = 39;
              imgdata[pixelPos + 1] = 132;
              imgdata[pixelPos + 2] = 188;
            } else if (imgdata[pixelPos] === 27) {
              //Unobserved
              imgdata[pixelPos] = 92;
              imgdata[pixelPos + 1] = 96;
              imgdata[pixelPos + 2] = 96;
              imgdata[pixelPos + 3] = 0;
            } else if (
              imgdata[pixelPos] === 1 ||
              imgdata[pixelPos] === 2 ||
              imgdata[pixelPos] === 10 ||
              imgdata[pixelPos] === 14
            ) {
              //Unknown / No data
              imgdata[pixelPos] = 256;
              imgdata[pixelPos + 1] = 256;
              imgdata[pixelPos + 2] = 256;
              imgdata[pixelPos + 3] = 0;
            } else {
              imgdata[pixelPos] = 256;
              imgdata[pixelPos + 1] = 256;
              imgdata[pixelPos + 2] = 256;
              imgdata[pixelPos + 3] = 0;
            }
          }
        }
      },

      setThreshold: function(threshold) {
        this.threshold = threshold;
        this.presenter.updateLayer();
      },

      _getUrl: function(x, y, z) {
        return new UriTemplate(this.options.urlTemplate).fillFromObject({
          x: x,
          y: y,
          z: z,
          threshold: this.threshold
        });
      }
    });

    return BraMapBiomasLayer;
  }
);
<|endoftext|>


<commit_before>'use strict';

// TODO: inject an entity service, and use it to get the entity object
angular.module('memexLinkerApp')
.controller('EntitydetailCtrl', function ($scope, $http, $stateParams, $q, $modal, lodash, Auth) {
    var _ = lodash;

    function collectAdProperty(ads, propertyName) {
      return _.map(ads, function(ad) {
        return ad.properties[propertyName];
      });
    }

    function uniqueFlatAndDefined(items) {
      return _.filter(_.uniq(_.flatten(items)), function(item) {
        return ! _.isUndefined(item);
      });
    }
    function uniqueAndDefined(items) {
      return _.filter(_.uniq(items), function(item) {
        return ! _.isUndefined(item);
      });
    }

    function mode(arr) {
    return arr.reduce(function(current, item) {
        var val = current.numMapping[item] = (current.numMapping[item] || 0) + 1;
        if (val > current.greatestFreq) {
            current.greatestFreq = val;
            current.mode = item;
        }
        return current;
    }, {mode: null, greatestFreq: -Infinity, numMapping: {}}, arr).mode;
    }

    $scope.logo = 'http://icons.iconarchive.com/icons/icons8/ios7/256/Very-Basic-Paper-Clip-icon.png';

    $scope.map = {
        center: {
            latitude: 33.5206608,
            longitude: -86.80248999999998
        },
        zoom: 8
    };
    $scope.markers = [
                 // {
                 //   id: 583187,
                 //   latitude: 46.7682,
                 //   longitude: -71.3234,
                 //   title: 'title'
                 // }
               ];

    $scope.blur = true;
    $scope.ads = [];
    $scope.imageUrls = [];
    $scope.face_image_url = [];
    $scope.suggestedAds = [];
    $scope.id = $stateParams.id;
    $scope.user = null;

    $scope.heatmapConfig = {
        entityId: $scope.id,
        start: new Date(2013, 0),
        domain : 'year',
        cellSize: 14,
        subDomain : 'day',
        legend: [2, 4, 6, 10],
        range : 1
    };

    // if (Auth.isLoggedIn()) {
    //     $scope.user = Auth.getCurrentUser();
    //     console.log($scope.user);
    // }

    $scope.entity = {
        phone:'',
        email:[],
        name:[],
        city:[],
        age:[],
        ethnicities:[],
        height:[],
        weight:[],
        eyes:[],
        hair:[],
        price:[],
        postTimes:[],
        firstPostTime:''
    };

    $scope.getHost = function (url) {
        var parser = document.createElement('a');
        parser.href = url;
        return parser.host;
    };

    // ---- Map Modal ------- //

    $scope.lat = 34.834442;
    $scope.lng = -82.3686479;

    $scope.expandMap = function () {
        var modalInstance = $modal.open({
            templateUrl:'/app/entitydetail/partials/mapdetail.html',
            controller: ModalInstanceCtrl,
            resolve: {
                lat: function () {
                    return $scope.lat;
                },
                lng: function () {
                    return $scope.lng;
                }
            }
        });
    };

    // Link Ad to Entity by user-confirmed image similarity.
    $scope.linkToEntity = function(ad) {
        var data = {
            idA: _.parseInt($scope.id),
            idB: ad.id,
            relType: 'BY_IMG',
            properties: {
                userName: 'test_user'
            }
        };
        $http.post('/api/relationships', data).
          success(function(data, status, headers, config) {
            updateLinked();
            updateSuggestedText();
            updateSuggestedImage();
          }).
          error(function(data, status, headers, config) {
            console.log(data);
          });
    };

    var ModalInstanceCtrl = function ($scope, $modalInstance, lat, lng) {
        $scope.lat = lat;
        $scope.lng = lng;

        $scope.ok = function() {
            $modalInstance.close();
        };

        $scope.cancel = function () {
            $modalInstance.dismiss('cancel');
        };
    };

    // ---- Map Modal ------- //

    $http.get('/api/entities/' + $scope.id).success(function(res) {
        $scope.entity.phone = res._node.properties.identifier;
        $scope.entity.email = res._node.properties.email;
        $scope.entity.name = res._node.properties.name;
        $scope.entity.city = res._node.properties.city;
        $scope.entity.n_faces = res._node.properties.n_faces;
    });

    function updateLinked() {
        $http.get('api/entities/' + $scope.id + '/linked').success(function(res){
            $scope.ads = _.map(res, function(element){
              var ad = {
                'id':element.ad._id,
                'labels':element.ad.labels,
                'properties':element.ad.properties
              };
              return ad;
            });
            updateEntity();
        });
    }

    function updateSuggestedText() {
        $http.get('api/entities/' + $scope.id + '/byText').success(function(res){
            $scope.suggestedAds = _.map(res, function(element){
              var ad = {
                'id':element.ad._id,
                'labels':element.ad.labels,
                'properties':element.ad.properties,
                'suggestedByText':true
              };
              return ad;
            });

            updateEntity();
        });

    }

    function updateSuggestedImage() {
        $http.get('api/entities/' + $scope.id + '/byImage').success(function(res){
            $scope.suggestedAds = _.map(res, function(element){
              var ad = {
                'id':element.ad._id,
                'labels':element.ad.labels,
                'properties':element.ad.properties,
                'suggestedByImage':true
              };
              return ad;
            });

            updateEntity();
        });

    }

    function updateEntity() {
        $scope.entity.cities= uniqueFlatAndDefined(collectAdProperty($scope.ads, 'city')).sort();
        $scope.entity.postTime= uniqueFlatAndDefined(collectAdProperty($scope.ads, 'posttime')).sort();
        $scope.entity.age = uniqueFlatAndDefined(collectAdProperty($scope.ads, 'age')).sort();
        $scope.entity.ethnicities = uniqueFlatAndDefined(collectAdProperty($scope.ads, 'ethnicity')).sort();
        $scope.entity.height = uniqueFlatAndDefined(collectAdProperty($scope.ads, 'height')).sort();
        $scope.entity.weight = uniqueFlatAndDefined(collectAdProperty($scope.ads, 'weight')).sort();
        $scope.entity.eyes = uniqueFlatAndDefined(collectAdProperty($scope.ads, 'eyes')).sort();
        $scope.entity.hair = uniqueFlatAndDefined(collectAdProperty($scope.ads, 'hair')).sort();
        $scope.entity.price = uniqueFlatAndDefined(collectAdProperty($scope.ads, 'rate60')).sort();
        //var priceRange = 'Missing' ;
        if ($scope.entity.price[0] !== null) {
            $scope.entity.minPrice = _.min($scope.entity.price);
            $scope.entity.maxPrice = _.max($scope.entity.price);
        }
        else {
            $scope.entity.minPrice = 'Missing';
            $scope.entity.maxPrice = 'Missing';
        }
        $scope.entity.modePrice = mode($scope.entity.price);
        $scope.entity.name = uniqueFlatAndDefined(collectAdProperty($scope.ads, 'name')).sort();
        $scope.entity.email = _.uniq(
            _.map($scope.ads, function(ad) {
                return ad.properties.email;
            })
            );
        $scope.entity.email = _.filter($scope.entity.email, function(element){
            return ! _.isEmpty(element);
        });

        $scope.imageUrls = _.flatten(
          _.map($scope.ads, function(ad) {
            return ad.properties.image_locations;
        }),
          true
          );
        $scope.imageUrls = _.filter($scope.imageUrls, function(element){
          return ! _.isUndefined(element);
      });

        $scope.face_image_url = _.flatten(
          _.map($scope.ads, function(ad) {
            return ad.properties.face_image_url;
        }),
        true
          );
        $scope.face_image_url = _.filter($scope.face_image_url, function(element){
          return ! _.isUndefined(element);
      });

        if (! _.isEmpty($scope.entity.cities)) {

            var promise = geocodeCity($scope.entity.cities[0]);
            promise.then(function(point) {
                $scope.map = {
                    center: {
                        latitude: point.latitude,
                        longitude: point.longitude
                    },
                    zoom: 8
                };
                console.log($scope.map);
            }, function(reason) {
                console.log('Failed');
            }, function(update) {
                console.log('Alert');
            });

            _.forEach($scope.entity.cities, function(city, key) {
                console.log(city, key);
                geocodeCity(city)
                    .then(function(point){
                        console.log(point);
                                         //   id: 583187,
                 //   latitude: 46.7682,
                 //   longitude: -71.3234,
                 //   title: 'title'
                        var m = {
                            id:key,
                            latitude: point.latitude,
                            longitude: point.longitude,
                            title: city
                        };
                        console.log('Marker:');
                        console.log(m);
                        $scope.markers.push(m);
                    });
            });
        }
    }

    var geocoder = new google.maps.Geocoder();
    function geocodeCity(cityName) {
        var deferred = $q.defer();

        geocoder.geocode( { 'address': cityName }, function(results, status) {
            if (status === google.maps.GeocoderStatus.OK && results.length > 0) {
                var location = results[0].geometry.location;
                deferred.resolve({
                    latitude: parseFloat(location.lat()),
                    longitude: parseFloat(location.lng())
                });
            } else {
                deferred.resolve({
                    latitude: 0,
                    longitude: 0
                });
            }
        });
        return deferred.promise;
    }

    updateLinked();
    updateSuggestedText();
    updateSuggestedImage();
});

// TODO: put this under components
angular.module('memexLinkerApp').
filter('capitalize', function() {
    return function(input, all) {
      return (!!input) ? input.replace(/([^\W_]+[^\s-]*) */g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}) : '';
  };
});

<commit_msg>whitespace cleanup<commit_after>'use strict';

// TODO: inject an entity service, and use it to get the entity object
angular.module('memexLinkerApp')
.controller('EntitydetailCtrl', function ($scope, $http, $stateParams, $q, $modal, lodash, Auth) {
    var _ = lodash;

    function collectAdProperty(ads, propertyName) {
      return _.map(ads, function(ad) {
        return ad.properties[propertyName];
      });
    }

    function uniqueFlatAndDefined(items) {
      return _.filter(_.uniq(_.flatten(items)), function(item) {
        return ! _.isUndefined(item);
      });
    }
    function uniqueAndDefined(items) {
      return _.filter(_.uniq(items), function(item) {
        return ! _.isUndefined(item);
      });
    }

    function mode(arr) {
    return arr.reduce(function(current, item) {
        var val = current.numMapping[item] = (current.numMapping[item] || 0) + 1;
        if (val > current.greatestFreq) {
            current.greatestFreq = val;
            current.mode = item;
        }
        return current;
    }, {mode: null, greatestFreq: -Infinity, numMapping: {}}, arr).mode;
    }

    $scope.logo = 'http://icons.iconarchive.com/icons/icons8/ios7/256/Very-Basic-Paper-Clip-icon.png';

    $scope.map = {
        center: {
            latitude: 33.5206608,
            longitude: -86.80248999999998
        },
        zoom: 8
    };
    $scope.markers = [
                 // {
                 //   id: 583187,
                 //   latitude: 46.7682,
                 //   longitude: -71.3234,
                 //   title: 'title'
                 // }
               ];

    $scope.blur = true;
    $scope.ads = [];
    $scope.imageUrls = [];
    $scope.face_image_url = [];
    $scope.suggestedAds = [];
    $scope.id = $stateParams.id;
    $scope.user = null;

    $scope.heatmapConfig = {
        entityId: $scope.id,
        start: new Date(2013, 0),
        domain : 'year',
        cellSize: 14,
        subDomain : 'day',
        legend: [2, 4, 6, 10],
        range : 1
    };

    // if (Auth.isLoggedIn()) {
    //     $scope.user = Auth.getCurrentUser();
    //     console.log($scope.user);
    // }

    $scope.entity = {
        phone:'',
        email:[],
        name:[],
        city:[],
        age:[],
        ethnicities:[],
        height:[],
        weight:[],
        eyes:[],
        hair:[],
        price:[],
        postTimes:[],
        firstPostTime:''
    };

    $scope.getHost = function (url) {
        var parser = document.createElement('a');
        parser.href = url;
        return parser.host;
    };

    // ---- Map Modal ------- //

    $scope.lat = 34.834442;
    $scope.lng = -82.3686479;

    $scope.expandMap = function () {
        var modalInstance = $modal.open({
            templateUrl:'/app/entitydetail/partials/mapdetail.html',
            controller: ModalInstanceCtrl,
            resolve: {
                lat: function () {
                    return $scope.lat;
                },
                lng: function () {
                    return $scope.lng;
                }
            }
        });
    };

    // Link Ad to Entity by user-confirmed image similarity.
    $scope.linkToEntity = function(ad) {
        var data = {
            idA: _.parseInt($scope.id),
            idB: ad.id,
            relType: 'BY_IMG',
            properties: {
                userName: 'test_user'
            }
        };
        $http.post('/api/relationships', data).
          success(function(data, status, headers, config) {
            updateLinked();
            updateSuggestedText();
            updateSuggestedImage();
          }).
          error(function(data, status, headers, config) {
            console.log(data);
          });
    };

    var ModalInstanceCtrl = function ($scope, $modalInstance, lat, lng) {
        $scope.lat = lat;
        $scope.lng = lng;

        $scope.ok = function() {
            $modalInstance.close();
        };

        $scope.cancel = function () {
            $modalInstance.dismiss('cancel');
        };
    };

    // ---- Map Modal ------- //

    $http.get('/api/entities/' + $scope.id).success(function(res) {
        $scope.entity.phone = res._node.properties.identifier;
        $scope.entity.email = res._node.properties.email;
        $scope.entity.name = res._node.properties.name;
        $scope.entity.city = res._node.properties.city;
        $scope.entity.n_faces = res._node.properties.n_faces;
    });

    function updateLinked() {
        $http.get('api/entities/' + $scope.id + '/linked').success(function(res){
            $scope.ads = _.map(res, function(element){
              var ad = {
                'id':element.ad._id,
                'labels':element.ad.labels,
                'properties':element.ad.properties
              };
              return ad;
            });
            updateEntity();
        });
    }

    function updateSuggestedText() {
        $http.get('api/entities/' + $scope.id + '/byText').success(function(res){
            $scope.suggestedAds = _.map(res, function(element){
              var ad = {
                'id':element.ad._id,
                'labels':element.ad.labels,
                'properties':element.ad.properties,
                'suggestedByText':true
              };
              return ad;
            });

            updateEntity();
        });

    }

    function updateSuggestedImage() {
        $http.get('api/entities/' + $scope.id + '/byImage').success(function(res){
            $scope.suggestedAds = _.map(res, function(element){
              var ad = {
                'id':element.ad._id,
                'labels':element.ad.labels,
                'properties':element.ad.properties,
                'suggestedByImage':true
              };
              return ad;
            });

            updateEntity();
        });

    }

    function updateEntity() {
        $scope.entity.cities= uniqueFlatAndDefined(collectAdProperty($scope.ads, 'city')).sort();
        $scope.entity.postTime= uniqueFlatAndDefined(collectAdProperty($scope.ads, 'posttime')).sort();
        $scope.entity.age = uniqueFlatAndDefined(collectAdProperty($scope.ads, 'age')).sort();
        $scope.entity.ethnicities = uniqueFlatAndDefined(collectAdProperty($scope.ads, 'ethnicity')).sort();
        $scope.entity.height = uniqueFlatAndDefined(collectAdProperty($scope.ads, 'height')).sort();
        $scope.entity.weight = uniqueFlatAndDefined(collectAdProperty($scope.ads, 'weight')).sort();
        $scope.entity.eyes = uniqueFlatAndDefined(collectAdProperty($scope.ads, 'eyes')).sort();
        $scope.entity.hair = uniqueFlatAndDefined(collectAdProperty($scope.ads, 'hair')).sort();
        $scope.entity.price = uniqueFlatAndDefined(collectAdProperty($scope.ads, 'rate60')).sort();
        //var priceRange = 'Missing' ;
        if ($scope.entity.price[0] !== null) {
            $scope.entity.minPrice = _.min($scope.entity.price);
            $scope.entity.maxPrice = _.max($scope.entity.price);
        }
        else {
            $scope.entity.minPrice = 'Missing';
            $scope.entity.maxPrice = 'Missing';
        }
        $scope.entity.modePrice = mode($scope.entity.price);
        $scope.entity.name = uniqueFlatAndDefined(collectAdProperty($scope.ads, 'name')).sort();
        $scope.entity.email = _.uniq(
            _.map($scope.ads, function(ad) {
                return ad.properties.email;
            })
            );
        $scope.entity.email = _.filter($scope.entity.email, function(element){
            return ! _.isEmpty(element);
        });

        $scope.imageUrls = _.flatten(
          _.map($scope.ads, function(ad) {
            return ad.properties.image_locations;
        }),
          true
          );
        $scope.imageUrls = _.filter($scope.imageUrls, function(element){
          return ! _.isUndefined(element);
      });

        $scope.face_image_url = _.flatten(
          _.map($scope.ads, function(ad) {
            return ad.properties.face_image_url;
        }),
        true
          );
        $scope.face_image_url = _.filter($scope.face_image_url, function(element){
          return ! _.isUndefined(element);
      });

        if (! _.isEmpty($scope.entity.cities)) {

            var promise = geocodeCity($scope.entity.cities[0]);
            promise.then(function(point) {
                $scope.map = {
                    center: {
                        latitude: point.latitude,
                        longitude: point.longitude
                    },
                    zoom: 8
                };
                console.log($scope.map);
            }, function(reason) {
                console.log('Failed');
            }, function(update) {
                console.log('Alert');
            });

            _.forEach($scope.entity.cities, function(city, key) {
                console.log(city, key);
                geocodeCity(city)
                    .then(function(point){
                        console.log(point);
                                         //   id: 583187,
                 //   latitude: 46.7682,
                 //   longitude: -71.3234,
                 //   title: 'title'
                        var m = {
                            id:key,
                            latitude: point.latitude,
                            longitude: point.longitude,
                            title: city
                        };
                        console.log('Marker:');
                        console.log(m);
                        $scope.markers.push(m);
                    });
            });
        }
    }

    var geocoder = new google.maps.Geocoder();
    function geocodeCity(cityName) {
        var deferred = $q.defer();

        geocoder.geocode( { 'address': cityName }, function(results, status) {
            if (status === google.maps.GeocoderStatus.OK && results.length > 0) {
                var location = results[0].geometry.location;
                deferred.resolve({
                    latitude: parseFloat(location.lat()),
                    longitude: parseFloat(location.lng())
                });
            } else {
                deferred.resolve({
                    latitude: 0,
                    longitude: 0
                });
            }
        });
        return deferred.promise;
    }

    updateLinked();
    updateSuggestedText();
    updateSuggestedImage();
});

// TODO: put this under components
angular.module('memexLinkerApp').
filter('capitalize', function() {
    return function(input, all) {
      return (!!input) ? input.replace(/([^\W_]+[^\s-]*) */g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}) : '';
  };
});

<|endoftext|>


<commit_before>import SimpleJoin from '../models/simple_join'

describe ( 'SimpleJoin', () => {
  describe( '#constructor', () => {
    it( 'throws when no parameters are provided', () => {
      expect( () => new SimpleJoin() ).toThrow( 'Table parameter is required' )
    })

    it( 'throws when a non string parameter is provided', () => {
      expect( () => new SimpleJoin( 1 ) ).toThrow( 'Table parameter must be string' )
    })
  })

  describe( '#toString', () => {
    it( 'returns a SELECT field.* SQL statement JOIN', () => {
      const query = new SimpleJoin( 'genres',  {
          fields: ['genres', 'book_genres.book_id'],
          join: ['book_genres'],
          where: [{ field_id: 'book_genres.book_id' }],
          on: [{join_id: 'book_genres.genre_id', eqlTo: 'genres.id'}],
          in: 1
        })

      expect( query.toString() ).toEqual(
        `SELECT genres.*, book_genres.book_id FROM genres JOIN book_genres ON genres.id = book_genres.genre_id WHERE book_genres.book_id IN 1`
      )
    })

  it( 'returns a SELECT field.* SQL statement JOIN', () => {
    const query = new SimpleJoin( 'genres',  {
        fields: ['genres'],
        join: ['book_genres'],
        where: [{ field_id: 'book_genres.book_id' }],
        on: [{join_id: 'book_genres.genre_id', eqlTo: 'genres.id'}],
        in: 1
      })

    expect( query.toString() ).toEqual(
      `SELECT genres.* FROM genres JOIN book_genres ON genres.id = book_genres.genre_id WHERE book_genres.book_id IN 1`
    )
  })
  })
})

/*
SELECT genres.*, book_genres.book_id FROM book_genres ON genres.id = book_genres.genre_id WHERE book_genres.book_id IN (stuff)

SELECT authors.*, book_authors.book_id FROM book_authors ON authors.id = book_authors.author_id WHERE book_authors.book_id IN (stuff)
SELECT book.*, book_favorites.user_id FROM book_favorites ON book.id = book_favorites.user_id WHERE book_favorites.book_id IN (stuff)
*/
<commit_msg>one more test for join class<commit_after>import SimpleJoin from '../models/simple_join'

describe ( 'SimpleJoin', () => {
  describe( '#constructor', () => {
    it( 'throws when no parameters are provided', () => {
      expect( () => new SimpleJoin() ).toThrow( 'Table parameter is required' )
    })

    it( 'throws when a non string parameter is provided', () => {
      expect( () => new SimpleJoin( 1 ) ).toThrow( 'Table parameter must be string' )
    })
  })

  describe( '#toString', () => {
    it( 'returns a SELECT field.* SQL statement JOIN', () => {
      const query = new SimpleJoin( 'genres',  {
          fields: ['genres', 'book_genres.book_id'],
          join: ['book_genres'],
          where: [{ field_id: 'book_genres.book_id' }],
          on: [{join_id: 'book_genres.genre_id', eqlTo: 'genres.id'}],
          in: 1
        })

      expect( query.toString() ).toEqual(
        `SELECT genres.*, book_genres.book_id FROM genres JOIN book_genres ON genres.id = book_genres.genre_id WHERE book_genres.book_id IN 1`
      )
    })

    it( 'returns a SELECT field.* SQL statement JOIN', () => {
      const query = new SimpleJoin( 'genres',  {
          fields: ['genres'],
          join: ['book_genres'],
          where: [{ field_id: 'book_genres.book_id' }],
          on: [{join_id: 'book_genres.genre_id', eqlTo: 'genres.id'}],
          in: 1
        })

      expect( query.toString() ).toEqual(
        `SELECT genres.* FROM genres JOIN book_genres ON genres.id = book_genres.genre_id WHERE book_genres.book_id IN 1`
      )
    })

    it( 'returns a SELECT field.* SQL statement JOIN', () => {
      const query = new SimpleJoin( 'books',  {
          fields: ['books'],
          join: ['book_authors'],
          where: [{ field_id: 'book_authors.author_id' }],
          on: [{join_id: 'book_authors.book_id', eqlTo: 'book.id'}],
          in: 1
        })

      expect( query.toString() ).toEqual(
        `SELECT books.* FROM books JOIN book_authors ON book.id = book_authors.book_id WHERE book_authors.author_id IN 1`
      )
    })
  })
})

/*
SELECT genres.*, book_genres.book_id FROM book_genres ON genres.id = book_genres.genre_id WHERE book_genres.book_id IN (stuff)

SELECT authors.*, book_authors.book_id FROM book_authors ON authors.id = book_authors.author_id WHERE book_authors.book_id IN (stuff)
SELECT book.*, book_favorites.user_id FROM book_favorites ON book.id = book_favorites.user_id WHERE book_favorites.book_id IN (stuff)
*/
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactNative
 * @flow
 */
'use strict';

// Require ReactNativeDefaultInjection first for its side effects of setting up
// the JS environment
var ReactNativeDefaultInjection = require('ReactNativeDefaultInjection');

var ReactChildren = require('ReactChildren');
var ReactClass = require('ReactClass');
var ReactComponent = require('ReactComponent');
var ReactCurrentOwner = require('ReactCurrentOwner');
var ReactElement = require('ReactElement');
var ReactElementValidator = require('ReactElementValidator');
var ReactInstanceHandles = require('ReactInstanceHandles');
var ReactNativeMount = require('ReactNativeMount');
var ReactPropTypes = require('ReactPropTypes');
var ReactUpdates = require('ReactUpdates');

var findNodeHandle = require('findNodeHandle');
var invariant = require('fbjs/lib/invariant');
var onlyChild = require('onlyChild');
var warning = require('fbjs/lib/warning');

ReactNativeDefaultInjection.inject();

var createElement = ReactElement.createElement;
var createFactory = ReactElement.createFactory;
var cloneElement = ReactElement.cloneElement;

if (__DEV__) {
  createElement = ReactElementValidator.createElement;
  createFactory = ReactElementValidator.createFactory;
  cloneElement = ReactElementValidator.cloneElement;
}

var resolveDefaultProps = function(element) {
  // Could be optimized, but not currently in heavy use.
  var defaultProps = element.type.defaultProps;
  var props = element.props;
  for (var propName in defaultProps) {
    if (props[propName] === undefined) {
      props[propName] = defaultProps[propName];
    }
  }
};

// Experimental optimized element creation
var augmentElement = function(element: ReactElement): ReactElement {
  if (__DEV__) {
    invariant(
      false,
      'This optimized path should never be used in DEV mode because ' +
      'it does not provide validation. Check your JSX transform.'
    );
  }
  element._owner = ReactCurrentOwner.current;
  if (element.type.defaultProps) {
    resolveDefaultProps(element);
  }
  return element;
};

var render = function(
  element: ReactElement,
  mountInto: number,
  callback?: ?(() => void)
): ?ReactComponent {
  return ReactNativeMount.renderComponent(element, mountInto, callback);
};

var ReactNative = {
  hasReactNativeInitialized: false,
  Children: {
    map: ReactChildren.map,
    forEach: ReactChildren.forEach,
    count: ReactChildren.count,
    toArray: ReactChildren.toArray,
    only: onlyChild
  },
  Component: ReactComponent,
  PropTypes: ReactPropTypes,
  createClass: ReactClass.createClass,
  createElement: createElement,
  createFactory: createFactory,
  cloneElement: cloneElement,
  _augmentElement: augmentElement,
  findNodeHandle: findNodeHandle,
  render: render,
  unmountComponentAtNode: ReactNativeMount.unmountComponentAtNode,

  /* eslint-disable camelcase */
  unstable_batchedUpdates: ReactUpdates.batchedUpdates,
  /* eslint-enable camelcase */

  // Hook for JSX spread, don't use this for anything else.
  __spread: Object.assign,

  unmountComponentAtNodeAndRemoveContainer: ReactNativeMount.unmountComponentAtNodeAndRemoveContainer,
  isValidClass: ReactElement.isValidFactory,
  isValidElement: ReactElement.isValidElement,

  // Deprecations (remove for 0.13)
  renderComponent: function(
    element: ReactElement,
    mountInto: number,
    callback?: ?(() => void)
  ): ?ReactComponent {
    warning('Use React.render instead of React.renderComponent');
    return ReactNative.render(element, mountInto, callback);
  },
};

// Inject the runtime into a devtools global hook regardless of browser.
// Allows for debugging when the hook is injected on the page.
/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
  typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
  typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') {
  __REACT_DEVTOOLS_GLOBAL_HOOK__.inject({
    CurrentOwner: ReactCurrentOwner,
    InstanceHandles: ReactInstanceHandles,
    Mount: ReactNativeMount,
    Reconciler: require('ReactReconciler'),
    TextComponent: require('ReactNativeTextComponent'),
  });
}

module.exports = ReactNative;
<commit_msg>Strip isomorphic stuff from the ReactNative module<commit_after>/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactNative
 * @flow
 */
'use strict';

// Require ReactNativeDefaultInjection first for its side effects of setting up
// the JS environment
var ReactNativeDefaultInjection = require('ReactNativeDefaultInjection');

var ReactCurrentOwner = require('ReactCurrentOwner');
var ReactElement = require('ReactElement');
var ReactInstanceHandles = require('ReactInstanceHandles');
var ReactNativeMount = require('ReactNativeMount');
var ReactUpdates = require('ReactUpdates');

var findNodeHandle = require('findNodeHandle');

ReactNativeDefaultInjection.inject();

var render = function(
  element: ReactElement,
  mountInto: number,
  callback?: ?(() => void)
): ?ReactComponent {
  return ReactNativeMount.renderComponent(element, mountInto, callback);
};

var ReactNative = {
  hasReactNativeInitialized: false,
  findNodeHandle: findNodeHandle,
  render: render,
  unmountComponentAtNode: ReactNativeMount.unmountComponentAtNode,

  /* eslint-disable camelcase */
  unstable_batchedUpdates: ReactUpdates.batchedUpdates,
  /* eslint-enable camelcase */

  unmountComponentAtNodeAndRemoveContainer: ReactNativeMount.unmountComponentAtNodeAndRemoveContainer,

  // Deprecations (remove for 0.13)
  renderComponent: function(
    element: ReactElement,
    mountInto: number,
    callback?: ?(() => void)
  ): ?ReactComponent {
    warning('Use React.render instead of React.renderComponent');
    return ReactNative.render(element, mountInto, callback);
  },
};

// Inject the runtime into a devtools global hook regardless of browser.
// Allows for debugging when the hook is injected on the page.
/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
  typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
  typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') {
  __REACT_DEVTOOLS_GLOBAL_HOOK__.inject({
    CurrentOwner: ReactCurrentOwner,
    InstanceHandles: ReactInstanceHandles,
    Mount: ReactNativeMount,
    Reconciler: require('ReactReconciler'),
    TextComponent: require('ReactNativeTextComponent'),
  });
}

module.exports = ReactNative;
<|endoftext|>


<commit_before>/**
 * tab-util.js
 */

import {getType, isString, sleep} from "./common.js";
import {
  getCurrentWindow, getSessionWindowValue, getTab, setSessionWindowValue,
  updateTab,
} from "./browser.js";
import {setTabContent} from "./tab-content.js";
import {
  CLASS_TAB_COLLAPSED, CLASS_TAB_CONTAINER, CLASS_TAB_GROUP,
  NEW_TAB, TAB_LIST, TAB_QUERY,
} from "./constant.js";

/* constants */
const TIME_3SEC = 3000;

/**
 * get template
 * @param {string} id - template ID
 * @returns {Object} - document fragment
 */
export const getTemplate = id => {
  const tmpl = document.getElementById(id);
  const {content: {firstElementChild}} = tmpl;
  return document.importNode(firstElementChild, true);
};

/**
 * get sidebar tab container from parent node
 * @param {Object} node - node
 * @returns {Object} - sidebar tab container
 */
export const getSidebarTabContainer = node => {
  let container;
  while (node && node.parentNode) {
    const {classList, parentNode} = node;
    if (classList.contains(CLASS_TAB_CONTAINER)) {
      container = node;
      break;
    }
    node = parentNode;
  }
  return container || null;
};

/**
 * restore sidebar tab container
 * @param {Object} container - tab container
 * @returns {void}
 */
export const restoreTabContainer = container => {
  if (container && container.nodeType === Node.ELEMENT_NODE) {
    const {childElementCount, classList, parentNode} = container;
    switch (childElementCount) {
      case 0:
        parentNode.removeChild(container);
        break;
      case 1:
        classList.remove(CLASS_TAB_GROUP);
        break;
      default:
    }
  }
};

/**
 * get sidebar tab from parent node
 * @param {Object} node - node
 * @returns {Object} - sidebar tab
 */
export const getSidebarTab = node => {
  let tab;
  while (node && node.parentNode) {
    const {dataset, parentNode} = node;
    if (dataset.tabId) {
      tab = node;
      break;
    }
    node = parentNode;
  }
  return tab || null;
};

/**
 * get sidebar tab ID
 * @param {Object} node - node
 * @returns {?number} - tab ID
 */
export const getSidebarTabId = node => {
  let tabId;
  while (node && node.parentNode) {
    const {dataset, parentNode} = node;
    if (dataset.tabId) {
      tabId = dataset.tabId * 1;
      break;
    }
    node = parentNode;
  }
  return tabId || null;
};

/**
 * get sidebar tab index
 * @param {Object} tab - tab
 * @returns {?number} - index
 */
export const getSidebarTabIndex = tab => {
  let index;
  if (tab && tab.nodeType === Node.ELEMENT_NODE) {
    const items = document.querySelectorAll(TAB_QUERY);
    const l = items.length;
    let i = 0;
    while (i < l && !Number.isInteger(index)) {
      if (items[i] === tab) {
        index = i;
        break;
      }
      i++;
    }
  }
  return Number.isInteger(index) ?
    index :
    null;
};

/**
 * get tabs in range
 * @param {Object} tabA - tab A
 * @param {Object} tabB - tab B
 * @returns {Array} - Array of tabs
 */
export const getTabsInRange = async (tabA, tabB) => {
  const tabAIndex = getSidebarTabIndex(tabA);
  const tabBIndex = getSidebarTabIndex(tabB);
  const arr = [];
  if (Number.isInteger(tabAIndex) && Number.isInteger(tabBIndex)) {
    const items = document.querySelectorAll(TAB_QUERY);
    let fromIndex, toIndex;
    if (tabAIndex > tabBIndex) {
      fromIndex = tabBIndex;
      toIndex = tabAIndex;
    } else {
      fromIndex = tabAIndex;
      toIndex = tabBIndex;
    }
    for (let i = fromIndex; i <= toIndex; i++) {
      arr.push(items[i]);
    }
  }
  return arr;
};

/**
 * get tab list from sessions
 * @param {string} key - key
 * @returns {Object} - tab list
 */
export const getSessionTabList = async key => {
  const win = await getCurrentWindow({
    populate: true,
  });
  let tabList;
  if (win && isString(key)) {
    const {id: windowId} = win;
    tabList = await getSessionWindowValue(key, windowId);
    if (tabList) {
      tabList = JSON.parse(tabList);
    }
  }
  return tabList || null;
};

/**
 * set tab list to sessions
 * @returns {void}
 */
export const setSessionTabList = async () => {
  const win = await getCurrentWindow({
    populate: true,
  });
  if (win) {
    const {id: windowId, incognito} = win;
    const tabLength = document.querySelectorAll(TAB_QUERY).length;
    if (!incognito && tabLength) {
      const tabList = {};
      const items =
        document.querySelectorAll(`.${CLASS_TAB_CONTAINER}:not(#${NEW_TAB})`);
      const l = items.length;
      let i = 0;
      while (i < l) {
        const item = items[i];
        const collapsed = item.classList.contains(CLASS_TAB_COLLAPSED);
        const childTabs = item.querySelectorAll(TAB_QUERY);
        for (const tab of childTabs) {
          const tabsTab = tab.dataset && tab.dataset.tab;
          if (tabsTab) {
            const {url} = JSON.parse(tabsTab);
            const tabIndex = getSidebarTabIndex(tab);
            if (Number.isInteger(tabIndex)) {
              tabList[tabIndex] = {
                collapsed, url,
                containerIndex: i,
              };
            }
          }
        }
        i++;
      }
      await setSessionWindowValue(TAB_LIST, JSON.stringify(tabList), windowId);
    }
  }
};

/**
 * activate tab
 * @param {Object} elm - element
 * @returns {?AsyncFunction} - updateTab()
 */
export const activateTab = async elm => {
  const tabId = getSidebarTabId(elm);
  let func;
  if (Number.isInteger(tabId)) {
    const active = true;
    func = updateTab(tabId, {active});
  }
  return func || null;
};

/**
 * observe tab
 * @param {number} tabId - tab ID
 * @returns {Promise.<Array>} - results of each handler
 */
export const observeTab = async tabId => {
  if (!Number.isInteger(tabId)) {
    throw new TypeError(`Expected Number but got ${getType(tabId)}.`);
  }
  await sleep(TIME_3SEC);
  const tabsTab = await getTab(tabId);
  const func = [];
  if (tabsTab) {
    const {status, id} = tabsTab;
    if (status === "complete") {
      await setTabContent(document.querySelector(`[data-tab-id="${id}"]`),
                          tabsTab);
      func.push(setSessionTabList());
    } else {
      func.push(observeTab(id));
    }
  }
  return Promise.all(func);
};
<commit_msg>Move functions to tab util<commit_after>/**
 * tab-util.js
 */

import {getType, isString, sleep} from "./common.js";
import {
  createBookmark, createTab, getCurrentWindow, getSessionWindowValue, getTab,
  reloadTab, removeTab, setSessionWindowValue, updateTab,
} from "./browser.js";
import {setTabContent} from "./tab-content.js";
import {
  CLASS_TAB_COLLAPSED, CLASS_TAB_CONTAINER, CLASS_TAB_GROUP,
  NEW_TAB, TAB_LIST, TAB_QUERY,
} from "./constant.js";

/* api */
const {windows} = browser;

/* constants */
const TIME_3SEC = 3000;

/**
 * get template
 * @param {string} id - template ID
 * @returns {Object} - document fragment
 */
export const getTemplate = id => {
  const tmpl = document.getElementById(id);
  const {content: {firstElementChild}} = tmpl;
  return document.importNode(firstElementChild, true);
};

/**
 * get sidebar tab container from parent node
 * @param {Object} node - node
 * @returns {Object} - sidebar tab container
 */
export const getSidebarTabContainer = node => {
  let container;
  while (node && node.parentNode) {
    const {classList, parentNode} = node;
    if (classList.contains(CLASS_TAB_CONTAINER)) {
      container = node;
      break;
    }
    node = parentNode;
  }
  return container || null;
};

/**
 * restore sidebar tab container
 * @param {Object} container - tab container
 * @returns {void}
 */
export const restoreTabContainer = container => {
  if (container && container.nodeType === Node.ELEMENT_NODE) {
    const {childElementCount, classList, parentNode} = container;
    switch (childElementCount) {
      case 0:
        parentNode.removeChild(container);
        break;
      case 1:
        classList.remove(CLASS_TAB_GROUP);
        break;
      default:
    }
  }
};

/**
 * get sidebar tab from parent node
 * @param {Object} node - node
 * @returns {Object} - sidebar tab
 */
export const getSidebarTab = node => {
  let tab;
  while (node && node.parentNode) {
    const {dataset, parentNode} = node;
    if (dataset.tabId) {
      tab = node;
      break;
    }
    node = parentNode;
  }
  return tab || null;
};

/**
 * get sidebar tab ID
 * @param {Object} node - node
 * @returns {?number} - tab ID
 */
export const getSidebarTabId = node => {
  let tabId;
  while (node && node.parentNode) {
    const {dataset, parentNode} = node;
    if (dataset.tabId) {
      tabId = dataset.tabId * 1;
      break;
    }
    node = parentNode;
  }
  return tabId || null;
};

/**
 * get sidebar tab index
 * @param {Object} tab - tab
 * @returns {?number} - index
 */
export const getSidebarTabIndex = tab => {
  let index;
  if (tab && tab.nodeType === Node.ELEMENT_NODE) {
    const items = document.querySelectorAll(TAB_QUERY);
    const l = items.length;
    let i = 0;
    while (i < l && !Number.isInteger(index)) {
      if (items[i] === tab) {
        index = i;
        break;
      }
      i++;
    }
  }
  return Number.isInteger(index) ?
    index :
    null;
};

/**
 * get tabs in range
 * @param {Object} tabA - tab A
 * @param {Object} tabB - tab B
 * @returns {Array} - Array of tabs
 */
export const getTabsInRange = async (tabA, tabB) => {
  const tabAIndex = getSidebarTabIndex(tabA);
  const tabBIndex = getSidebarTabIndex(tabB);
  const arr = [];
  if (Number.isInteger(tabAIndex) && Number.isInteger(tabBIndex)) {
    const items = document.querySelectorAll(TAB_QUERY);
    let fromIndex, toIndex;
    if (tabAIndex > tabBIndex) {
      fromIndex = tabBIndex;
      toIndex = tabAIndex;
    } else {
      fromIndex = tabAIndex;
      toIndex = tabBIndex;
    }
    for (let i = fromIndex; i <= toIndex; i++) {
      arr.push(items[i]);
    }
  }
  return arr;
};

/**
 * get tab list from sessions
 * @param {string} key - key
 * @returns {Object} - tab list
 */
export const getSessionTabList = async key => {
  const win = await getCurrentWindow({
    populate: true,
  });
  let tabList;
  if (win && isString(key)) {
    const {id: windowId} = win;
    tabList = await getSessionWindowValue(key, windowId);
    if (tabList) {
      tabList = JSON.parse(tabList);
    }
  }
  return tabList || null;
};

/**
 * set tab list to sessions
 * @returns {void}
 */
export const setSessionTabList = async () => {
  const win = await getCurrentWindow({
    populate: true,
  });
  if (win) {
    const {id: windowId, incognito} = win;
    const tabLength = document.querySelectorAll(TAB_QUERY).length;
    if (!incognito && tabLength) {
      const tabList = {};
      const items =
        document.querySelectorAll(`.${CLASS_TAB_CONTAINER}:not(#${NEW_TAB})`);
      const l = items.length;
      let i = 0;
      while (i < l) {
        const item = items[i];
        const collapsed = item.classList.contains(CLASS_TAB_COLLAPSED);
        const childTabs = item.querySelectorAll(TAB_QUERY);
        for (const tab of childTabs) {
          const tabsTab = tab.dataset && tab.dataset.tab;
          if (tabsTab) {
            const {url} = JSON.parse(tabsTab);
            const tabIndex = getSidebarTabIndex(tab);
            if (Number.isInteger(tabIndex)) {
              tabList[tabIndex] = {
                collapsed, url,
                containerIndex: i,
              };
            }
          }
        }
        i++;
      }
      await setSessionWindowValue(TAB_LIST, JSON.stringify(tabList), windowId);
    }
  }
};

/**
 * activate tab
 * @param {Object} elm - element
 * @returns {?AsyncFunction} - updateTab()
 */
export const activateTab = async elm => {
  const tabId = getSidebarTabId(elm);
  let func;
  if (Number.isInteger(tabId)) {
    const active = true;
    func = updateTab(tabId, {active});
  }
  return func || null;
};

/**
 * observe tab
 * @param {number} tabId - tab ID
 * @returns {Promise.<Array>} - results of each handler
 */
export const observeTab = async tabId => {
  if (!Number.isInteger(tabId)) {
    throw new TypeError(`Expected Number but got ${getType(tabId)}.`);
  }
  await sleep(TIME_3SEC);
  const tabsTab = await getTab(tabId);
  const func = [];
  if (tabsTab) {
    const {status, id} = tabsTab;
    if (status === "complete") {
      await setTabContent(document.querySelector(`[data-tab-id="${id}"]`),
                          tabsTab);
      func.push(setSessionTabList());
    } else {
      func.push(observeTab(id));
    }
  }
  return Promise.all(func);
};

/* bookmark */
/**
 * bookmark all tabs
 * @returns {Promise.<Array>} - results of each handler
 */
export const bookmarkAllTabs = async () => {
  const func = [];
  const items = document.querySelectorAll(TAB_QUERY);
  for (const item of items) {
    const {dataset} = item;
    const itemTab = dataset && dataset.tab && JSON.parse(dataset.tab);
    const {title, url} = itemTab;
    func.push(createBookmark({title, url}));
  }
  return Promise.all(func);
};

/**
 * bookmark tabs
 * @param {Object} nodes - node list
 * @returns {Promise.<Array>} - results of each handler
 */
export const bookmarkTabs = async nodes => {
  const func = [];
  if (nodes instanceof NodeList) {
    for (const item of nodes) {
      if (item.nodeType === Node.ELEMENT_NODE) {
        const {dataset} = item;
        const itemTab = dataset && dataset.tab && JSON.parse(dataset.tab);
        if (itemTab) {
          const {title, url} = itemTab;
          func.push(createBookmark({title, url}));
        }
      }
    }
  }
  return Promise.all(func);
};

/* close */
/**
 * close other tabs
 * @param {Array} tabIds - array of tab ID
 * @returns {?AsyncFunction} - removeTab()
 */
export const closeOtherTabs = async tabIds => {
  if (!Array.isArray(tabIds)) {
    throw new TypeError(`Expected Array but got ${getType(tabIds)}`);
  }
  let func;
  const items = document.querySelectorAll(TAB_QUERY);
  const arr = [];
  for (const item of items) {
    if (item.nodeType === Node.ELEMENT_NODE) {
      const {dataset} = item;
      const itemId = dataset && dataset.tabId && dataset.tabId * 1;
      if (Number.isInteger(itemId) && !tabIds.includes(itemId)) {
        arr.push(itemId);
      }
    }
  }
  if (arr.length) {
    func = removeTab(arr);
  }
  return func || null;
};

/**
 * close tabs
 * @param {Object} nodes - node list
 * @returns {?AsyncFunction} - removeTab()
 */
export const closeTabs = async nodes => {
  let func;
  if (nodes instanceof NodeList) {
    const arr = [];
    for (const item of nodes) {
      if (item.nodeType === Node.ELEMENT_NODE) {
        const {dataset} = item;
        const tabId = dataset && dataset.tabId && dataset.tabId * 1;
        if (Number.isInteger(tabId)) {
          arr.push(tabId);
        }
      }
    }
    if (arr.length) {
      func = removeTab(arr);
    }
  }
  return func || null;
};

/* dupe */
/**
 * duplicate tab
 * @param {number} tabId - tab ID
 * @param {number} windowId - window ID
 * @returns {?AsyncFunction} - createTab()
 */
export const dupeTab = async (tabId, windowId) => {
  if (!Number.isInteger(tabId)) {
    throw new TypeError(`Expected Number but got ${getType(tabId)}`);
  }
  if (!Number.isInteger(windowId)) {
    windowId = windows.WINDOW_ID_CURRENT;
  }
  let func;
  const tabsTab = await getTab(tabId);
  if (tabsTab) {
    const {index, url} = tabsTab;
    const opt = {
      url, windowId,
      active: true,
      index: index + 1,
      openerTabId: tabId,
    };
    func = createTab(opt);
  }
  return func || null;
};

/* mute */
/**
 * mute tabs
 * @param {Object} nodes - node list
 * @param {boolean} muted - muted
 * @returns {Promise.<Array>} - results of each handler
 */
export const muteTabs = async (nodes, muted) => {
  const func = [];
  if (nodes instanceof NodeList) {
    for (const item of nodes) {
      if (item.nodeType === Node.ELEMENT_NODE) {
        const {dataset} = item;
        const tabId = dataset && dataset.tabId && dataset.tabId * 1;
        if (Number.isInteger(tabId)) {
          func.push(updateTab(tabId, {muted: !!muted}));
        }
      }
    }
  }
  return Promise.all(func);
};

/* pin */
/**
 * pin tabs
 * @param {Object} nodes - node list
 * @param {boolean} pinned - pinned
 * @returns {Promise.<Array>} - results of each handler
 */
export const pinTabs = async (nodes, pinned) => {
  const func = [];
  if (nodes instanceof NodeList) {
    for (const item of nodes) {
      if (item.nodeType === Node.ELEMENT_NODE) {
        const {dataset} = item;
        const tabId = dataset && dataset.tabId && dataset.tabId * 1;
        if (Number.isInteger(tabId)) {
          func.push(updateTab(tabId, {pinned: !!pinned}));
        }
      }
    }
  }
  return Promise.all(func);
};

/* reload */
/**
 * reload all tabs
 * @returns {Promise.<Array>} - results of each handler
 */
export const reloadAllTabs = async () => {
  const func = [];
  const items = document.querySelectorAll(TAB_QUERY);
  for (const item of items) {
    const {dataset} = item;
    const itemId = dataset && dataset.tabId && dataset.tabId * 1;
    if (Number.isInteger(itemId)) {
      func.push(reloadTab(itemId));
    }
  }
  return Promise.all(func);
};

/**
 * reload tabs
 * @param {Object} nodes - node list
 * @returns {Promise.<Array>} - results of each handler
 */
export const reloadTabs = async nodes => {
  const func = [];
  if (nodes instanceof NodeList) {
    for (const item of nodes) {
      if (item.nodeType === Node.ELEMENT_NODE) {
        const {dataset} = item;
        const itemId = dataset && dataset.tabId && dataset.tabId * 1;
        if (Number.isInteger(itemId)) {
          func.push(reloadTab(itemId));
        }
      }
    }
  }
  return Promise.all(func);
};
<|endoftext|>


<commit_before><commit_msg>fix all stock and price<commit_after><|endoftext|>


<commit_before>/**
 * The Forest2000 layer module for use on canvas.
 *
 * @return ForestLayer class (extends CanvasLayerClass)
 */
define([
  'd3',
  'uri',
  'abstract/layer/CanvasLayerClass',
  'map/presenters/layers/TerraiCanvasLayerPresenter'
], function(d3,UriTemplate, CanvasLayerClass, Presenter) {

  'use strict';

  var TerraiCanvasLayer = CanvasLayerClass.extend({

    options: {
      threshold: 30,
      dataMaxZoom: 11,
      //ATTENTION: check config.ru file to get the whole route, reverse proxying here
      //urlTemplate: '/latin-america/Z{z}/{y}/{x}.png'
      urlTemplate: 'https://s3.amazonaws.com/wri-tiles/latin_decrease_current_15_jun_2015/{z}/{x}/{y}.png'

    },

    init: function(layer, options, map) {
      this.presenter = new Presenter(this);
      this.currentDate = options.currentDate || [moment(layer.mindate), moment(layer.maxdate)];
      this._super(layer, options, map);
      this.top_date = (layer.maxdate.year()-2004)*23+Math.floor(layer.maxdate.dayOfYear()/16);
      this.top_date -= 16;
    },

    /**
     * Filters the canvas imgdata.
     * @override
     */
    filterCanvasImgdata: function(imgdata, w, h) {
      var components = 4;
      var start = (moment(this.currentDate[0]).year()-2004)*23+Math.floor(moment(this.currentDate[0]).dayOfYear()/16);
      var end   = (moment(this.currentDate[1]).year()-2004)*23+Math.floor(moment(this.currentDate[1]).dayOfYear()/16);

      for(var i=0; i < w; ++i) {
        for(var j=0; j < h; ++j) {
          var pixelPos = (j*w + i) * components;
       // var r = imgdata[pixelPos]; //left here for coherence
          var g = imgdata[pixelPos+1];
          var b = imgdata[pixelPos+2];
          // var timeLoss = b+(256*g); //old method, just in case
          var timeLoss = b+g;

          if (timeLoss > start && timeLoss < end) {
            imgdata[pixelPos]     = 220;
            imgdata[pixelPos + 1] = 102;
            imgdata[pixelPos + 2] = 153;
            //imgdata[pixelPos + 3] = 256;
            if (timeLoss > this.top_date) {
              imgdata[pixelPos]     = 233;
              imgdata[pixelPos + 1] = 189;
              imgdata[pixelPos + 2] = 21;
            }
          } else {
            imgdata[pixelPos + 3] = 0;
          }
        }
      } //end first for loop
    },

    /**
     * Used by TerraiCanvasLayerPresenter to set the dates for the tile.
     *
     * @param {Array} date 2D array of moment dates [begin, end]
     */
    setTimelineDate: function(date) {
      this.currentDate = date;
      this.updateTiles();
    },
  });

  return TerraiCanvasLayer;

});
<commit_msg>Terra i endpoint<commit_after>/**
 * The Forest2000 layer module for use on canvas.
 *
 * @return ForestLayer class (extends CanvasLayerClass)
 */
define([
  'd3',
  'uri',
  'abstract/layer/CanvasLayerClass',
  'map/presenters/layers/TerraiCanvasLayerPresenter'
], function(d3,UriTemplate, CanvasLayerClass, Presenter) {

  'use strict';

  var TerraiCanvasLayer = CanvasLayerClass.extend({

    options: {
      threshold: 30,
      dataMaxZoom: 11,
      //ATTENTION: check config.ru file to get the whole route, reverse proxying here
      //urlTemplate: '/latin-america/Z{z}/{y}/{x}.png'
      urlTemplate: 'https://s3.amazonaws.com/wri-tiles/latin-decrease-current/{z}/{x}/{y}.png'

    },

    init: function(layer, options, map) {
      this.presenter = new Presenter(this);
      this.currentDate = options.currentDate || [moment(layer.mindate), moment(layer.maxdate)];
      this._super(layer, options, map);
      this.top_date = (layer.maxdate.year()-2004)*23+Math.floor(layer.maxdate.dayOfYear()/16);
      this.top_date -= 16;
    },

    /**
     * Filters the canvas imgdata.
     * @override
     */
    filterCanvasImgdata: function(imgdata, w, h) {
      var components = 4;
      var start = (moment(this.currentDate[0]).year()-2004)*23+Math.floor(moment(this.currentDate[0]).dayOfYear()/16);
      var end   = (moment(this.currentDate[1]).year()-2004)*23+Math.floor(moment(this.currentDate[1]).dayOfYear()/16);

      for(var i=0; i < w; ++i) {
        for(var j=0; j < h; ++j) {
          var pixelPos = (j*w + i) * components;
       // var r = imgdata[pixelPos]; //left here for coherence
          var g = imgdata[pixelPos+1];
          var b = imgdata[pixelPos+2];
          // var timeLoss = b+(256*g); //old method, just in case
          var timeLoss = b+g;

          if (timeLoss > start && timeLoss < end) {
            imgdata[pixelPos]     = 220;
            imgdata[pixelPos + 1] = 102;
            imgdata[pixelPos + 2] = 153;
            // imgdata[pixelPos + 3] = 256;
            if (timeLoss > this.top_date) {
              imgdata[pixelPos]     = 233;
              imgdata[pixelPos + 1] = 189;
              imgdata[pixelPos + 2] = 21;
            }
          } else {
            imgdata[pixelPos + 3] = 0;
          }
        }
      } //end first for loop
    },

    /**
     * Used by TerraiCanvasLayerPresenter to set the dates for the tile.
     *
     * @param {Array} date 2D array of moment dates [begin, end]
     */
    setTimelineDate: function(date) {
      this.currentDate = date;
      this.updateTiles();
    },
  });

  return TerraiCanvasLayer;

});
<|endoftext|>


<commit_before>'use strict';

// TODO: inject an entity service, and use it to get the entity object
angular.module('memexLinkerApp')
  .controller('EntitydetailCtrl', function ($scope, $http, $stateParams, lodash, Auth) {

    // console.log('Logged in? ' + Auth.isLoggedIn());
    // if (Auth.isLoggedIn()) {
    //     console.log(Auth.getCurrentUser().name);
    // }

    $scope.blur = true;
    $scope.ads = [];
    //$scope.photos = [];

    $scope.imageUrls = [];

    $scope.suggestedAds = [];
    $scope.id = $stateParams.id;

    $scope.entity = {
        phone:'',
        cities:[],
        ages:[],
        ethnicities:[],
        heights:[]
    };

    $scope.getHost = function (url) {
        var parser = document.createElement('a');
        parser.href = url;
        return parser.host;
    };

    $http.get('/api/entities/' + $scope.id).success(function(res) {
        $scope.entity.phone = res._node._data.data.identifier;
    });

    $http.get('api/entities/' + $scope.id + '/byphone').success(function(res){
        $scope.ads = lodash.map(res, function(element){
            //console.log(element);
            var nodeData = element.ad._data.data;
            var nodeMetaData = element.ad._data.metadata;
            return {
              'id': nodeMetaData.id,
              'data' : nodeData
            };
        });
        updateEntity();

    });

    $http.get('api/entities/' + $scope.id + '/byimage').success(function(res){
        $scope.suggestedAds = lodash.map(res, function(element){
            var nodeData = element.ad._data.data;
            var nodeMetaData = element.ad._data.metadata;
            return {
              'id': nodeMetaData.id,
              'data' : nodeData
            };
        });
        updateEntity();
    });

    function updateEntity() {
        console.log($scope.ads);
        $scope.entity.ages = lodash.uniq(
            lodash.map($scope.ads, function(ad) {
                return ad.data.age;
            })
        );
        $scope.entity.cities = lodash.uniq(
            lodash.map($scope.ads, function(ad) {
                return ad.data.city;
            })
        );
        $scope.entity.ethnicities = lodash.uniq(
            lodash.map($scope.ads, function(ad) {
                return ad.data.ethnicity;
            })
        );

        $scope.imageUrls = lodash.flatten(
              lodash.map($scope.ads, function(ad) {
                return ad.data.image_locations;
              }),
              true
            );
        $scope.imageUrls = lodash.filter($scope.imageUrls, function(element){
          return ! lodash.isUndefined(element);
        });
    }

  });
<commit_msg>minor cleanup<commit_after>'use strict';

// TODO: inject an entity service, and use it to get the entity object
angular.module('memexLinkerApp')
.controller('EntitydetailCtrl', function ($scope, $http, $stateParams, lodash, Auth) {

    console.log('Logged in? ' + Auth.isLoggedIn());
    if (Auth.isLoggedIn()) {
        console.log(Auth.getCurrentUser().name);
    }

    $scope.blur = true;
    $scope.ads = [];
    //$scope.photos = [];

    $scope.imageUrls = [];

    $scope.suggestedAds = [];
    $scope.id = $stateParams.id;

    $scope.entity = {
        phone:'',
        cities:[],
        ages:[],
        ethnicities:[],
        heights:[]
    };

    $scope.getHost = function (url) {
        var parser = document.createElement('a');
        parser.href = url;
        return parser.host;
    };

    $http.get('/api/entities/' + $scope.id).success(function(res) {
        $scope.entity.phone = res._node._data.data.identifier;
    });

    $http.get('api/entities/' + $scope.id + '/byphone').success(function(res){
        $scope.ads = lodash.map(res, function(element){
            //console.log(element);
            var nodeData = element.ad._data.data;
            var nodeMetaData = element.ad._data.metadata;
            return {
              'id': nodeMetaData.id,
              'data' : nodeData,
              'metaData' : nodeMetaData
          };
      });
        updateEntity();

    });

    $http.get('api/entities/' + $scope.id + '/byimage').success(function(res){
        $scope.suggestedAds = lodash.map(res, function(element){
            var nodeData = element.ad._data.data;
            var nodeMetaData = element.ad._data.metadata;
            return {
              'id': nodeMetaData.id,
              'data' : nodeData
          };
      });
        updateEntity();
    });

    function updateEntity() {
        console.log($scope.ads);
        $scope.entity.ages = lodash.uniq(
            lodash.map($scope.ads, function(ad) {
                return ad.data.age;
            })
            );
        $scope.entity.cities = lodash.uniq(
            lodash.map($scope.ads, function(ad) {
                return ad.data.city;
            })
            );
        $scope.entity.ethnicities = lodash.uniq(
            lodash.map($scope.ads, function(ad) {
                return ad.data.ethnicity;
            })
            );

        $scope.imageUrls = lodash.flatten(
          lodash.map($scope.ads, function(ad) {
            return ad.data.image_locations;
        }),
          true
          );
        $scope.imageUrls = lodash.filter($scope.imageUrls, function(element){
          return ! lodash.isUndefined(element);
      });
    }

});
<|endoftext|>


<commit_before>
'use strict';

const os = require('os');
const https = require('https');
const proc = require('child_process');
const StateController = require('../../lib/state-controller');
const OSXSupport = require('../../lib/support/osx');

const {
  fakeProcesses, fakeKiteInstallPaths, fakeResponse,
  withKiteInstalled, withKiteRunning, withKiteNotRunning,
  withFakeServer,
} = require('../spec-helpers.js');

describe('StateController - OSX Support', () => {
  beforeEach(() => {
    spyOn(os, 'platform').andReturn('darwin');
    spyOn(os, 'release').andReturn('14.0.0');
  });

  fakeKiteInstallPaths();

  describe('.isKiteSupported()', () => {
    it('returns a resolved promise', () => {
      waitsForPromise(() => StateController.isKiteSupported());
    });

    describe('when the os release is below 10.10', () => {
      beforeEach(() => {
        os.release.andReturn('13.0.0');
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.isKiteSupported());
      });
    });
  });

  describe('.isKiteInstalled()', () => {
    withKiteInstalled(() => {
      it('returns a resolved promise', () => {
        waitsForPromise(() => StateController.isKiteInstalled());
      });
    });

    describe('when there is no file at the given path', () => {
      it('returns a rejected promise', () => {
        waitsForPromise({
          shouldReject: true,
        }, () => StateController.isKiteInstalled());
      });
    });
  });

  describe('.installKite()', () => {
    describe('when every command succeeds', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: () => 0,
          cp: () => 0,
          rm: () => 0,
        });
      });

      it('returns a resolved promise', () => {
        const options = {
          onInstallStart: jasmine.createSpy(),
          onMount: jasmine.createSpy(),
          onCopy: jasmine.createSpy(),
          onUnmount: jasmine.createSpy(),
          onRemove: jasmine.createSpy(),
        };

        waitsForPromise(() => StateController.installKite(options));
        runs(() => {
          expect(proc.spawn).toHaveBeenCalledWith('hdiutil', [
            'attach', '-nobrowse',
            OSXSupport.KITE_DMG_PATH,
          ]);
          expect(proc.spawn).toHaveBeenCalledWith('cp', [
            '-r',
            OSXSupport.KITE_APP_PATH.mounted,
            OSXSupport.APPS_PATH,
          ]);
          expect(proc.spawn).toHaveBeenCalledWith('hdiutil', [
            'detach',
            OSXSupport.KITE_VOLUME_PATH,
          ]);
          expect(proc.spawn).toHaveBeenCalledWith('rm', [
            OSXSupport.KITE_DMG_PATH,
          ]);

          expect(options.onInstallStart).toHaveBeenCalled();
          expect(options.onMount).toHaveBeenCalled();
          expect(options.onCopy).toHaveBeenCalled();
          expect(options.onUnmount).toHaveBeenCalled();
          expect(options.onRemove).toHaveBeenCalled();
        });
      });
    });

    describe('when mounting the archive fails', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: () => 1,
          cp: () => 0,
          rm: () => 0,
        });
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.installKite());
      });
    });

    describe('when copying the archive content fails', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: () => 0,
          cp: () => 1,
          rm: () => 0,
        });
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.installKite());
      });
    });

    describe('when unmounting the archive fails', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: (ps, [command]) => command === 'attach' ? 0 : 1,
          cp: () => 0,
          rm: () => 0,
        });
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.installKite());
      });
    });

    describe('when removing the downloaded archive fails', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: () => 0,
          cp: () => 0,
          rm: () => 1,
        });
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.installKite());
      });
    });
  });

  describe('.downloadKite()', () => {
    withFakeServer([
      [
        o => /^https:\/\/alpha\.kite\.com/.test(o),
        o => fakeResponse(303, '', {headers: {location: 'https://download.kite.com'}}),
      ], [
        o => /^https:\/\/download\.kite\.com/.test(o),
        o => fakeResponse(200, 'foo'),
      ],
    ], () => {
      describe('when the download succeeds', () => {
        beforeEach(() => {
          fakeProcesses({
            hdiutil: () => 0,
            cp: () => 0,
            rm: () => 0,
          });
        });

        describe('with the install option', () => {
          it('returns a promise resolved after the install', () => {
            const options = {
              install: true,
              onDownload: jasmine.createSpy(),
              onInstallStart: jasmine.createSpy(),
              onMount: jasmine.createSpy(),
              onCopy: jasmine.createSpy(),
              onUnmount: jasmine.createSpy(),
              onRemove: jasmine.createSpy(),
            };
            const url = 'http://kite.com/download';

            waitsForPromise(() => StateController.downloadKite(url, options));
            runs(() => {
              expect(https.request).toHaveBeenCalledWith('https://download.kite.com');
              expect(proc.spawn).toHaveBeenCalledWith('hdiutil', [
                'attach', '-nobrowse',
                OSXSupport.KITE_DMG_PATH,
              ]);
              expect(proc.spawn).toHaveBeenCalledWith('cp', [
                '-r',
                OSXSupport.KITE_APP_PATH.mounted,
                OSXSupport.APPS_PATH,
              ]);
              expect(proc.spawn).toHaveBeenCalledWith('hdiutil', [
                'detach',
                OSXSupport.KITE_VOLUME_PATH,
              ]);
              expect(proc.spawn).toHaveBeenCalledWith('rm', [
                OSXSupport.KITE_DMG_PATH,
              ]);

              expect(options.onDownload).toHaveBeenCalled();
              expect(options.onInstallStart).toHaveBeenCalled();
              expect(options.onMount).toHaveBeenCalled();
              expect(options.onCopy).toHaveBeenCalled();
              expect(options.onUnmount).toHaveBeenCalled();
              expect(options.onRemove).toHaveBeenCalled();
            });
          });
        });
      });
    });
  });

  describe('.isKiteRunning()', () => {
    describe('when kite is not installed', () => {
      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.isKiteRunning());
      });
    });

    withKiteInstalled(() => {
      describe('but not running', () => {
        beforeEach(() => {
          fakeProcesses({
            '/bin/ps': (ps) => {
              ps.stdout('');
              return 0;
            },
          });
        });

        it('returns a rejected promise', () => {
          waitsForPromise({shouldReject: true}, () => StateController.isKiteRunning());
        });
      });

      withKiteRunning(() => {
        it('returns a resolved promise', () => {
          waitsForPromise(() => StateController.isKiteRunning());
        });
      });
    });
  });

  describe('.canRunKite()', () => {
    describe('when kite is not installed', () => {
      it('returns a rejected function', () => {
        waitsForPromise({shouldReject: true}, () => StateController.canRunKite());
      });
    });

    withKiteInstalled(() => {
      describe('but not running', () => {
        beforeEach(() => {
          fakeProcesses({
            '/bin/ps': (ps) => {
              ps.stdout('');
              return 0;
            },
          });
        });

        it('returns a resolved promise', () => {
          waitsForPromise(() => StateController.canRunKite());
        });
      });

      withKiteRunning(() => {
        it('returns a rejected function', () => {
          waitsForPromise({shouldReject: true}, () => StateController.canRunKite());
        });
      });
    });
  });

  describe('.runKite()', () => {
    describe('when kite is not installed', () => {
      it('returns a rejected function', () => {
        waitsForPromise({shouldReject: true}, () => StateController.runKite());
      });
    });

    withKiteInstalled(() => {
      withKiteRunning(() => {
        it('returns a rejected function', () => {
          waitsForPromise({shouldReject: true}, () => StateController.runKite());
        });
      });

      withKiteNotRunning(() => {
        it('returns a resolved promise', () => {
          waitsForPromise(() => StateController.runKite());
          runs(() => {
            expect(proc.spawn).toHaveBeenCalledWith('defaults', [
              'write', 'com.kite.Kite', 'shouldReopenSidebar', '0',
            ]);

            expect(proc.spawn).toHaveBeenCalledWith('open', [
              '-a', OSXSupport.KITE_APP_PATH.installed,
            ]);
          });
        });
      });
    });
  });
});
<commit_msg>Properly use test helpers<commit_after>
'use strict';

const os = require('os');
const https = require('https');
const proc = require('child_process');
const StateController = require('../../lib/state-controller');
const OSXSupport = require('../../lib/support/osx');

const {
  fakeProcesses, fakeKiteInstallPaths, fakeResponse,
  withKiteInstalled, withKiteRunning, withKiteNotRunning,
  withFakeServer,
} = require('../spec-helpers.js');

describe('StateController - OSX Support', () => {
  beforeEach(() => {
    spyOn(os, 'platform').andReturn('darwin');
    spyOn(os, 'release').andReturn('14.0.0');
  });

  fakeKiteInstallPaths();

  describe('.isKiteSupported()', () => {
    it('returns a resolved promise', () => {
      waitsForPromise(() => StateController.isKiteSupported());
    });

    describe('when the os release is below 10.10', () => {
      beforeEach(() => {
        os.release.andReturn('13.0.0');
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.isKiteSupported());
      });
    });
  });

  describe('.isKiteInstalled()', () => {
    withKiteInstalled(() => {
      it('returns a resolved promise', () => {
        waitsForPromise(() => StateController.isKiteInstalled());
      });
    });

    describe('when there is no file at the given path', () => {
      it('returns a rejected promise', () => {
        waitsForPromise({
          shouldReject: true,
        }, () => StateController.isKiteInstalled());
      });
    });
  });

  describe('.installKite()', () => {
    describe('when every command succeeds', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: () => 0,
          cp: () => 0,
          rm: () => 0,
        });
      });

      it('returns a resolved promise', () => {
        const options = {
          onInstallStart: jasmine.createSpy(),
          onMount: jasmine.createSpy(),
          onCopy: jasmine.createSpy(),
          onUnmount: jasmine.createSpy(),
          onRemove: jasmine.createSpy(),
        };

        waitsForPromise(() => StateController.installKite(options));
        runs(() => {
          expect(proc.spawn).toHaveBeenCalledWith('hdiutil', [
            'attach', '-nobrowse',
            OSXSupport.KITE_DMG_PATH,
          ]);
          expect(proc.spawn).toHaveBeenCalledWith('cp', [
            '-r',
            OSXSupport.KITE_APP_PATH.mounted,
            OSXSupport.APPS_PATH,
          ]);
          expect(proc.spawn).toHaveBeenCalledWith('hdiutil', [
            'detach',
            OSXSupport.KITE_VOLUME_PATH,
          ]);
          expect(proc.spawn).toHaveBeenCalledWith('rm', [
            OSXSupport.KITE_DMG_PATH,
          ]);

          expect(options.onInstallStart).toHaveBeenCalled();
          expect(options.onMount).toHaveBeenCalled();
          expect(options.onCopy).toHaveBeenCalled();
          expect(options.onUnmount).toHaveBeenCalled();
          expect(options.onRemove).toHaveBeenCalled();
        });
      });
    });

    describe('when mounting the archive fails', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: () => 1,
          cp: () => 0,
          rm: () => 0,
        });
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.installKite());
      });
    });

    describe('when copying the archive content fails', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: () => 0,
          cp: () => 1,
          rm: () => 0,
        });
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.installKite());
      });
    });

    describe('when unmounting the archive fails', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: (ps, [command]) => command === 'attach' ? 0 : 1,
          cp: () => 0,
          rm: () => 0,
        });
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.installKite());
      });
    });

    describe('when removing the downloaded archive fails', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: () => 0,
          cp: () => 0,
          rm: () => 1,
        });
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.installKite());
      });
    });
  });

  describe('.downloadKite()', () => {
    withFakeServer([
      [
        o => /^https:\/\/alpha\.kite\.com/.test(o),
        o => fakeResponse(303, '', {headers: {location: 'https://download.kite.com'}}),
      ], [
        o => /^https:\/\/download\.kite\.com/.test(o),
        o => fakeResponse(200, 'foo'),
      ],
    ], () => {
      describe('when the download succeeds', () => {
        beforeEach(() => {
          fakeProcesses({
            hdiutil: () => 0,
            cp: () => 0,
            rm: () => 0,
          });
        });

        describe('with the install option', () => {
          it('returns a promise resolved after the install', () => {
            const options = {
              install: true,
              onDownload: jasmine.createSpy(),
              onInstallStart: jasmine.createSpy(),
              onMount: jasmine.createSpy(),
              onCopy: jasmine.createSpy(),
              onUnmount: jasmine.createSpy(),
              onRemove: jasmine.createSpy(),
            };
            const url = 'http://kite.com/download';

            waitsForPromise(() => StateController.downloadKite(url, options));
            runs(() => {
              expect(https.request).toHaveBeenCalledWith('https://download.kite.com');
              expect(proc.spawn).toHaveBeenCalledWith('hdiutil', [
                'attach', '-nobrowse',
                OSXSupport.KITE_DMG_PATH,
              ]);
              expect(proc.spawn).toHaveBeenCalledWith('cp', [
                '-r',
                OSXSupport.KITE_APP_PATH.mounted,
                OSXSupport.APPS_PATH,
              ]);
              expect(proc.spawn).toHaveBeenCalledWith('hdiutil', [
                'detach',
                OSXSupport.KITE_VOLUME_PATH,
              ]);
              expect(proc.spawn).toHaveBeenCalledWith('rm', [
                OSXSupport.KITE_DMG_PATH,
              ]);

              expect(options.onDownload).toHaveBeenCalled();
              expect(options.onInstallStart).toHaveBeenCalled();
              expect(options.onMount).toHaveBeenCalled();
              expect(options.onCopy).toHaveBeenCalled();
              expect(options.onUnmount).toHaveBeenCalled();
              expect(options.onRemove).toHaveBeenCalled();
            });
          });
        });
      });
    });
  });

  describe('.isKiteRunning()', () => {
    describe('when kite is not installed', () => {
      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.isKiteRunning());
      });
    });

    withKiteInstalled(() => {
      describe('but not running', () => {
        beforeEach(() => {
          fakeProcesses({
            '/bin/ps': (ps) => {
              ps.stdout('');
              return 0;
            },
          });
        });

        it('returns a rejected promise', () => {
          waitsForPromise({shouldReject: true}, () => StateController.isKiteRunning());
        });
      });

      withKiteRunning(() => {
        it('returns a resolved promise', () => {
          waitsForPromise(() => StateController.isKiteRunning());
        });
      });
    });
  });

  describe('.canRunKite()', () => {
    describe('when kite is not installed', () => {
      it('returns a rejected function', () => {
        waitsForPromise({shouldReject: true}, () => StateController.canRunKite());
      });
    });

    withKiteNotRunning(() => {
      it('returns a resolved promise', () => {
        waitsForPromise(() => StateController.canRunKite());
      });
    });

    withKiteRunning(() => {
      it('returns a rejected function', () => {
        waitsForPromise({shouldReject: true}, () => StateController.canRunKite());
      });
    });
  });

  describe('.runKite()', () => {
    describe('when kite is not installed', () => {
      it('returns a rejected function', () => {
        waitsForPromise({shouldReject: true}, () => StateController.runKite());
      });
    });

    withKiteRunning(() => {
      it('returns a rejected function', () => {
        waitsForPromise({shouldReject: true}, () => StateController.runKite());
      });
    });

    withKiteNotRunning(() => {
      it('returns a resolved promise', () => {
        waitsForPromise(() => StateController.runKite());
        runs(() => {
          expect(proc.spawn).toHaveBeenCalledWith('defaults', [
            'write', 'com.kite.Kite', 'shouldReopenSidebar', '0',
          ]);

          expect(proc.spawn).toHaveBeenCalledWith('open', [
            '-a', OSXSupport.KITE_APP_PATH.installed,
          ]);
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>var Hook = require('./Hook');

/**@class A Widget models a set of controls on a website.
*/
var Widget = new Class({
	/** The name of this widget.
	* Automatically set to the name of its containing file upon parsing.
	*@type	{String}
	*/
	name: '',

	/**
	*@param	name	Name of this widget.
	*@param	values	A hash with the following form:
	*	`elements`: a hash mapping attribute names to a hook. A hook is a one-pair hash mapping a selector type to an actual selector.
	*	a series of methods definitions, i.e. `name: function name(…) { … }`, that will be made available
	*@param	driver	The WebDriver instance in which this widget should look for its elements.
	*/
	initialize: function init(name, values, driver) {
		this.name = name;

		var widget = this;

		Object.each(values.elements, function(typeAndSelector, key) {
			Hook.addHook(widget, key, typeAndSelector, driver);
		});

		delete values.elements;

		Object.each(values, function(method, key) {
			widget[key] = function() {
				if (VERBOSE)
					console.log('	- did ' + key + ' ' + Array.prototype.slice.call(arguments).join(', '));
				method.apply(widget, arguments); //TODO: handle elements overloading
			}
		});
	},

	/** Checks that the given element is found on the page.
	*
	*@param	{String}	attribute	The name of the element whose presence is to be checked.
	*@returns	{boolean}	Whether the element was found or not.
	*/
	has: function has(attribute) {
		if (VERBOSE)
			console.log('	- checked presence of ' + attribute);

		try {
			this[attribute];
			return true;
		} catch (error) {
			console.error('> ', error.message);
			return false;
		}
	}
});

module.exports = Widget;	// CommonJS export
<commit_msg>Made presence detection compatible with scenarios (promise embedding).<commit_after>var promises = require('q');

var Hook = require('./Hook');

/**@class A Widget models a set of controls on a website.
*/
var Widget = new Class({
	/** The name of this widget.
	* Automatically set to the name of its containing file upon parsing.
	*@type	{String}
	*/
	name: '',

	/**
	*@param	name	Name of this widget.
	*@param	values	A hash with the following form:
	*	`elements`: a hash mapping attribute names to a hook. A hook is a one-pair hash mapping a selector type to an actual selector.
	*	a series of methods definitions, i.e. `name: function name(…) { … }`, that will be made available
	*@param	driver	The WebDriver instance in which this widget should look for its elements.
	*/
	initialize: function init(name, values, driver) {
		this.name = name;

		var widget = this;

		Object.each(values.elements, function(typeAndSelector, key) {
			Hook.addHook(widget, key, typeAndSelector, driver);
		});

		delete values.elements;

		Object.each(values, function(method, key) {
			widget[key] = function() {
				if (VERBOSE)
					console.log('	- did ' + key + ' ' + Array.prototype.slice.call(arguments).join(', '));
				method.apply(widget, arguments); //TODO: handle elements overloading
			}
		});

		this.has = this.has.bind(this);
	},

	/** Checks that the given element is found on the page.
	*
	*@param	{String}	attribute	The name of the element whose presence is to be checked.
	*@returns	{boolean}	Whether the element was found or not.
	*/
	has: function has(attribute) {
		var deferred = promises.defer();

		try {
			this[attribute].then(function() {
					if (VERBOSE)
						console.log('	- checked presence of ' + attribute);

					deferred.resolve();;
				},
				deferred.reject.bind(deferred, 'Missing element ' + attribute)
			);
		} catch (error) {
			deferred.reject('Error while trying to check presence of element "' + attribute + '"');
		}

		return deferred.promise;
	}
});

module.exports = Widget;	// CommonJS export
<|endoftext|>