<commit_before>// Mapping functions

var map;
var markers;
var otherMarkers;
var stopsById = new Array();
var proj = new OpenLayers.Projection("EPSG:4326");
var selectControl;
var openPopup;
var openHover;
var segmentStyle =
{
  strokeColor: "#CC0000",
  strokeOpacity: 0.2,
  strokeWidth: 4
};

var segmentSelectedStyle =
{
  strokeColor: "#000000",
  strokeOpacity: 0.5,
  strokeWidth: 4
};

// Handle a click on a marker - go to its URL
function markerClick(evt) {
  if (evt.feature.attributes.url) {
    window.location =  evt.feature.attributes.url;
  }
  OpenLayers.Event.stop(evt);
}

function area_init() {
  // Vector layers must be added onload for IE
  if ($.browser.msie) {
      $(window).load(createAreaMap);
  } else {
      createAreaMap();
  }
}

function createAreaMap(){
  createMap('map');
  bounds = new OpenLayers.Bounds();

  // layers for markers that are the current focus (markers), other markers in the area
  // (otherMarkers) and other markers that are significant (highlightedMarkers)
  // - e.g. locations with problem reports, rather than without when browsing
  // an area.
  markers = new OpenLayers.Layer.Vector( "Markers" );
  otherMarkers = new OpenLayers.Layer.Vector( "Other Markers" );
  highlightedMarkers = new OpenLayers.Layer.Vector( "Highlighted Markers" );
  map.addLayer(otherMarkers);
  map.addLayer(highlightedMarkers);
  map.addLayer(markers);

  // All markers should handle to a click event
  markers.events.register( 'featureselected', markers, markerClick );
  otherMarkers.events.register( 'featureselected', otherMarkers, markerClick );
  highlightedMarkers.events.register( 'featureselected', highlightedMarkers, markerClick );
  var select = new OpenLayers.Control.SelectFeature( [markers, otherMarkers, highlightedMarkers] );
  map.addControl( select );
  select.activate();

  // Load the main markers, and the background markers (in either the highlighted or other layer)
  addMarkerList(areaStops, markers, false, null);
  addMarkerList(otherAreaStops, otherMarkers, true, highlightedMarkers);

  centerCoords =  new OpenLayers.LonLat(lon, lat);
  centerCoords.transform(proj, map.getProjectionObject());
  map.setCenter(centerCoords, zoom);

  if (findOtherLocations == true) {
    map.events.register('moveend', map, updateLocations);
  }

  // if we're constrained to less than the expected map dimensions, try
  // to make sure the markers are all shown
  if (($('#map').width() < mapWidth || $('#map').height() < mapHeight) && (areaStops.length > 0)) {
    map.zoomToExtent(bounds, false);
  }

  // Enforce some zoom constraints
  map.events.register("zoomend", map, function() {
      // World zoom resets map
      if (map.getZoom() == 0) {
        map.setCenter(centerCoords, zoom);
        return;
      }
      if (map.getZoom() < minZoom) map.zoomTo(minZoom);
      if (map.getZoom() > maxZoom) map.zoomTo(maxZoom);
  });

}

function updateLocations(event) {
  var currentZoom = map.getZoom();
  if (currentZoom >= minZoomForOtherMarkers){
    if ($('#map-zoom-notice').length > 0) {
      $('#map-zoom-notice').fadeOut(500);
    }
    // Show other, non-highlighted markers
    otherMarkers.setVisibility(true)
  }else{
    if ($('#map-zoom-notice').length > 0) {
      $('#map-zoom-notice').fadeIn(500);
    }
    // Hide other, non-highlighted markers
    otherMarkers.setVisibility(false)
  }
  // Request and load markers by ajax
  if (currentZoom >= minZoomForOtherMarkers || highlight == 'has_content'){
    center = map.getCenter();
    center = center.transform(map.getProjectionObject(), proj);
    url = "/locations/" + map.getZoom() + "/" + Math.round(center.lat*1000)/1000 + "/" + Math.round(center.lon*1000)/1000 + "/" + linkType;
    params = "?height=" + $('#map').height() + "&width=" + $('#map').width();
    params = params + "&highlight=" + highlight;
    $.ajax({
      url: url + params,
      dataType: 'json',
      success: loadNewMarkers,
      failure: markerFail})
  }

}

function loadNewMarkers(markerData) {
  newMarkers = markerData['locations'];
  // load new background markers
  addMarkerList(newMarkers, otherMarkers, true, highlightedMarkers);
  // update any associated list of issues
  newContent = markerData['issue_content'];
  if ($('#issues-in-area').length > 0){
    $('#issues-in-area').html(newContent);
  }
}

function markerFail(){
// do nothing
}

function addMarkerList(list, layer, others, highlightedLayer) {
  for (var i=0; i < list.length; i++){
    var item = list[i];
    // an element in the list may be an individual marker or an array
    // of markers representing a route
    if (item instanceof Array){
      for (var j=0; j < item.length; j++){
        addMarker(item[j], bounds, layer, others, highlightedLayer);
      }
    }else{
      addMarker(item, bounds, layer, others, highlightedLayer);
    }
  }
}

function addMarker(current, bounds, layer, other, highlightedLayer){
  stopCoords = pointCoords(current.lon, current.lat);

  if (stopsById[current.id] == undefined) {
    bounds.extend(stopCoords);
    var marker = new OpenLayers.Feature.Vector(stopCoords, {
      url: current.url,
      name: current.description,
      id: current.id,
      highlight: current.highlight,
    },
    {externalGraphic: current.icon + ".png",
        graphicTitle: current.description,
        graphicWidth: current.width,
        graphicHeight: current.height,
        graphicOpacity: 1,
        graphicXOffset: -( current.width/2),
        graphicYOffset: -current.height,
        cursor: 'pointer'
    });

    stopsById[current.id] = marker;
    if (current.highlight == true && other == true) {
      highlightedLayer.addFeatures( marker );
    }else{
      layer.addFeatures( marker );
    }
  }

}

function pointCoords(lon, lat) {
  return new OpenLayers.Geometry.Point(lon, lat).transform(proj, map.getProjectionObject());
}

function route_init(map_element, routeSegments) {

  createMap(map_element);
  bounds = new OpenLayers.Bounds();

  var vectorLayer = new OpenLayers.Layer.Vector("Vector Layer",{projection: proj});
  map.addLayer(vectorLayer);

  addSelectedHandler(vectorLayer);
  for (var i=0; i < routeSegments.length; i++){
     var coords = routeSegments[i];
     var fromCoords = pointCoords(coords[0].lon, coords[0].lat);
     var toCoords = pointCoords(coords[1].lon, coords[1].lat);
     var points = [];
     points.push(fromCoords);
     points.push(toCoords)
     bounds.extend(fromCoords);
     bounds.extend(toCoords);
     lineString = new OpenLayers.Geometry.LineString(points);
     lineFeature = new OpenLayers.Feature.Vector(lineString, {projection: proj}, segmentStyle);
     lineFeature.segment_id = coords[2];
     vectorLayer.addFeatures([lineFeature]);
   }
   map.zoomToExtent(bounds, false);

}

function addSelectedHandler(vectorLayer) {
  vectorLayer.events.on({
      'featureselected': segmentSelected,
      'featureunselected': segmentUnselected
  });
  selectControl = new OpenLayers.Control.SelectFeature(vectorLayer, {multiple: false,
                                                                     toggleKey: "ctrlKey",
                                                                     multipleKey: "shiftKey"});
  map.addControl(selectControl);
  selectControl.activate();
}

function segmentSelected(event) {
  segment = event.feature;
  segment.style = segmentSelectedStyle;
  this.drawFeature(segment);
  var row = $("#route_segment_" + segment.segment_id);
  row.toggleClass("selected");
  row.find(".check-route-segment").attr('checked', 'true');
}

function segmentUnselected(event) {
  segment = event.feature;
  segment.style = segmentStyle;
  this.drawFeature(segment);
  $("#route_segment_" + segment.segment_id).toggleClass("selected");

}

function createMap(map_element) {
  var options = {
        'projection': new OpenLayers.Projection("EPSG:900913"),
        'units': "m",
        'numZoomLevels': 18,
        'maxResolution': 156543.0339,
        'theme': null,
        'maxExtent': new OpenLayers.Bounds(-20037508.34, -20037508.34,
                                          20037508.34, 20037508.34)
      };
  $('.static-map-element').hide();
  map = new OpenLayers.Map(map_element, options);
  var layer = new OpenLayers.Layer.Google("Google Streets",{'sphericalMercator': true,
                                                           'maxExtent': new OpenLayers.Bounds(-20037508.34, -20037508.34,
                                                                                20037508.34, 20037508.34)});
  map.addLayer(layer);
}

<commit_msg>Readd imagepath var.<commit_after>// Mapping functions

var map;
var markers;
var otherMarkers;
var stopsById = new Array();
var proj = new OpenLayers.Projection("EPSG:4326");
var selectControl;
var openPopup;
var openHover;
var segmentStyle =
{
  strokeColor: "#CC0000",
  strokeOpacity: 0.2,
  strokeWidth: 4
};

var segmentSelectedStyle =
{
  strokeColor: "#000000",
  strokeOpacity: 0.5,
  strokeWidth: 4
};

// Handle a click on a marker - go to its URL
function markerClick(evt) {
  if (evt.feature.attributes.url) {
    window.location =  evt.feature.attributes.url;
  }
  OpenLayers.Event.stop(evt);
}

function area_init() {
  // Vector layers must be added onload for IE
  if ($.browser.msie) {
      $(window).load(createAreaMap);
  } else {
      createAreaMap();
  }
}

function createAreaMap(){
  createMap('map');
  bounds = new OpenLayers.Bounds();

  // layers for markers that are the current focus (markers), other markers in the area
  // (otherMarkers) and other markers that are significant (highlightedMarkers)
  // - e.g. locations with problem reports, rather than without when browsing
  // an area.
  markers = new OpenLayers.Layer.Vector( "Markers" );
  otherMarkers = new OpenLayers.Layer.Vector( "Other Markers" );
  highlightedMarkers = new OpenLayers.Layer.Vector( "Highlighted Markers" );
  map.addLayer(otherMarkers);
  map.addLayer(highlightedMarkers);
  map.addLayer(markers);

  // All markers should handle to a click event
  markers.events.register( 'featureselected', markers, markerClick );
  otherMarkers.events.register( 'featureselected', otherMarkers, markerClick );
  highlightedMarkers.events.register( 'featureselected', highlightedMarkers, markerClick );
  var select = new OpenLayers.Control.SelectFeature( [markers, otherMarkers, highlightedMarkers] );
  map.addControl( select );
  select.activate();

  // Load the main markers, and the background markers (in either the highlighted or other layer)
  addMarkerList(areaStops, markers, false, null);
  addMarkerList(otherAreaStops, otherMarkers, true, highlightedMarkers);

  centerCoords =  new OpenLayers.LonLat(lon, lat);
  centerCoords.transform(proj, map.getProjectionObject());
  map.setCenter(centerCoords, zoom);

  if (findOtherLocations == true) {
    map.events.register('moveend', map, updateLocations);
  }

  // if we're constrained to less than the expected map dimensions, try
  // to make sure the markers are all shown
  if (($('#map').width() < mapWidth || $('#map').height() < mapHeight) && (areaStops.length > 0)) {
    map.zoomToExtent(bounds, false);
  }

  // Enforce some zoom constraints
  map.events.register("zoomend", map, function() {
      // World zoom resets map
      if (map.getZoom() == 0) {
        map.setCenter(centerCoords, zoom);
        return;
      }
      if (map.getZoom() < minZoom) map.zoomTo(minZoom);
      if (map.getZoom() > maxZoom) map.zoomTo(maxZoom);
  });

}

function updateLocations(event) {
  var currentZoom = map.getZoom();
  if (currentZoom >= minZoomForOtherMarkers){
    if ($('#map-zoom-notice').length > 0) {
      $('#map-zoom-notice').fadeOut(500);
    }
    // Show other, non-highlighted markers
    otherMarkers.setVisibility(true)
  }else{
    if ($('#map-zoom-notice').length > 0) {
      $('#map-zoom-notice').fadeIn(500);
    }
    // Hide other, non-highlighted markers
    otherMarkers.setVisibility(false)
  }
  // Request and load markers by ajax
  if (currentZoom >= minZoomForOtherMarkers || highlight == 'has_content'){
    center = map.getCenter();
    center = center.transform(map.getProjectionObject(), proj);
    url = "/locations/" + map.getZoom() + "/" + Math.round(center.lat*1000)/1000 + "/" + Math.round(center.lon*1000)/1000 + "/" + linkType;
    params = "?height=" + $('#map').height() + "&width=" + $('#map').width();
    params = params + "&highlight=" + highlight;
    $.ajax({
      url: url + params,
      dataType: 'json',
      success: loadNewMarkers,
      failure: markerFail})
  }

}

function loadNewMarkers(markerData) {
  newMarkers = markerData['locations'];
  // load new background markers
  addMarkerList(newMarkers, otherMarkers, true, highlightedMarkers);
  // update any associated list of issues
  newContent = markerData['issue_content'];
  if ($('#issues-in-area').length > 0){
    $('#issues-in-area').html(newContent);
  }
}

function markerFail(){
// do nothing
}

function addMarkerList(list, layer, others, highlightedLayer) {
  for (var i=0; i < list.length; i++){
    var item = list[i];
    // an element in the list may be an individual marker or an array
    // of markers representing a route
    if (item instanceof Array){
      for (var j=0; j < item.length; j++){
        addMarker(item[j], bounds, layer, others, highlightedLayer);
      }
    }else{
      addMarker(item, bounds, layer, others, highlightedLayer);
    }
  }
}

function addMarker(current, bounds, layer, other, highlightedLayer){
  stopCoords = pointCoords(current.lon, current.lat);

  if (stopsById[current.id] == undefined) {
    bounds.extend(stopCoords);
    var marker = new OpenLayers.Feature.Vector(stopCoords, {
      url: current.url,
      name: current.description,
      id: current.id,
      highlight: current.highlight,
    },
    {externalGraphic: current.icon + ".png",
        graphicTitle: current.description,
        graphicWidth: current.width,
        graphicHeight: current.height,
        graphicOpacity: 1,
        graphicXOffset: -( current.width/2),
        graphicYOffset: -current.height,
        cursor: 'pointer'
    });

    stopsById[current.id] = marker;
    if (current.highlight == true && other == true) {
      highlightedLayer.addFeatures( marker );
    }else{
      layer.addFeatures( marker );
    }
  }

}

function pointCoords(lon, lat) {
  return new OpenLayers.Geometry.Point(lon, lat).transform(proj, map.getProjectionObject());
}

function route_init(map_element, routeSegments) {

  createMap(map_element);
  bounds = new OpenLayers.Bounds();

  var vectorLayer = new OpenLayers.Layer.Vector("Vector Layer",{projection: proj});
  map.addLayer(vectorLayer);

  addSelectedHandler(vectorLayer);
  for (var i=0; i < routeSegments.length; i++){
     var coords = routeSegments[i];
     var fromCoords = pointCoords(coords[0].lon, coords[0].lat);
     var toCoords = pointCoords(coords[1].lon, coords[1].lat);
     var points = [];
     points.push(fromCoords);
     points.push(toCoords)
     bounds.extend(fromCoords);
     bounds.extend(toCoords);
     lineString = new OpenLayers.Geometry.LineString(points);
     lineFeature = new OpenLayers.Feature.Vector(lineString, {projection: proj}, segmentStyle);
     lineFeature.segment_id = coords[2];
     vectorLayer.addFeatures([lineFeature]);
   }
   map.zoomToExtent(bounds, false);

}

function addSelectedHandler(vectorLayer) {
  vectorLayer.events.on({
      'featureselected': segmentSelected,
      'featureunselected': segmentUnselected
  });
  selectControl = new OpenLayers.Control.SelectFeature(vectorLayer, {multiple: false,
                                                                     toggleKey: "ctrlKey",
                                                                     multipleKey: "shiftKey"});
  map.addControl(selectControl);
  selectControl.activate();
}

function segmentSelected(event) {
  segment = event.feature;
  segment.style = segmentSelectedStyle;
  this.drawFeature(segment);
  var row = $("#route_segment_" + segment.segment_id);
  row.toggleClass("selected");
  row.find(".check-route-segment").attr('checked', 'true');
}

function segmentUnselected(event) {
  segment = event.feature;
  segment.style = segmentStyle;
  this.drawFeature(segment);
  $("#route_segment_" + segment.segment_id).toggleClass("selected");

}

function createMap(map_element) {
  OpenLayers.ImgPath='/javascripts/img/';
  var options = {
        'projection': new OpenLayers.Projection("EPSG:900913"),
        'units': "m",
        'numZoomLevels': 18,
        'maxResolution': 156543.0339,
        'theme': null,
        'maxExtent': new OpenLayers.Bounds(-20037508.34, -20037508.34,
                                          20037508.34, 20037508.34)
      };
  $('.static-map-element').hide();
  map = new OpenLayers.Map(map_element, options);
  var layer = new OpenLayers.Layer.Google("Google Streets",{'sphericalMercator': true,
                                                           'maxExtent': new OpenLayers.Bounds(-20037508.34, -20037508.34,
                                                                                20037508.34, 20037508.34)});
  map.addLayer(layer);
}

<|endoftext|>


<commit_before>'use strict';

var wiredep = require('wiredep');
var merge = require('merge');

module.exports = (function() {
  var src = './';
  var client = src + 'client/';
  var server = src + 'server/';
  var tests = src + 'tests/';
  var build = '../manageiq/public/self_service/';
  var temp = './.tmp/';
  var reports = './reports/';
  var bower = './bower_components/';
  var nodeModules = './node_modules/';

  var config = {};

  /**
   * Files
   */
  var indexFile = 'index.html';
  var specsFile = 'specs.html';
  var cssFile = 'styles.css';
  var sassFiles = [
    client + 'assets/sass/**/*.sass',
    client + 'app/**/*.sass'
  ];
  var templateFiles = client + 'app/**/*.html';
   var serverIntegrationSpecs = [tests + 'server-integration/**/*.spec.js'];
  var specHelperFiles = tests + 'test-helpers/*.js';

  var imageFiles = [
    client + 'assets/images/**/*.*'
  ];

  var fontFiles = [
    src + 'client/assets/fonts/**/*.*',
    bower + 'font-awesome/fonts/**/*.*',
    bower + 'patternfly/dist/fonts/**/*.*'
  ];

  var clientJsOrder = [
    '**/globals.js',
    '**/app.module.js',
    '**/*.module.js',
    '**/*.js'
  ];

  var wiredepOptions = {
    json: require('../bower.json'),
    directory: bower,
    ignorePath: '..',
    // Ignore CSS and JavaScript this is not needed or is undesired
    exclude: [
      // Exclude the bootstrap CSS, the Sass version will be @imported instead
      /bootstrap\.css/
    ]
  };

  var serverApp = server + 'app.js';

  function getClientJsFiles(ordered, includeSpecs) {
    var files = [client + 'app/**/*.js', client + 'app/skin/**/*.js'];

    if (ordered) {
      files = [].concat(client + 'app/globals.js', client + 'app/app.module.js', client + 'app/**/*module*.js', files)
    }

    if (includeSpecs) {
      files = [].concat(files,  tests + '**/*.spec.js');
    }

    return files;
  }

  function getKarmaOptions() {
    var options = {
      files: [].concat(
        './node_modules/phantomjs-polyfill/bind-polyfill.js',
        wiredep({devDependencies: true}).js,
        specHelperFiles,
        getClientJsFiles(true, true),
        config.templatecache.build + config.templatecache.output,
        config.test.serverIntegrationSpecs
      ),
      exclude: [],
      coverage: {
        dir: reports + 'coverage',
        reporters: [
          // reporters not supporting the `file` property
          {type: 'html', subdir: 'report-html'},
          {type: 'lcov', subdir: 'report-lcov'},
          {type: 'text-summary'}
        ]
      },
      preprocessors: {}
    };
    options.preprocessors[client + 'app/**/*.js'] = ['coverage'];

    return options;
  }

  // gulp-load-plugins options
  config.plugins = {
    lazy: true
  };

  // task ESLint: Runs ESLint on client code
  config.eslint = {
    src: getClientJsFiles(true, false)
  };

  // task plato: Analyze client code with Plato
  config.plato = {
    src: getClientJsFiles(true, false)[0],
    output: reports + 'plato',
    options: {
      title: 'Plato Inspections Report',
      exclude: /.*\.spec\.js/
    }
  };

  // task clean: Directories to clean
  config.clean = {
    src: [
      build + '*',
      // report + '*',
      temp + '*'
    ]
  };

  config.cleanStyles = {
    src: [
      temp + '**/*.css',
      build + 'styles/**/*.css'
    ]
  };

  config.cleanFonts = {
    src: [build + 'fonts/**/*.*']
  };

  config.cleanImages = {
    src: [build + 'images/**/*.*']
  };

  config.cleanCode = {
    src: [
      temp + '**/*.js',
      build + 'js/**/*.js',
      build + '**/*.html'
    ]
  };

  // task images: Image build options
  config.images = {
    src: imageFiles,
    build: build + 'images',
    minify: true,
    options: {
      optimizationLevel: 5,
      progressive: true,
      interlaced: true
    }
  };

  config.skinImages = {
    src: [
      client + 'skin/images/**/*.*'
    ],
    build: build + 'images',
    minify: true,
    options: {
      optimizationLevel: 5,
      progressive: true,
      interlaced: true
    }
  };

  config.devImages = {
    src: imageFiles,
    build: temp + 'images',
    minify: false
  };

  config.devSkinImages = {
    src: [
      client + 'skin/images/**/*.*'
    ],
    build: temp + 'images',
    minify: false
  };

  config.imgs = {
    src: [
      bower + 'patternfly/dist/img/**/*'
    ],
    build: build + 'img',
    minify: true,
    options: {
      optimizationLevel: 5,
      progressive: true,
      interlaced: true
    }
  };

  config.devImgs = {
    src: [
      bower + 'patternfly/dist/img/**/*'
    ],
    build: temp + 'img',
    minify: false
  };

  // task fonts: Copies fonts into build directory
  config.fonts = {
    src: fontFiles,
    build: build + 'fonts'
  };

  config.devFonts = {
    src: fontFiles,
    build: temp + 'fonts'
  };

  // task sass: Sass build options
  config.sass = {
    src: client + 'assets/sass/styles.sass',
    build: temp + 'styles/',
    output: cssFile,
    options: {
      // Only includes the styles if @imported
      // Remember to then update exclude in wiredepOptions if using @import
      loadPath: [
        bower + 'bootstrap-sass-official/assets/stylesheets/',
        bower + 'font-awesome/scss/',
        bower + 'patternfly-sass/assets/stylesheets/',
        // Hack so that font-awesome/variables can be found
        client + 'assets/sass/'
      ],
      style: 'compact',
      noCache: false,
      compass: false,
      bundleExec: true,
      sourcemap: false,
      precision: 8
    },
    autoprefixer: {
      browsers: [
        'last 2 versions',
        '> 5%'
      ],
      cascade: true
    }
  };

  // task templatecache: Optimize templates
  config.templatecache = {
    src: templateFiles,
    build: temp,
    output: 'templates.js',
    minify: true, // Always minify the templates
    minifyOptions: {
      empty: true
    },
    templateOptions: {
      module: 'app.core',
      standalone: false,
      root: 'app/'
    }
  };

  // task wiredep: Inject Bower CSS and JS into index.html
  // This task will also inject the application JavaScript
  // The inject task will inject the application CSS
  config.wiredep = {
    index: client + indexFile,
    build: client,
    options: wiredepOptions,
    files: getClientJsFiles(true, false),
    order: clientJsOrder
  };

  // task inject: Injects the application CSS (compiled from Sass) into index.html
  config.inject = {
    index: client + indexFile,
    build: client,
    css: [
      temp + 'styles/' + cssFile,
      client + '/skin/**/*.css'
    ]
  };

  config.optimize = {
    index: client + indexFile,
    build: build,
    cssFilter: '**/*.css',
    appJsFilter: '**/app.js',
    libJsFilter: '**/lib.js',
    templateCache: config.templatecache.build + config.templatecache.output,
    ngAnnotateOptions: {
      add: true,
      single_quotes: true
    },
    devHost: 'http://localhost:3000'
  };

  config.build = {
    clean: temp
  };

  // task build-specs: Builds a specs index file
  config.buildSpecs = {
    index: tests + specsFile,
    build: tests,
    templateCache: config.templatecache.build + config.templatecache.output,
    options: merge({}, wiredepOptions, {devDependencies: true}),
    specs: [tests + '*.spec.js'],
    serverIntegrationSpecs: serverIntegrationSpecs,
    files: getClientJsFiles(true, false),
    order: clientJsOrder,
    testLibraries: [
      nodeModules + 'mocha/mocha.js',
      nodeModules + 'chai/chai.js',
      nodeModules + 'mocha-clean/index.js',
      nodeModules + 'sinon-chai/lib/sinon-chai.js'
    ],
    specHelpers: [specHelperFiles]
  };

  config.test = {
    confFile: __dirname + '/../karma.conf.js',
    serverEnv: 'dev',
    serverPort: 8888,
    serverApp: serverApp,
    serverIntegrationSpecs: serverIntegrationSpecs
  };

  config.karma = getKarmaOptions();

  config.serve = {
    serverApp: serverApp,
    serverPort: process.env.PORT || '8001',
    watch: [server],
    browserReloadDelay: 1000,
    specsFile: specsFile,
    sass: sassFiles,
    js: getClientJsFiles(true, false),
    html: [].concat(client + indexFile, templateFiles),
    devFiles: [
      client + '**/*.js',
      client + '**/*.html',
      temp + '**/*.css'
    ],
    browserSyncOptions: {
      proxy: 'localhost:' + (process.env.PORT || '8001'),
      port: 3001,
      startPath: '/self_service/',
      files: [],
      ghostMode: {
        clicks: true,
        location: false,
        forms: true,
        scroll: true
      },
      injectChanges: true,
      logFileChanges: true,
      logLevel: 'debug',
      logPrefix: 'angular-gulp-sass-inject',
      notify: true,
      reloadDelay: 0
    }
  };

  config.availableLanguages = {
    catalogs: 'client/gettext/json/*/*.json',
    availLangsFile: 'client/gettext/json/available_languages.json',
    supportedLangsFile: 'client/gettext/json/supported_languages.json'
  };

  var poDir = 'client/gettext/po/';

  config.gettextExtract = {
    inputs: ['client/**/*.js', 'client/**/*.html'],
    potFile: 'manageiq-ui-self_service.pot',
    extractorOptions: {
      markerNames: ['__', 'N_'],
    },
    outputDir: poDir,
  };

  config.gettextCompile = {
    inputs: poDir + '**/*.po',
    compilerOptions: {
      format: 'json',
    },
    outputDir: 'client/gettext/json/',
  };

  config.gettextCopy = {
    inputs: ['client/gettext/json/**/*.json', config.availableLanguages.availLangsFile],
    outputDir: build + 'gettext/json/',
  };

  config.consoleCopy = [
    {
      input: 'bower_components/no-vnc/**/*',
      output: build + 'bower_components/no-vnc',
    },
    {
      input: 'bower_components/spice-html5-bower/**/*',
      output: build + 'bower_components/spice-html5-bower',
    },
  ];

  // task bump: Revs the package and bower files
  config.bump = {
    packages: [
      './package.json',
      './bower.json'
    ],
    root: './'
  };

  return config;
})();
<commit_msg>gulp - fix skinning - broken inject<commit_after>'use strict';

var wiredep = require('wiredep');
var merge = require('merge');

module.exports = (function() {
  var src = './';
  var client = src + 'client/';
  var server = src + 'server/';
  var tests = src + 'tests/';
  var build = '../manageiq/public/self_service/';
  var temp = './.tmp/';
  var reports = './reports/';
  var bower = './bower_components/';
  var nodeModules = './node_modules/';

  var config = {};

  /**
   * Files
   */
  var indexFile = 'index.html';
  var specsFile = 'specs.html';
  var cssFile = 'styles.css';
  var sassFiles = [
    client + 'assets/sass/**/*.sass',
    client + 'app/**/*.sass'
  ];
  var templateFiles = client + 'app/**/*.html';
   var serverIntegrationSpecs = [tests + 'server-integration/**/*.spec.js'];
  var specHelperFiles = tests + 'test-helpers/*.js';

  var imageFiles = [
    client + 'assets/images/**/*.*'
  ];

  var fontFiles = [
    src + 'client/assets/fonts/**/*.*',
    bower + 'font-awesome/fonts/**/*.*',
    bower + 'patternfly/dist/fonts/**/*.*'
  ];

  var clientJsOrder = [
    '**/globals.js',
    '**/app.module.js',
    '**/*.module.js',
    '**/*.js'
  ];

  var wiredepOptions = {
    json: require('../bower.json'),
    directory: bower,
    ignorePath: '..',
    // Ignore CSS and JavaScript this is not needed or is undesired
    exclude: [
      // Exclude the bootstrap CSS, the Sass version will be @imported instead
      /bootstrap\.css/
    ]
  };

  var serverApp = server + 'app.js';

  function getClientJsFiles(ordered, includeSpecs) {
    var files = [client + 'app/**/*.js', client + 'skin/**/*.js'];

    if (ordered) {
      files = [].concat(client + 'app/globals.js', client + 'app/app.module.js', client + 'app/**/*module*.js', files)
    }

    if (includeSpecs) {
      files = [].concat(files,  tests + '**/*.spec.js');
    }

    return files;
  }

  function getKarmaOptions() {
    var options = {
      files: [].concat(
        './node_modules/phantomjs-polyfill/bind-polyfill.js',
        wiredep({devDependencies: true}).js,
        specHelperFiles,
        getClientJsFiles(true, true),
        config.templatecache.build + config.templatecache.output,
        config.test.serverIntegrationSpecs
      ),
      exclude: [],
      coverage: {
        dir: reports + 'coverage',
        reporters: [
          // reporters not supporting the `file` property
          {type: 'html', subdir: 'report-html'},
          {type: 'lcov', subdir: 'report-lcov'},
          {type: 'text-summary'}
        ]
      },
      preprocessors: {}
    };
    options.preprocessors[client + 'app/**/*.js'] = ['coverage'];

    return options;
  }

  // gulp-load-plugins options
  config.plugins = {
    lazy: true
  };

  // task ESLint: Runs ESLint on client code
  config.eslint = {
    src: getClientJsFiles(true, false)
  };

  // task plato: Analyze client code with Plato
  config.plato = {
    src: getClientJsFiles(true, false)[0],
    output: reports + 'plato',
    options: {
      title: 'Plato Inspections Report',
      exclude: /.*\.spec\.js/
    }
  };

  // task clean: Directories to clean
  config.clean = {
    src: [
      build + '*',
      // report + '*',
      temp + '*'
    ]
  };

  config.cleanStyles = {
    src: [
      temp + '**/*.css',
      build + 'styles/**/*.css'
    ]
  };

  config.cleanFonts = {
    src: [build + 'fonts/**/*.*']
  };

  config.cleanImages = {
    src: [build + 'images/**/*.*']
  };

  config.cleanCode = {
    src: [
      temp + '**/*.js',
      build + 'js/**/*.js',
      build + '**/*.html'
    ]
  };

  // task images: Image build options
  config.images = {
    src: imageFiles,
    build: build + 'images',
    minify: true,
    options: {
      optimizationLevel: 5,
      progressive: true,
      interlaced: true
    }
  };

  config.skinImages = {
    src: [
      client + 'skin/images/**/*.*'
    ],
    build: build + 'images',
    minify: true,
    options: {
      optimizationLevel: 5,
      progressive: true,
      interlaced: true
    }
  };

  config.devImages = {
    src: imageFiles,
    build: temp + 'images',
    minify: false
  };

  config.devSkinImages = {
    src: [
      client + 'skin/images/**/*.*'
    ],
    build: temp + 'images',
    minify: false
  };

  config.imgs = {
    src: [
      bower + 'patternfly/dist/img/**/*'
    ],
    build: build + 'img',
    minify: true,
    options: {
      optimizationLevel: 5,
      progressive: true,
      interlaced: true
    }
  };

  config.devImgs = {
    src: [
      bower + 'patternfly/dist/img/**/*'
    ],
    build: temp + 'img',
    minify: false
  };

  // task fonts: Copies fonts into build directory
  config.fonts = {
    src: fontFiles,
    build: build + 'fonts'
  };

  config.devFonts = {
    src: fontFiles,
    build: temp + 'fonts'
  };

  // task sass: Sass build options
  config.sass = {
    src: client + 'assets/sass/styles.sass',
    build: temp + 'styles/',
    output: cssFile,
    options: {
      // Only includes the styles if @imported
      // Remember to then update exclude in wiredepOptions if using @import
      loadPath: [
        bower + 'bootstrap-sass-official/assets/stylesheets/',
        bower + 'font-awesome/scss/',
        bower + 'patternfly-sass/assets/stylesheets/',
        // Hack so that font-awesome/variables can be found
        client + 'assets/sass/'
      ],
      style: 'compact',
      noCache: false,
      compass: false,
      bundleExec: true,
      sourcemap: false,
      precision: 8
    },
    autoprefixer: {
      browsers: [
        'last 2 versions',
        '> 5%'
      ],
      cascade: true
    }
  };

  // task templatecache: Optimize templates
  config.templatecache = {
    src: templateFiles,
    build: temp,
    output: 'templates.js',
    minify: true, // Always minify the templates
    minifyOptions: {
      empty: true
    },
    templateOptions: {
      module: 'app.core',
      standalone: false,
      root: 'app/'
    }
  };

  // task wiredep: Inject Bower CSS and JS into index.html
  // This task will also inject the application JavaScript
  // The inject task will inject the application CSS
  config.wiredep = {
    index: client + indexFile,
    build: client,
    options: wiredepOptions,
    files: getClientJsFiles(true, false),
    order: clientJsOrder
  };

  // task inject: Injects the application CSS (compiled from Sass) into index.html
  config.inject = {
    index: client + indexFile,
    build: client,
    css: [
      temp + 'styles/' + cssFile,
      client + '/skin/**/*.css'
    ]
  };

  config.optimize = {
    index: client + indexFile,
    build: build,
    cssFilter: '**/*.css',
    appJsFilter: '**/app.js',
    libJsFilter: '**/lib.js',
    templateCache: config.templatecache.build + config.templatecache.output,
    ngAnnotateOptions: {
      add: true,
      single_quotes: true
    },
    devHost: 'http://localhost:3000'
  };

  config.build = {
    clean: temp
  };

  // task build-specs: Builds a specs index file
  config.buildSpecs = {
    index: tests + specsFile,
    build: tests,
    templateCache: config.templatecache.build + config.templatecache.output,
    options: merge({}, wiredepOptions, {devDependencies: true}),
    specs: [tests + '*.spec.js'],
    serverIntegrationSpecs: serverIntegrationSpecs,
    files: getClientJsFiles(true, false),
    order: clientJsOrder,
    testLibraries: [
      nodeModules + 'mocha/mocha.js',
      nodeModules + 'chai/chai.js',
      nodeModules + 'mocha-clean/index.js',
      nodeModules + 'sinon-chai/lib/sinon-chai.js'
    ],
    specHelpers: [specHelperFiles]
  };

  config.test = {
    confFile: __dirname + '/../karma.conf.js',
    serverEnv: 'dev',
    serverPort: 8888,
    serverApp: serverApp,
    serverIntegrationSpecs: serverIntegrationSpecs
  };

  config.karma = getKarmaOptions();

  config.serve = {
    serverApp: serverApp,
    serverPort: process.env.PORT || '8001',
    watch: [server],
    browserReloadDelay: 1000,
    specsFile: specsFile,
    sass: sassFiles,
    js: getClientJsFiles(true, false),
    html: [].concat(client + indexFile, templateFiles),
    devFiles: [
      client + '**/*.js',
      client + '**/*.html',
      temp + '**/*.css'
    ],
    browserSyncOptions: {
      proxy: 'localhost:' + (process.env.PORT || '8001'),
      port: 3001,
      startPath: '/self_service/',
      files: [],
      ghostMode: {
        clicks: true,
        location: false,
        forms: true,
        scroll: true
      },
      injectChanges: true,
      logFileChanges: true,
      logLevel: 'debug',
      logPrefix: 'angular-gulp-sass-inject',
      notify: true,
      reloadDelay: 0
    }
  };

  config.availableLanguages = {
    catalogs: 'client/gettext/json/*/*.json',
    availLangsFile: 'client/gettext/json/available_languages.json',
    supportedLangsFile: 'client/gettext/json/supported_languages.json'
  };

  var poDir = 'client/gettext/po/';

  config.gettextExtract = {
    inputs: ['client/**/*.js', 'client/**/*.html'],
    potFile: 'manageiq-ui-self_service.pot',
    extractorOptions: {
      markerNames: ['__', 'N_'],
    },
    outputDir: poDir,
  };

  config.gettextCompile = {
    inputs: poDir + '**/*.po',
    compilerOptions: {
      format: 'json',
    },
    outputDir: 'client/gettext/json/',
  };

  config.gettextCopy = {
    inputs: ['client/gettext/json/**/*.json', config.availableLanguages.availLangsFile],
    outputDir: build + 'gettext/json/',
  };

  config.consoleCopy = [
    {
      input: 'bower_components/no-vnc/**/*',
      output: build + 'bower_components/no-vnc',
    },
    {
      input: 'bower_components/spice-html5-bower/**/*',
      output: build + 'bower_components/spice-html5-bower',
    },
  ];

  // task bump: Revs the package and bower files
  config.bump = {
    packages: [
      './package.json',
      './bower.json'
    ],
    root: './'
  };

  return config;
})();
<|endoftext|>


<commit_before>// Includes file dependencies
define([
    "underscore",
	"jquery",
	"backbone",
    "text!../templates/character-summarize-list-item.html",
    "marionette",
    "../models/Vampire",
    "backform",
    "text!../templates/character-summarize-list-item-csv.html",
    "text!../templates/character-summarize-list-item-csv-header-grouped.html",
    "../helpers/PromiseFailReport",
    "papaparse"
], function( _, $, Backbone, character_summarize_list_item_html, Marionette, Vampire, Backform, character_summarize_list_item_csv_html, character_summarize_list_item_csv_header_grouped_html, PromiseFailReport, Papa ) {

    var PrettyView = Marionette.ItemView.extend({
        tagName: "li",
        className: "ul-li-has-thumb",
        template: _.template(character_summarize_list_item_html),
        initialize: function(options) {
            this.mode = options.mode;
            this.name = options.name;
        },

        templateHelpers: function () {
            var self = this;
            return {
                e: self.model,
                mode: self.mode,
                name: self.name
            };
        },

        events: {
            "click": "clicked",
        },

        clicked: function(e) {
            var self = this;
            e.preventDefault();
            $.mobile.loading("show");
            var targete = $(e.currentTarget);
            var pickedId = targete.attr("backendId");
            var tmpl = _.template(self.click_url)({character_id: pickedId});
            window.location.hash = tmpl;
        },

        onRender: function () {
            this.$el.enhanceWithin();
        }
    });

    var CSVView = Marionette.ItemView.extend({
        tagName: "li",
        template: _.template(character_summarize_list_item_csv_html),
        initialize: function(options) {
            this.mode = options.mode;
            this.name = options.name;
            this.columnNames = options.columnNames;
        },

        templateHelpers: function () {
            var self = this;
            return {
                e: self.model,
                mode: self.mode,
                name: self.name,
            };
        },

    });

    var CSVHeaderGroupedView = Marionette.ItemView.extend({
        tagName: "li",
        template: _.template(character_summarize_list_item_csv_header_grouped_html),
        initialize: function(options) {
            this.mode = options.mode;
            this.name = options.name;
            this.columnNames = options.columnNames;
        },

        templateHelpers: function () {
            var self = this;
            return {
                e: self.model,
                mode: self.mode,
                name: self.name,
                columnNames: self.columnNames
            };
        },

    });

    var CharactersView = Marionette.CollectionView.extend( {
        tagName: 'ul',
        childView: PrettyView,
        childViewOptions: function(model, index) {
            var self = this;
            return {
                mode: self.mode,
                name: self.name,
                columnNames: self.columnNames
            }
        },

        onRender: function () {
            var self = this;
            /*
            self.$el.filterable({
                input: "#troupes-characters-filter"
            });
            self.$el.filterable("enable");
            */
            self.$el.attr('data-role', 'listview');
            self.$el.attr('data-inset', 'true');
            self.$el.attr('data-filter', 'true');
            self.$el.attr('data-input', '#troupes-summarize-characters-filter');
            /*
            self.$el.enhanceWithin();
            */
        },

        /*
        onAddChild: function() {
            var self = this;
            self.$el.filterable("refresh");
        },
        */
        onDomRefresh: function() {
            var self = this;
            /*
            self.$el.filterable("refresh");
            self.$el.filterable("enable");
            */
        }

    } );

    var FilterButton = Marionette.ItemView.extend({
        className: "ui-block-b",
        template: function (serialized_model) {
            return _.template("<button><%= name %></button>")(serialized_model);
        },
        events: {
            "click": "filterwith"
        },
        filterwith: function () {
            this.triggerMethod("filterwith", this.model);
        }
    });

    var FiltersView = Marionette.CollectionView.extend({
        className: "ui-grid-b ui-responsive",
        childView: FilterButton
    });

    var DataForm = Backform.Form.extend({
        fields: [
            {
                control: "button",
                label: "Update Changes to Server"
            },
            {
                name: "descriptiondata",
                label: "Descriptions",
                control: "textarea"
            }
        ],
        events: {
            "submit": function(e) {
                var self = this;
                e.preventDefault();
                var results = Papa.parse(self.model.get("descriptiondata"), {header: true});
                console.log(results);
                if (0 != results.errors.length) {
                    console.log(JSON.stringify(results.errors));
                    return;
                }

                var promises = _.map(results.data, function(d, i) {
                    // Find any existing data that matches the category and name
                    var q = new Parse.Query("Description")
                        .equalTo("category", d.category)
                        .equalTo("name", d.name);
                    return q.first().then(function (toupdate) {
                        // If found, use that as the update object
                        // Otherwise create a new update object
                        if (!toupdate) {
                            toupdate = new Parse.Object("Description", {
                                name: d.name,
                                category: d.category
                            });
                            console.log("Didn't find existing object for " + d.category + " " + d.name);
                        } else {
                            console.log("Found existing object for " + d.category + " " + d.name);
                        }

                        // Set the ACL to be writable by administrators
                        var acl = new Parse.ACL;
                        acl.setPublicReadAccess(true);
                        acl.setPublicWriteAccess(false);
                        acl.setRoleReadAccess("Administrator", true);
                        acl.setRoleWriteAccess("Administrator", true);
                        toupdate.setACL(acl);

                        var final = _.omit(d, function(key) {
                            if (_.includes(["name", "category"], key)) {
                                return true;
                            }
                            if ("" == key) {
                                return true;
                            }

                            return false;
                        })

                        _.each(final, function(value, key) {
                            toupdate.set(key, value);
                        })
                        console.log(toupdate.attributes);
                        return Parse.Promise.as(toupdate);
                    })
                    // Return the promise so we can wait on them all
                });

                Parse.Promise.when(promises).then(function() {
                    console.log(JSON.stringify(arguments));
                    return Parse.Object.saveAll(arguments);
                }).then(function() {
                    console.log("Saved all of that");
                }).fail(PromiseFailReport);
                // Wait on all of the promises and report back
            }
        }
    });

    var Form = Backform.Form.extend({
        fields: [
            {
                name: "category",
                label: "Category",
                control: "select",
                options: [{label: "None", value: "None"}]
            }
        ]
    });

    var Mode = Backbone.Model.extend({

    });

    var Modes = Backbone.Collection.extend({
        model: Mode
    })

    var View = Marionette.LayoutView.extend({
        el: "#administration-descriptions > div[data-role='main']",
        regions: {
            sections: "#descriptions-sections",
            list: "#administration-descriptions-list"
        },
        childEvents: {
            "filterwith": "filterwith",
            "submit": "submit"
        },
        filterwith: function (formvalues) {
            var self = this
            self.data.set("descriptiondata", formvalues.get("category"));
            var descriptions = [];
            var q = new Parse.Query("Description").equalTo("category", formvalues.get("category"));
            return q.each(function (d) {
                descriptions.push(_.omit(d.attributes, "ACL"));
            }).then(function () {
                descriptions = _(descriptions)
                    .sortBy("order", "name")
                    .value();
                var all_fields = _(descriptions)
                    .map(function (d) {
                        return _.keys(d);
                    })
                    .tap(function(o) {
                        console.log(o)
                    })
                    .flatten()
                    .uniq()
                    .value();
                self.data.set("descriptiondata", Papa.unparse({
                    fields: all_fields,
                    data: descriptions}));
            }).fail(PromiseFailReport);

            this.$el.enhanceWithin();
        },
        getColumnNames: function(category) {
            var self = this;
            return _(self.collection.models)
                .map("attributes." + category)
                .flatten()
                .map("attributes.name")
                .without(undefined)
                .sortBy()
                .uniq(true)
                .value();
        },
        setup: function() {
            var self = this;
            var options = self.options || {};
            var modes = new Modes;
            self.filterOptions = new Backbone.Model({
                playable: true,
                category: "attributes",
                antecedence: "PC",
                resulttype: "onlycat",
                format: "pretty"
            });
            self.data = new Backbone.Model({
                descriptiondata: "Nothing here yet"
            })
            self.listenTo(self.filterOptions, 'change', self.filterwith);
            self.showChildView(
                'sections',
                new Form({
                    model: self.filterOptions
                }),
                options);
            self.showChildView(
                'list',
                new DataForm({
                    model: self.data,
                }),
                options);
            this.$el.enhanceWithin();
            return self;
        },
        update_categories: function () {
            var self = this;
            var q = new Parse.Query("Description");
            q.select("category");
            var categories = {};
            return q.each(function (d) {
                categories[d.get("category")] = 1;
            }).then(function () {
                console.log(categories);
                var form = self.sections.currentView;
                var firstSelect = form.fields.models[0];
                firstSelect.set("options", _.map(categories, function(value, key) {
                    return {
                        label: key,
                        value: key
                    };
                }));
                return Parse.Promise.as(form.render());
            })
        }
    });

    // Returns the View class
    return View;

} );<commit_msg>Update the descriptions view<commit_after>// Includes file dependencies
define([
    "underscore",
	"jquery",
	"backbone",
    "text!../templates/character-summarize-list-item.html",
    "marionette",
    "../models/Vampire",
    "backform",
    "text!../templates/character-summarize-list-item-csv.html",
    "text!../templates/character-summarize-list-item-csv-header-grouped.html",
    "../helpers/PromiseFailReport",
    "papaparse"
], function( _, $, Backbone, character_summarize_list_item_html, Marionette, Vampire, Backform, character_summarize_list_item_csv_html, character_summarize_list_item_csv_header_grouped_html, PromiseFailReport, Papa ) {

    var PrettyView = Marionette.ItemView.extend({
        tagName: "li",
        className: "ul-li-has-thumb",
        template: _.template(character_summarize_list_item_html),
        initialize: function(options) {
            this.mode = options.mode;
            this.name = options.name;
        },

        templateHelpers: function () {
            var self = this;
            return {
                e: self.model,
                mode: self.mode,
                name: self.name
            };
        },

        events: {
            "click": "clicked",
        },

        clicked: function(e) {
            var self = this;
            e.preventDefault();
            $.mobile.loading("show");
            var targete = $(e.currentTarget);
            var pickedId = targete.attr("backendId");
            var tmpl = _.template(self.click_url)({character_id: pickedId});
            window.location.hash = tmpl;
        },

        onRender: function () {
            this.$el.enhanceWithin();
        }
    });

    var CSVView = Marionette.ItemView.extend({
        tagName: "li",
        template: _.template(character_summarize_list_item_csv_html),
        initialize: function(options) {
            this.mode = options.mode;
            this.name = options.name;
            this.columnNames = options.columnNames;
        },

        templateHelpers: function () {
            var self = this;
            return {
                e: self.model,
                mode: self.mode,
                name: self.name,
            };
        },

    });

    var CSVHeaderGroupedView = Marionette.ItemView.extend({
        tagName: "li",
        template: _.template(character_summarize_list_item_csv_header_grouped_html),
        initialize: function(options) {
            this.mode = options.mode;
            this.name = options.name;
            this.columnNames = options.columnNames;
        },

        templateHelpers: function () {
            var self = this;
            return {
                e: self.model,
                mode: self.mode,
                name: self.name,
                columnNames: self.columnNames
            };
        },

    });

    var CharactersView = Marionette.CollectionView.extend( {
        tagName: 'ul',
        childView: PrettyView,
        childViewOptions: function(model, index) {
            var self = this;
            return {
                mode: self.mode,
                name: self.name,
                columnNames: self.columnNames
            }
        },

        onRender: function () {
            var self = this;
            /*
            self.$el.filterable({
                input: "#troupes-characters-filter"
            });
            self.$el.filterable("enable");
            */
            self.$el.attr('data-role', 'listview');
            self.$el.attr('data-inset', 'true');
            self.$el.attr('data-filter', 'true');
            self.$el.attr('data-input', '#troupes-summarize-characters-filter');
            /*
            self.$el.enhanceWithin();
            */
        },

        /*
        onAddChild: function() {
            var self = this;
            self.$el.filterable("refresh");
        },
        */
        onDomRefresh: function() {
            var self = this;
            /*
            self.$el.filterable("refresh");
            self.$el.filterable("enable");
            */
        }

    } );

    var FilterButton = Marionette.ItemView.extend({
        className: "ui-block-b",
        template: function (serialized_model) {
            return _.template("<button><%= name %></button>")(serialized_model);
        },
        events: {
            "click": "filterwith"
        },
        filterwith: function () {
            this.triggerMethod("filterwith", this.model);
        }
    });

    var FiltersView = Marionette.CollectionView.extend({
        className: "ui-grid-b ui-responsive",
        childView: FilterButton
    });

    var DataForm = Backform.Form.extend({
        fields: [
            {
                control: "button",
                label: "Update Changes to Server"
            },
            {
                name: "descriptiondata",
                label: "Descriptions",
                control: "textarea"
            }
        ],
        events: {
            "submit": function(e) {
                var self = this;
                e.preventDefault();
                var results = Papa.parse(self.model.get("descriptiondata"), {header: true});
                console.log(results);
                if (0 != results.errors.length) {
                    console.log(JSON.stringify(results.errors));
                    return;
                }

                var promises = _.map(results.data, function(d, i) {
                    // Find any existing data that matches the category and name
                    var q = new Parse.Query("Description")
                        .equalTo("category", d.category)
                        .equalTo("name", d.name);
                    return q.first().then(function (toupdate) {
                        // If found, use that as the update object
                        // Otherwise create a new update object
                        if (!toupdate) {
                            toupdate = new Parse.Object("Description", {
                                name: d.name,
                                category: d.category
                            });
                            console.log("Didn't find existing object for " + d.category + " " + d.name);
                        } else {
                            console.log("Found existing object for " + d.category + " " + d.name);
                        }

                        // Set the ACL to be writable by administrators
                        var acl = new Parse.ACL;
                        acl.setPublicReadAccess(true);
                        acl.setPublicWriteAccess(false);
                        acl.setRoleReadAccess("Administrator", true);
                        acl.setRoleWriteAccess("Administrator", true);
                        toupdate.setACL(acl);

                        var final = _.omit(d, function(key) {
                            if (_.includes(["name", "category"], key)) {
                                return true;
                            }
                            if ("" == key) {
                                return true;
                            }

                            return false;
                        })

                        _.each(final, function(value, key) {
                            toupdate.set(key, value);
                        })
                        console.log(toupdate.attributes);
                        return Parse.Promise.as(toupdate);
                    })
                    // Return the promise so we can wait on them all
                });

                Parse.Promise.when(promises).then(function() {
                    console.log(JSON.stringify(arguments));
                    return Parse.Object.saveAll(arguments);
                }).then(function() {
                    console.log("Saved all of that");
                }).fail(PromiseFailReport);
                // Wait on all of the promises and report back
            }
        }
    });

    var Form = Backform.Form.extend({
        fields: [
            {
                name: "category",
                label: "Category",
                control: "select",
                options: [{label: "None", value: "None"}]
            }
        ]
    });

    var Mode = Backbone.Model.extend({

    });

    var Modes = Backbone.Collection.extend({
        model: Mode
    })

    var View = Marionette.LayoutView.extend({
        el: "#administration-descriptions > div[data-role='main']",
        regions: {
            sections: "#descriptions-sections",
            list: "#administration-descriptions-list"
        },
        childEvents: {
            "filterwith": "filterwith",
            "submit": "submit"
        },
        filterwith: function (formvalues) {
            var self = this
            var q;
            if (formvalues.get("category") == "All") {
                q = new Parse.Query("Description");
            } else {
                q = new Parse.Query("Description").equalTo("category", formvalues.get("category"));
            }
            var descriptions = [];
            return q.each(function (d) {
                descriptions.push(_.omit(d.attributes, "ACL"));
            }).then(function () {
                descriptions = _(descriptions)
                    .sortByAll(["category", "order", "name"])
                    .value();
                var all_fields = _(descriptions)
                    .map(function (d) {
                        return _.keys(d);
                    })
                    .tap(function(o) {
                        console.log(o)
                    })
                    .flatten()
                    .uniq()
                    .value();
                self.data.set("descriptiondata", Papa.unparse({
                    fields: all_fields,
                    data: descriptions}));
            }).fail(PromiseFailReport);

            this.$el.enhanceWithin();
        },
        getColumnNames: function(category) {
            var self = this;
            return _(self.collection.models)
                .map("attributes." + category)
                .flatten()
                .map("attributes.name")
                .without(undefined)
                .sortBy()
                .uniq(true)
                .value();
        },
        setup: function() {
            var self = this;
            var options = self.options || {};
            var modes = new Modes;
            self.filterOptions = new Backbone.Model({
                playable: true,
                category: "attributes",
                antecedence: "PC",
                resulttype: "onlycat",
                format: "pretty"
            });
            self.data = new Backbone.Model({
                descriptiondata: "Nothing here yet"
            })
            self.listenTo(self.filterOptions, 'change', self.filterwith);
            self.showChildView(
                'sections',
                new Form({
                    model: self.filterOptions
                }),
                options);
            self.showChildView(
                'list',
                new DataForm({
                    model: self.data,
                }),
                options);
            this.$el.enhanceWithin();
            return self;
        },
        update_categories: function () {
            var self = this;
            var q = new Parse.Query("Description");
            q.select("category");
            var categories = {};
            return q.each(function (d) {
                categories[d.get("category")] = 1;
            }).then(function () {
                console.log(categories);
                var form = self.sections.currentView;
                var firstSelect = form.fields.models[0];
                var so = _.map(categories, function(value, key) {
                    return {
                        label: key,
                        value: key
                    };
                });
                so = _.sortBy(so, 'label');
                so.push({label: "All", value: "All"});

                firstSelect.set("options", so);
                return Parse.Promise.as(form.render());
            })
        }
    });

    // Returns the View class
    return View;

} );<|endoftext|>


<commit_before>/*jslint node: true */
var _ = require('underscore');
var logger = require('loge');
var request = require('request');
var streaming = require('streaming');

var errors = require('./errors');
var credentials = require('./credentials');

var requestWithOAuth = exports.requestWithOAuth = function(opts, callback) {
  /**
  callback signature: function(Error | null, response)
  */
  credentials.getOAuth('~/.twitter', function(err, oauth) {
    if (err) return callback(err);

    var options = _.extend({oauth: oauth}, opts);

    logger.debug('Authenticated request: %j', options);

    request(options)
    .on('response', function(response) {
      if (response.statusCode != 200) {
        streaming.readToEnd(response, function(err, chunks) {
          if (err) return callback(err);

          var body = chunks.join('');
          callback(new errors.TwitterError(response, body));
        });
      }
      else {
        callback(null, response);
      }
    })
    .on('error', callback);
  });
};

var requestWithOAuthUntilSuccess = exports.requestWithOAuthUntilSuccess = function(opts, callback) {
  requestWithOAuth(opts, function(err, response) {
    if (err && err instanceof errors.TwitterError && err.statusCode == 403) {
      logger.debug('%s, retrying', err.message);
      return requestWithOAuthUntilSuccess(opts, callback);
    }
    callback(err, response);
  });
};

// exports.request = function(options, callback) {
//   request(options, function(err, response, body) {
//     if (err) {
//       callback(err);
//     }
//     else if (response.statusCode != 200) {
//       callback(new errors.TwitterError(response, body));
//     }
//     else {
//       callback(null, body);
//     }
//   });
// };
<commit_msg>Retry on timeouts and hangups in http request call<commit_after>/*jslint node: true */
var _ = require('underscore');
var logger = require('loge');
var request = require('request');
var streaming = require('streaming');

var errors = require('./errors');
var credentials = require('./credentials');

var requestWithOAuth = exports.requestWithOAuth = function(opts, callback) {
  /**
  callback signature: function(Error | null, response)
  */
  credentials.getOAuth('~/.twitter', function(err, oauth) {
    if (err) return callback(err);

    var options = _.extend({oauth: oauth}, opts);

    logger.debug('Authenticated request: %j', options);

    request(options)
    .on('response', function(response) {
      if (response.statusCode != 200) {
        streaming.readToEnd(response, function(err, chunks) {
          if (err) return callback(err);

          var body = chunks.join('');
          callback(new errors.TwitterError(response, body));
        });
      }
      else {
        callback(null, response);
      }
    })
    .on('error', callback);
  });
};

var requestWithOAuthUntilSuccess = exports.requestWithOAuthUntilSuccess = function(opts, callback) {
  requestWithOAuth(opts, function(err, response) {
    if (err) {
      if (err instanceof errors.TwitterError && err.statusCode == 403) {
        logger.debug('403: %s, retrying', err.message);
        return requestWithOAuthUntilSuccess(opts, callback);
      }
      else if (err.code == 'ETIMEDOUT') {
        logger.debug('ETIMEDOUT: %s, retrying', err.message);
        return requestWithOAuthUntilSuccess(opts, callback);
      }
      else if (err.code == 'ECONNRESET') {
        logger.debug('ECONNRESET: %s, retrying', err.message);
        return requestWithOAuthUntilSuccess(opts, callback);
      }
    }
    callback(err, response);
  });
};

// exports.request = function(options, callback) {
//   request(options, function(err, response, body) {
//     if (err) {
//       callback(err);
//     }
//     else if (response.statusCode != 200) {
//       callback(new errors.TwitterError(response, body));
//     }
//     else {
//       callback(null, body);
//     }
//   });
// };
<|endoftext|>


<commit_before>var dev = 'http://localhost:55881' // eslint-disable-line
var staging = 'http://streetsupport-api-staging.apphb.com' // eslint-disable-line
var live = 'http://api.streetsupport.net' // eslint-disable-line

function p (addr) {
  return staging + addr
}

var createSession = '/v1/sessions/create'
var getServiceProviders = '/v1/all-service-providers'
var getServiceCategories = '/v2/service-categories'

module.exports = {
  createSession: p(createSession),
  getServiceProviders: p(getServiceProviders),
  getServiceCategories: p(getServiceCategories)
}
<commit_msg>point to live db<commit_after>var dev = 'http://localhost:55881' // eslint-disable-line
var staging = 'http://streetsupport-api-staging.apphb.com' // eslint-disable-line
var live = 'http://api.streetsupport.net' // eslint-disable-line

function p (addr) {
  return live + addr
}

var createSession = '/v1/sessions/create'
var getServiceProviders = '/v1/all-service-providers'
var getServiceCategories = '/v2/service-categories'

module.exports = {
  createSession: p(createSession),
  getServiceProviders: p(getServiceProviders),
  getServiceCategories: p(getServiceCategories)
}
<|endoftext|>


<commit_before>/* global describe, beforeEach, it */
'use strict';

var path = require('path');
var helpers = require('yeoman-generator').test;

describe('gulp-requirejs generator', function(){
	beforeEach(function(done){
		helpers.testDirectory(path.join(__dirname, 'temp'), function(err){
			if(err) return done(err);
			var generators = [
				['../../generators/app'],
				['../../generators/back'],
				['../../generators/front']
			];
			this.app = helpers.createGenerator('gulp-requirejs:app', generators[0]);
			this.back = helpers.createGenerator('gulp-requirejs:back', generators[1]);
			this.front = helpers.createGenerator('gulp-requirejs:front', generators[2]);
			done();
		}.bind(this));
	});

	it('creates expected files', function(done){
		var expected = ['.editorconfig'];
		helpers.mockPrompt(this.app, { someOption:true });
		this.app.options['skip-install'] = true;
		this.app.run({}, function(){
			helpers.assertFile(expected);
			done();
		});
	});
});
<commit_msg>Update: spec<commit_after>/* global describe, beforeEach, it */
'use strict';

var path = require('path');
var helpers = require('yeoman-generator').test;
var Utils = require('../generators/utils');

describe('gulp-requirejs generator', function(){
	beforeEach(function(done){
		helpers.testDirectory(path.join(__dirname, 'temp'), function(err){
			if(err) return done(err);
			var generators = [
				['../../generators/app'],
				['../../generators/back'],
				['../../generators/front']
			];
			this.app = helpers.createGenerator('gulp-requirejs:app', generators[0]);
			this.back = helpers.createGenerator('gulp-requirejs:back', generators[1]);
			this.front = helpers.createGenerator('gulp-requirejs:front', generators[2]);
			done();
		}.bind(this));
	});

	it('creates expected files', function(done){
		var expected = ['.editorconfig'];
		helpers.mockPrompt(this.app, { someOption:true });
		this.app.options['skip-install'] = true;
		this.app.run({}, function(){
			helpers.assertFile(expected);
			done();
		});
	});
});
<|endoftext|>


<commit_before>/**
 * @brief タグ関連処理
 */
var gspecv = gspecv || {};
gspecv.tag = {};

(function() {
  var fileTagNameArray = [];
  var stockTagNameArray = [];
  var selecters;

  /**
   * @brief タグ関連処理のセットアップ
   *
   * @param selecterObjects セレクタをまとめたオブジェクト
   */
  function setup(selecterObjects) {
    selecters = selecterObjects;
    var editFileName;

    // ダイアログのセットアップメソッドを設定
    selecters.$tagEditDialog.setup = function(fileName, data) {
      editFileName = fileName;
      fileTagNameArray = data.file_tags;
      stockTagNameArray = data.stock_tags;

      // タグリストを構築
      selecters.$fileTagList.droppable({
        drop: function(event, ui) {
          var $dropedSelecter = $(ui.draggable[0]);
          var droppedTagName = $dropedSelecter.text();
          fileTagNameArray.push(droppedTagName);
          stockTagNameArray = _.remove(stockTagNameArray, function(name) { return name !== droppedTagName; });

          updateTagList();
        }
      });
      selecters.$stockTagList.droppable({
        drop: function(event, ui) {
          var $dropedSelecter = $(ui.draggable[0]);
          var droppedTagName = $dropedSelecter.text();
          stockTagNameArray.push(droppedTagName);
          fileTagNameArray = _.remove(fileTagNameArray, function(name) { return name !== droppedTagName; });

          updateTagList();
        }
      });

      updateTagList();

      return selecters.$tagEditDialog;
    };

    selecters.$tagCreateButton.on('click', function() {
      // 新しいタグをリストに追加する
      var newTagName = $(selecters.tagCreateNameInput).val();
      if(newTagName !== '') {
        fileTagNameArray.push(newTagName.trim());

        selecters.$fileTagList.append(createTagLabel(newTagName));
      }
    });

    // 編集したタグを適用する
    selecters.$applyTagButton.on('click', function() {
      var info = {
        file_name: editFileName,
        tag_names: fileTagNameArray
      };

      $.post('/apply_tag', info)
        .done(function(data) {
          if(data.errorMessage) {
            alsert(data.errorMessage);
          }
        })
        .fail(function(error, errorMessage) {
          alsert(errorMessage);
        });

      selecters.$tagEditDialog.modal('hide');

      // 表示を更新する
      gspecv.commitInfo.updateActiveTab();
    });
  }

  /**
   * @brief タグのラベルを生成
   *
   * @param tagName タグ名
   *
   * @return タグのラベル
   */
  function createTagLabel(tagName) {
    return $('')
            .addClass('label label-default tag')
            .draggable({ revert: true })
            .text(tagName);
  }

  function updateTagList() {
    // 既存のタグ情報を削除
    selecters.$fileTagList.find('.tag').remove();
    selecters.$fileTagList.find('br').remove();
    selecters.$stockTagList.find('.tag').remove();
    selecters.$stockTagList.find('br').remove();

    var fileRowTagCount = 0;
    fileTagNameArray.forEach(function(tagName) {
      selecters.$fileTagList.append(createTagLabel(tagName));
      fileRowTagCount++;
      if(fileRowTagCount >= 3) {
        selecters.$fileTagList.append('
');
        fileRowTagCount = 0;
      }
    });

    var stockRowTagCount = 0;
    stockTagNameArray.forEach(function(tagName) {
      selecters.$stockTagList.append(createTagLabel(tagName));
      stockRowTagCount++;
      if(stockRowTagCount >= 3) {
        selecters.$stockTagList.append('
');
        stockRowTagCount = 0;
      }
    });
  }

  // 外部に公開する関数を設定
  gspecv.tag.setup = setup;
  gspecv.tag.createTagLabel = createTagLabel;
})();
<commit_msg>新規タグの作成時に、タグの配置が更新されるように対応<commit_after>/**
 * @brief タグ関連処理
 */
var gspecv = gspecv || {};
gspecv.tag = {};

(function() {
  var fileTagNameArray = [];
  var stockTagNameArray = [];
  var selecters;

  /**
   * @brief タグ関連処理のセットアップ
   *
   * @param selecterObjects セレクタをまとめたオブジェクト
   */
  function setup(selecterObjects) {
    selecters = selecterObjects;
    var editFileName;

    // ダイアログのセットアップメソッドを設定
    selecters.$tagEditDialog.setup = function(fileName, data) {
      editFileName = fileName;
      fileTagNameArray = data.file_tags;
      stockTagNameArray = data.stock_tags;

      // タグリストを構築
      selecters.$fileTagList.droppable({
        drop: function(event, ui) {
          var $dropedSelecter = $(ui.draggable[0]);
          var droppedTagName = $dropedSelecter.text();
          fileTagNameArray.push(droppedTagName);
          stockTagNameArray = _.remove(stockTagNameArray, function(name) { return name !== droppedTagName; });

          updateTagList();
        }
      });
      selecters.$stockTagList.droppable({
        drop: function(event, ui) {
          var $dropedSelecter = $(ui.draggable[0]);
          var droppedTagName = $dropedSelecter.text();
          stockTagNameArray.push(droppedTagName);
          fileTagNameArray = _.remove(fileTagNameArray, function(name) { return name !== droppedTagName; });

          updateTagList();
        }
      });

      updateTagList();

      return selecters.$tagEditDialog;
    };

    selecters.$tagCreateButton.on('click', function() {
      // 新しいタグをリストに追加する
      var newTagName = $(selecters.tagCreateNameInput).val();
      if(newTagName !== '') {
        fileTagNameArray.push(newTagName.trim());
        updateTagList();
      }
    });

    // 編集したタグを適用する
    selecters.$applyTagButton.on('click', function() {
      var info = {
        file_name: editFileName,
        tag_names: fileTagNameArray
      };

      $.post('/apply_tag', info)
        .done(function(data) {
          if(data.errorMessage) {
            alsert(data.errorMessage);
          }
        })
        .fail(function(error, errorMessage) {
          alsert(errorMessage);
        });

      selecters.$tagEditDialog.modal('hide');

      // 表示を更新する
      gspecv.commitInfo.updateActiveTab();
    });
  }

  /**
   * @brief タグのラベルを生成
   *
   * @param tagName タグ名
   *
   * @return タグのラベル
   */
  function createTagLabel(tagName) {
    return $('')
            .addClass('label label-default tag')
            .draggable({ revert: true })
            .text(tagName);
  }

  function updateTagList() {
    // 既存のタグ情報を削除
    selecters.$fileTagList.find('.tag').remove();
    selecters.$fileTagList.find('br').remove();
    selecters.$stockTagList.find('.tag').remove();
    selecters.$stockTagList.find('br').remove();

    var fileRowTagCount = 0;
    fileTagNameArray.forEach(function(tagName) {
      selecters.$fileTagList.append(createTagLabel(tagName));
      fileRowTagCount++;
      if(fileRowTagCount >= 3) {
        selecters.$fileTagList.append('
');
        fileRowTagCount = 0;
      }
    });

    var stockRowTagCount = 0;
    stockTagNameArray.forEach(function(tagName) {
      selecters.$stockTagList.append(createTagLabel(tagName));
      stockRowTagCount++;
      if(stockRowTagCount >= 3) {
        selecters.$stockTagList.append('
');
        stockRowTagCount = 0;
      }
    });
  }

  // 外部に公開する関数を設定
  gspecv.tag.setup = setup;
  gspecv.tag.createTagLabel = createTagLabel;
})();
<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');
var path = require('path');
var gulp = require('gulp');
var git = require('gulp-git');
var tag_version = require('gulp-tag-version');
var argv = require('yargs').argv;

var $ = require('gulp-load-plugins')();

module.exports = function(options) {
	var packageSrc = './package.json';

	var bump = function(type='patch'){
		return function bump(){
			return gulp.src(['./bower.json',packageSrc])
			.pipe($.bump({
				// version: options.version,
				type: type
			}))
			.pipe(gulp.dest('./'));
		}
	}

	gulp.task('git:tag', function () {
		return gulp.src(packageSrc)
		.pipe(tag_version({
			message: '[Release] %VERSION%'
		}));
	});

	gulp.task('git:push',function(done){
		return git.push('origin', 'HEAD', {
			args: '--tags'
		},function(err){
			if(err) console.error(err);
			done();
		});
	});

	gulp.task('git:add', function add() {
		return gulp.src(packageSrc)
			.pipe(git.add({args: ". -A"}));
	});

	gulp.task('git:commit_release', gulp.series('git:add', function commit_release () {
		var pkg = JSON.parse(fs.readFileSync(path.join(__dirname,'../package.json')));
		return gulp.src('./')
			.pipe(git.commit('v '+pkg.version));
	}));

	gulp.task('git:commit', gulp.series('git:add', function commit () {
		return gulp.src('./')
		.pipe(git.commit((argv.m && argv!==true  ?  argv.m : 'Minor changes :coffee:')));
	}));

	gulp.task('p', gulp.series('git:commit','git:push', function p(){
		process.exit();
	}));

	gulp.task('bump', gulp.series(bump(argv.major ? 'major' : (argv.minor ? 'minor' : 'patch'))));

	gulp.task('patch', gulp.series('build', bump('patch'), 'git:commit_release','git:tag','git:push'));
	gulp.task('minor', gulp.series('build', bump('minor'), 'git:commit_release','git:tag','git:push'));
	gulp.task('major', gulp.series('build', bump('major'), 'git:commit_release','git:tag','git:push'));
}
<commit_msg>small fix on version<commit_after>'use strict';

var fs = require('fs');
var path = require('path');
var gulp = require('gulp');
var git = require('gulp-git');
var tag_version = require('gulp-tag-version');
var argv = require('yargs').argv;

var $ = require('gulp-load-plugins')();

module.exports = function(options) {
	var packageSrc = './package.json';

	var bump = function(type='patch'){
		return function bump(){
			return gulp.src(['./bower.json',packageSrc])
			.pipe($.bump({
				// version: options.version,
				type: type
			}))
			.pipe(gulp.dest('./'));
		}
	}

	gulp.task('git:tag', function () {
		return gulp.src(packageSrc)
		.pipe(tag_version({
			message: '[Release] %VERSION%'
		}));
	});

	gulp.task('git:push',function(done){
		return git.push('origin', 'HEAD', {
			args: '--tags'
		},function(err){
			if(err) console.error(err);
			done();
		});
	});

	gulp.task('git:add', function add() {
		return gulp.src(packageSrc)
			.pipe(git.add({args: ". -A"}));
	});

	gulp.task('git:commit_release', gulp.series('git:add', function commit_release () {
		var pkg = JSON.parse(fs.readFileSync(path.join(__dirname,'../package.json')));
		return gulp.src('./')
			.pipe(git.commit('v '+pkg.version));
	}));

	gulp.task('git:commit', gulp.series('git:add', function commit () {
		return gulp.src('./')
		.pipe(git.commit((argv.m && argv!==true  ?  argv.m : 'Minor changes :coffee:')));
	}));

	gulp.task('p', gulp.series('git:commit','git:push', function p(){
		process.exit();
	}));

	gulp.task('bump', gulp.series(bump(argv.major ? 'major' : (argv.minor ? 'minor' : 'patch'))));

	gulp.task('patch', gulp.series(bump('patch'), 'build', 'git:commit_release','git:tag','git:push'));
	gulp.task('minor', gulp.series(bump('minor'), 'build', 'git:commit_release','git:tag','git:push'));
	gulp.task('major', gulp.series(bump('major'), 'build', 'git:commit_release','git:tag','git:push'));
}
<|endoftext|>