<commit_before>import L from 'leaflet';
import { featureCollection } from './FeatureCollection/FeatureCollection';
import { csvLayer } from './FeatureCollection/CSVLayer';
import { labelMarker } from './Label/LabelMarker';
import { pointLabelPos } from './Label/PointLabel';
import { polylineLabelPos } from './Label/PolylineLabel';
import { polygonLabelPos } from './Label/PolygonLabel';
import { createPopupContent } from './Popup/Popup';

export function operationalLayer (layer, layers, map, paneName) {
  return _generateEsriLayer(layer, layers, map, paneName);
}

export function _generateEsriLayer (layer, layers, map, paneName) {
  console.log('generateEsriLayer: ', layer.title, layer);
  var lyr;
  var labels = [];
  var labelsLayer;
  var labelPaneName = paneName + '-label';

  if (layer.featureCollection !== undefined) {
    console.log('create FeatureCollection');

    map.createPane(labelPaneName);

    labelsLayer = L.featureGroup(labels);
    lyr = featureCollection([], {
      data: layer.itemId || layer.featureCollection,
      opacity: layer.opacity,
      pane: paneName,
      onEachFeature: function (geojson, l) {
        if (layer.featureCollection.layers[0].popupInfo !== undefined) {
          var popupContent = createPopupContent(layer.featureCollection.layers[0].popupInfo, geojson.properties);
          l.bindPopup(popupContent);
        }
        if (layer.featureCollection.layers[0].layerDefinition.drawingInfo.labelingInfo !== undefined) {
          var labelingInfo = layer.featureCollection.layers[0].layerDefinition.drawingInfo.labelingInfo;
          var coordinates = l.feature.geometry.coordinates;
          var labelPos;

          if (l.feature.geometry.type === 'Point') {
            labelPos = pointLabelPos(coordinates);
          } else if (l.feature.geometry.type === 'LineString') {
            labelPos = polylineLabelPos(coordinates);
          } else if (l.feature.geometry.type === 'MultiLineString') {
            labelPos = polylineLabelPos(coordinates[Math.round(coordinates.length / 2)]);
          } else {
            labelPos = polygonLabelPos(l);
          }

          var label = labelMarker(labelPos.position, {
            zIndexOffset: 1,
            properties: geojson.properties,
            labelingInfo: labelingInfo,
            offset: labelPos.offset,
            pane: labelPaneName
          });

          labelsLayer.addLayer(label);
        }
      }
    });

    lyr = L.layerGroup([lyr, labelsLayer]);

    layers.push({ type: 'FC', title: layer.title || '', layer: lyr });

    return lyr;
  } else if (layer.type === 'Feature Collection') {
    console.log('create FeatureCollection without featureCollection property');
    lyr = featureCollection(null, {
      data: layer.itemId,
      pane: paneName,
      opacity: layer.opacity
    });

    return lyr;
  } else if (layer.layerType === 'ArcGISFeatureLayer' && layer.layerDefinition !== undefined) {
    var where = '1=1';
    if (layer.layerDefinition.drawingInfo !== undefined) {
      if (layer.layerDefinition.drawingInfo.renderer.type === 'heatmap') {
        console.log('create HeatmapLayer');
        var gradient = {};

        layer.layerDefinition.drawingInfo.renderer.colorStops.map(function (stop) {
          // gradient[stop.ratio] = 'rgba(' + stop.color[0] + ',' + stop.color[1] + ',' + stop.color[2] + ',' + (stop.color[3]/255) + ')';
          // gradient[Math.round(stop.ratio*100)/100] = 'rgb(' + stop.color[0] + ',' + stop.color[1] + ',' + stop.color[2] + ')';
          gradient[(Math.round(stop.ratio * 100) / 100 + 6) / 7] = 'rgb(' + stop.color[0] + ',' + stop.color[1] + ',' + stop.color[2] + ')';
        });

        lyr = L.esri.Heat.heatmapFeatureLayer({ // Esri Leaflet 2.0
        // lyr = L.esri.heatmapFeatureLayer({ // Esri Leaflet 1.0
          url: layer.url,
          minOpacity: 0.5,
          max: layer.layerDefinition.drawingInfo.renderer.maxPixelIntensity,
          blur: layer.layerDefinition.drawingInfo.renderer.blurRadius,
          radius: layer.layerDefinition.drawingInfo.renderer.blurRadius * 1.3,
          gradient: gradient,
          pane: paneName
        });

        layers.push({ type: 'HL', title: layer.title || '', layer: lyr });

        return lyr;
      } else {
        console.log('create ArcGISFeatureLayer (with layerDefinition.drawingInfo)');
        var drawingInfo = layer.layerDefinition.drawingInfo;
        drawingInfo.transparency = 100 - (layer.opacity * 100);
        console.log(drawingInfo.transparency);

        if (layer.layerDefinition.definitionExpression !== undefined) {
          where = layer.layerDefinition.definitionExpression;
        }

        map.createPane(labelPaneName);

        labelsLayer = L.featureGroup(labels);

        lyr = L.esri.featureLayer({
          url: layer.url,
          where: where,
          drawingInfo: drawingInfo,
          pane: paneName,
          onEachFeature: function (geojson, l) {
            if (layer.popupInfo !== undefined) {
              var popupContent = createPopupContent(layer.popupInfo, geojson.properties);
              l.bindPopup(popupContent);
            }
            if (layer.layerDefinition.drawingInfo.labelingInfo !== undefined) {
              var labelingInfo = layer.layerDefinition.drawingInfo.labelingInfo;
              var coordinates = l.feature.geometry.coordinates;
              var labelPos;

              if (l.feature.geometry.type === 'Point') {
                labelPos = pointLabelPos(coordinates);
              } else if (l.feature.geometry.type === 'LineString') {
                labelPos = polylineLabelPos(coordinates);
              } else if (l.feature.geometry.type === 'MultiLineString') {
                labelPos = polylineLabelPos(coordinates[Math.round(coordinates.length / 2)]);
              } else {
                labelPos = polygonLabelPos(l);
              }

              var label = labelMarker(labelPos.position, {
                zIndexOffset: 1,
                properties: geojson.properties,
                labelingInfo: labelingInfo,
                offset: labelPos.offset,
                pane: labelPaneName
              });

              labelsLayer.addLayer(label);
            }
          }
        });

        lyr = L.layerGroup([lyr, labelsLayer]);

        layers.push({ type: 'FL', title: layer.title || '', layer: lyr });

        return lyr;
      }
    } else {
      console.log('create ArcGISFeatureLayer (without layerDefinition.drawingInfo)');

      if (layer.layerDefinition.definitionExpression !== undefined) {
        where = layer.layerDefinition.definitionExpression;
      }

      lyr = L.esri.featureLayer({
        url: layer.url,
        where: where,
        pane: paneName,
        onEachFeature: function (geojson, l) {
          if (layer.popupInfo !== undefined) {
            var popupContent = createPopupContent(layer.popupInfo, geojson.properties);
            l.bindPopup(popupContent);
          }
        }
      });

      layers.push({ type: 'FL', title: layer.title || '', layer: lyr });

      return lyr;
    }
  } else if (layer.layerType === 'ArcGISFeatureLayer') {
    console.log('create ArcGISFeatureLayer');
    lyr = L.esri.featureLayer({
      url: layer.url,
      pane: paneName,
      onEachFeature: function (geojson, l) {
        if (layer.popupInfo !== undefined) {
          var popupContent = createPopupContent(layer.popupInfo, geojson.properties);
          l.bindPopup(popupContent);
        }
      }
    });

    layers.push({ type: 'FL', title: layer.title || '', layer: lyr });

    return lyr;
  } else if (layer.layerType === 'CSV') {
    labelsLayer = L.featureGroup(labels);
    lyr = csvLayer(null, {
      url: layer.url,
      layerDefinition: layer.layerDefinition,
      locationInfo: layer.locationInfo,
      opacity: layer.opacity,
      pane: paneName,
      onEachFeature: function (geojson, l) {
        if (layer.popupInfo !== undefined) {
          var popupContent = createPopupContent(layer.popupInfo, geojson.properties);
          l.bindPopup(popupContent);
        }
        if (layer.layerDefinition.drawingInfo.labelingInfo !== undefined) {
          var labelingInfo = layer.layerDefinition.drawingInfo.labelingInfo;
          var coordinates = l.feature.geometry.coordinates;
          var labelPos;

          if (l.feature.geometry.type === 'Point') {
            labelPos = pointLabelPos(coordinates);
          } else if (l.feature.geometry.type === 'LineString') {
            labelPos = polylineLabelPos(coordinates);
          } else if (l.feature.geometry.type === 'MultiLineString') {
            labelPos = polylineLabelPos(coordinates[Math.round(coordinates.length / 2)]);
          } else {
            labelPos = polygonLabelPos(l);
          }

          var label = labelMarker(labelPos.position, {
            zIndexOffset: 1,
            properties: geojson.properties,
            labelingInfo: labelingInfo,
            offset: labelPos.offset,
            pane: labelPaneName
          });

          labelsLayer.addLayer(label);
        }
      }
    });

    lyr = L.layerGroup([lyr, labelsLayer]);

    layers.push({ type: 'CSV', title: layer.title || '', layer: lyr });

    return lyr;
  } else if (layer.layerType === 'ArcGISImageServiceLayer') {
    console.log('create ArcGISImageServiceLayer');
    lyr = L.esri.imageMapLayer({
      url: layer.url,
      pane: paneName,
      opacity: layer.opacity || 1
    });

    layers.push({ type: 'IML', title: layer.title || '', layer: lyr });

    return lyr;
  } else if (layer.layerType === 'ArcGISMapServiceLayer') {
    lyr = L.esri.dynamicMapLayer({
      url: layer.url,
      pane: paneName,
      opacity: layer.opacity || 1
    });

    layers.push({ type: 'DML', title: layer.title || '', layer: lyr });

    return lyr;
  } else if (layer.layerType === 'ArcGISTiledMapServiceLayer') {
    try {
      lyr = L.esri.basemapLayer(layer.title);
    } catch (e) {
      lyr = L.esri.tiledMapLayer({
        url: layer.url
      });

      L.esri.request(layer.url, {}, function (err, res) {
        if (err) {
          console.log(err);
        } else {
          var maxWidth = (map.getSize().x - 55);
          var tiledAttribution = '' + res.copyrightText + '';
          map.attributionControl.addAttribution(tiledAttribution);
        }
      });
    }

    document.getElementsByClassName('leaflet-tile-pane')[0].style.opacity = layer.opacity || 1;

    layers.push({ type: 'TML', title: layer.title || '', layer: lyr });

    return lyr;
  } else if (layer.layerType === 'OpenStreetMap') {
    lyr = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
      attribution: '© OpenStreetMap contributors'
    });

    layers.push({ type: 'TL', title: layer.title || layer.id || '', layer: lyr });

    return lyr;
  } else if (layer.layerType === 'WebTiledLayer') {
    var lyrUrl = _esriWTLUrlTemplateToLeaflet(layer.templateUrl);
    lyr = L.tileLayer(lyrUrl, {
      attribution: layer.copyright
    });
    document.getElementsByClassName('leaflet-tile-pane')[0].style.opacity = layer.opacity || 1;

    layers.push({ type: 'TL', title: layer.title || layer.id || '', layer: lyr });

    return lyr;
  } else {
    lyr = L.featureGroup([]);
    console.log('Unsupported Layer: ', layer);
    return lyr;
  }
}

export function _esriWTLUrlTemplateToLeaflet (url) {
  var newUrl = url;

  newUrl = newUrl.replace(/\{level}/g, '{z}');
  newUrl = newUrl.replace(/\{col}/g, '{x}');
  newUrl = newUrl.replace(/\{row}/g, '{y}');

  return newUrl;
}

export var OperationalLayer = {
  operationalLayer: operationalLayer,
  _generateEsriLayer: _generateEsriLayer,
  _esriWTLUrlTemplateToLeaflet: _esriWTLUrlTemplateToLeaflet
};

export default OperationalLayer;
<commit_msg>add the case: labelingInfo is null<commit_after>import L from 'leaflet';
import { featureCollection } from './FeatureCollection/FeatureCollection';
import { csvLayer } from './FeatureCollection/CSVLayer';
import { labelMarker } from './Label/LabelMarker';
import { pointLabelPos } from './Label/PointLabel';
import { polylineLabelPos } from './Label/PolylineLabel';
import { polygonLabelPos } from './Label/PolygonLabel';
import { createPopupContent } from './Popup/Popup';

export function operationalLayer (layer, layers, map, paneName) {
  return _generateEsriLayer(layer, layers, map, paneName);
}

export function _generateEsriLayer (layer, layers, map, paneName) {
  console.log('generateEsriLayer: ', layer.title, layer);
  var lyr;
  var labels = [];
  var labelsLayer;
  var labelPaneName = paneName + '-label';

  if (layer.featureCollection !== undefined) {
    console.log('create FeatureCollection');

    map.createPane(labelPaneName);

    labelsLayer = L.featureGroup(labels);
    lyr = featureCollection([], {
      data: layer.itemId || layer.featureCollection,
      opacity: layer.opacity,
      pane: paneName,
      onEachFeature: function (geojson, l) {
        if (layer.featureCollection.layers[0].popupInfo !== undefined) {
          var popupContent = createPopupContent(layer.featureCollection.layers[0].popupInfo, geojson.properties);
          l.bindPopup(popupContent);
        }
        if (layer.featureCollection.layers[0].layerDefinition.drawingInfo.labelingInfo !== undefined || layer.featureCollection.layers[0].layerDefinition.drawingInfo.labelingInfo !== null) {
          var labelingInfo = layer.featureCollection.layers[0].layerDefinition.drawingInfo.labelingInfo;
          var coordinates = l.feature.geometry.coordinates;
          var labelPos;

          if (l.feature.geometry.type === 'Point') {
            labelPos = pointLabelPos(coordinates);
          } else if (l.feature.geometry.type === 'LineString') {
            labelPos = polylineLabelPos(coordinates);
          } else if (l.feature.geometry.type === 'MultiLineString') {
            labelPos = polylineLabelPos(coordinates[Math.round(coordinates.length / 2)]);
          } else {
            labelPos = polygonLabelPos(l);
          }

          var label = labelMarker(labelPos.position, {
            zIndexOffset: 1,
            properties: geojson.properties,
            labelingInfo: labelingInfo,
            offset: labelPos.offset,
            pane: labelPaneName
          });

          labelsLayer.addLayer(label);
        }
      }
    });

    lyr = L.layerGroup([lyr, labelsLayer]);

    layers.push({ type: 'FC', title: layer.title || '', layer: lyr });

    return lyr;
  } else if (layer.type === 'Feature Collection') {
    console.log('create FeatureCollection without featureCollection property');
    lyr = featureCollection(null, {
      data: layer.itemId,
      pane: paneName,
      opacity: layer.opacity
    });

    return lyr;
  } else if (layer.layerType === 'ArcGISFeatureLayer' && layer.layerDefinition !== undefined) {
    var where = '1=1';
    if (layer.layerDefinition.drawingInfo !== undefined) {
      if (layer.layerDefinition.drawingInfo.renderer.type === 'heatmap') {
        console.log('create HeatmapLayer');
        var gradient = {};

        layer.layerDefinition.drawingInfo.renderer.colorStops.map(function (stop) {
          // gradient[stop.ratio] = 'rgba(' + stop.color[0] + ',' + stop.color[1] + ',' + stop.color[2] + ',' + (stop.color[3]/255) + ')';
          // gradient[Math.round(stop.ratio*100)/100] = 'rgb(' + stop.color[0] + ',' + stop.color[1] + ',' + stop.color[2] + ')';
          gradient[(Math.round(stop.ratio * 100) / 100 + 6) / 7] = 'rgb(' + stop.color[0] + ',' + stop.color[1] + ',' + stop.color[2] + ')';
        });

        lyr = L.esri.Heat.heatmapFeatureLayer({ // Esri Leaflet 2.0
        // lyr = L.esri.heatmapFeatureLayer({ // Esri Leaflet 1.0
          url: layer.url,
          minOpacity: 0.5,
          max: layer.layerDefinition.drawingInfo.renderer.maxPixelIntensity,
          blur: layer.layerDefinition.drawingInfo.renderer.blurRadius,
          radius: layer.layerDefinition.drawingInfo.renderer.blurRadius * 1.3,
          gradient: gradient,
          pane: paneName
        });

        layers.push({ type: 'HL', title: layer.title || '', layer: lyr });

        return lyr;
      } else {
        console.log('create ArcGISFeatureLayer (with layerDefinition.drawingInfo)');
        var drawingInfo = layer.layerDefinition.drawingInfo;
        drawingInfo.transparency = 100 - (layer.opacity * 100);
        console.log(drawingInfo.transparency);

        if (layer.layerDefinition.definitionExpression !== undefined) {
          where = layer.layerDefinition.definitionExpression;
        }

        map.createPane(labelPaneName);

        labelsLayer = L.featureGroup(labels);

        lyr = L.esri.featureLayer({
          url: layer.url,
          where: where,
          drawingInfo: drawingInfo,
          pane: paneName,
          onEachFeature: function (geojson, l) {
            if (layer.popupInfo !== undefined) {
              var popupContent = createPopupContent(layer.popupInfo, geojson.properties);
              l.bindPopup(popupContent);
            }
            if (layer.layerDefinition.drawingInfo.labelingInfo !== undefined || layer.layerDefinition.drawingInfo.labelingInfo !== null) {
              var labelingInfo = layer.layerDefinition.drawingInfo.labelingInfo;
              var coordinates = l.feature.geometry.coordinates;
              var labelPos;

              if (l.feature.geometry.type === 'Point') {
                labelPos = pointLabelPos(coordinates);
              } else if (l.feature.geometry.type === 'LineString') {
                labelPos = polylineLabelPos(coordinates);
              } else if (l.feature.geometry.type === 'MultiLineString') {
                labelPos = polylineLabelPos(coordinates[Math.round(coordinates.length / 2)]);
              } else {
                labelPos = polygonLabelPos(l);
              }

              var label = labelMarker(labelPos.position, {
                zIndexOffset: 1,
                properties: geojson.properties,
                labelingInfo: labelingInfo,
                offset: labelPos.offset,
                pane: labelPaneName
              });

              labelsLayer.addLayer(label);
            }
          }
        });

        lyr = L.layerGroup([lyr, labelsLayer]);

        layers.push({ type: 'FL', title: layer.title || '', layer: lyr });

        return lyr;
      }
    } else {
      console.log('create ArcGISFeatureLayer (without layerDefinition.drawingInfo)');

      if (layer.layerDefinition.definitionExpression !== undefined) {
        where = layer.layerDefinition.definitionExpression;
      }

      lyr = L.esri.featureLayer({
        url: layer.url,
        where: where,
        pane: paneName,
        onEachFeature: function (geojson, l) {
          if (layer.popupInfo !== undefined) {
            var popupContent = createPopupContent(layer.popupInfo, geojson.properties);
            l.bindPopup(popupContent);
          }
        }
      });

      layers.push({ type: 'FL', title: layer.title || '', layer: lyr });

      return lyr;
    }
  } else if (layer.layerType === 'ArcGISFeatureLayer') {
    console.log('create ArcGISFeatureLayer');
    lyr = L.esri.featureLayer({
      url: layer.url,
      pane: paneName,
      onEachFeature: function (geojson, l) {
        if (layer.popupInfo !== undefined) {
          var popupContent = createPopupContent(layer.popupInfo, geojson.properties);
          l.bindPopup(popupContent);
        }
      }
    });

    layers.push({ type: 'FL', title: layer.title || '', layer: lyr });

    return lyr;
  } else if (layer.layerType === 'CSV') {
    labelsLayer = L.featureGroup(labels);
    lyr = csvLayer(null, {
      url: layer.url,
      layerDefinition: layer.layerDefinition,
      locationInfo: layer.locationInfo,
      opacity: layer.opacity,
      pane: paneName,
      onEachFeature: function (geojson, l) {
        if (layer.popupInfo !== undefined) {
          var popupContent = createPopupContent(layer.popupInfo, geojson.properties);
          l.bindPopup(popupContent);
        }
        if (layer.layerDefinition.drawingInfo.labelingInfo !== undefined || layer.layerDefinition.drawingInfo.labelingInfo !== null) {
          var labelingInfo = layer.layerDefinition.drawingInfo.labelingInfo;
          var coordinates = l.feature.geometry.coordinates;
          var labelPos;

          if (l.feature.geometry.type === 'Point') {
            labelPos = pointLabelPos(coordinates);
          } else if (l.feature.geometry.type === 'LineString') {
            labelPos = polylineLabelPos(coordinates);
          } else if (l.feature.geometry.type === 'MultiLineString') {
            labelPos = polylineLabelPos(coordinates[Math.round(coordinates.length / 2)]);
          } else {
            labelPos = polygonLabelPos(l);
          }

          var label = labelMarker(labelPos.position, {
            zIndexOffset: 1,
            properties: geojson.properties,
            labelingInfo: labelingInfo,
            offset: labelPos.offset,
            pane: labelPaneName
          });

          labelsLayer.addLayer(label);
        }
      }
    });

    lyr = L.layerGroup([lyr, labelsLayer]);

    layers.push({ type: 'CSV', title: layer.title || '', layer: lyr });

    return lyr;
  } else if (layer.layerType === 'ArcGISImageServiceLayer') {
    console.log('create ArcGISImageServiceLayer');
    lyr = L.esri.imageMapLayer({
      url: layer.url,
      pane: paneName,
      opacity: layer.opacity || 1
    });

    layers.push({ type: 'IML', title: layer.title || '', layer: lyr });

    return lyr;
  } else if (layer.layerType === 'ArcGISMapServiceLayer') {
    lyr = L.esri.dynamicMapLayer({
      url: layer.url,
      pane: paneName,
      opacity: layer.opacity || 1
    });

    layers.push({ type: 'DML', title: layer.title || '', layer: lyr });

    return lyr;
  } else if (layer.layerType === 'ArcGISTiledMapServiceLayer') {
    try {
      lyr = L.esri.basemapLayer(layer.title);
    } catch (e) {
      lyr = L.esri.tiledMapLayer({
        url: layer.url
      });

      L.esri.request(layer.url, {}, function (err, res) {
        if (err) {
          console.log(err);
        } else {
          var maxWidth = (map.getSize().x - 55);
          var tiledAttribution = '' + res.copyrightText + '';
          map.attributionControl.addAttribution(tiledAttribution);
        }
      });
    }

    document.getElementsByClassName('leaflet-tile-pane')[0].style.opacity = layer.opacity || 1;

    layers.push({ type: 'TML', title: layer.title || '', layer: lyr });

    return lyr;
  } else if (layer.layerType === 'OpenStreetMap') {
    lyr = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
      attribution: '© OpenStreetMap contributors'
    });

    layers.push({ type: 'TL', title: layer.title || layer.id || '', layer: lyr });

    return lyr;
  } else if (layer.layerType === 'WebTiledLayer') {
    var lyrUrl = _esriWTLUrlTemplateToLeaflet(layer.templateUrl);
    lyr = L.tileLayer(lyrUrl, {
      attribution: layer.copyright
    });
    document.getElementsByClassName('leaflet-tile-pane')[0].style.opacity = layer.opacity || 1;

    layers.push({ type: 'TL', title: layer.title || layer.id || '', layer: lyr });

    return lyr;
  } else {
    lyr = L.featureGroup([]);
    console.log('Unsupported Layer: ', layer);
    return lyr;
  }
}

export function _esriWTLUrlTemplateToLeaflet (url) {
  var newUrl = url;

  newUrl = newUrl.replace(/\{level}/g, '{z}');
  newUrl = newUrl.replace(/\{col}/g, '{x}');
  newUrl = newUrl.replace(/\{row}/g, '{y}');

  return newUrl;
}

export var OperationalLayer = {
  operationalLayer: operationalLayer,
  _generateEsriLayer: _generateEsriLayer,
  _esriWTLUrlTemplateToLeaflet: _esriWTLUrlTemplateToLeaflet
};

export default OperationalLayer;
<|endoftext|>


<commit_before>/**
 * @fileoverview Functions for handling the SPF config.
 *
 * @author nicksay@google.com (Alex Nicksay)
 */

goog.provide('spf.config');

goog.require('spf.state');

/**
 * Default configuration values.
 * @type {Object.<string, string|number|Function>}
 */
spf.config.defaults = {
  'animation-class': 'spf-animate',
  'animation-duration': 425,
  'cache-lifetime': 10 * 60 * 1000,  // 10 minute cache lifetime (ms).
  'cache-max': 50,  // 50 items.
  'cache-unified': false,
  'history-secure-functions': false,
  'link-class': 'spf-link',
  'nolink-class': 'spf-nolink',
  'navigate-limit': 20,  // 20 navigations per session.
  'navigate-lifetime': 24 * 60 * 60 * 1000,  // 1 day session lifetime (ms).
  'navigate-requested-callback': null,
  'navigate-part-received-callback': null,
  'navigate-part-processed-callback': null,
  'navigate-received-callback': null,
  'navigate-processed-callback': null,
  'navigate-error-callback': null,
  'prefetch-on-mousedown': false,
  'process-async': false,
  'request-timeout': 0,  // No request timeout.
  'script-loading-callback': null,
  'style-loading-callback': null,
  'url-identifier': '?spf=__type__'
};

/**
 * Checks whether a current configuration value exists.
 *
 * @param {string} name The configuration name.
 * @return {boolean} Whether the configuration value exists.
 */
spf.config.has = function(name) {
  var config = spf.config.config_();
  return name in config;
};

/**
 * Gets a current configuration value.
 *
 * @param {string} name The configuration name.
 * @return {*} The configuration value.
 */
spf.config.get = function(name) {
  var config = spf.config.config_();
  return config[name];
};

/**
 * Sets a current configuration value.
 *
 * @param {string} name The configuration name.
 * @param {*} value The configuration value.
 * @return {*} The configuration value.
 */
spf.config.set = function(name, value) {
  var config = spf.config.config_();
  config[name] = value;
  return value;
};

/**
 * Removes all data from the config.
 */
spf.config.clear = function() {
  spf.config.config_({});
};

/**
 * @param {!Object.<string, *>=} opt_config Optional config
 *     object to overwrite the current value.
 * @return {!Object.<string, *>} Current config object.
 * @private
 */
spf.config.config_ = function(opt_config) {
  if (opt_config || !spf.state.has('config')) {
    return /** @type {!Object.<string, *>} */ (
        spf.state.set('config', (opt_config || {})));
  }
  return /** @type {!Object.<string, *>} */ (
      spf.state.get('config'));
};
<commit_msg>SPF: Remove unused callback config keys now that the event-based API is launched<commit_after>/**
 * @fileoverview Functions for handling the SPF config.
 *
 * @author nicksay@google.com (Alex Nicksay)
 */

goog.provide('spf.config');

goog.require('spf.state');

/**
 * Default configuration values.
 * @type {Object.<string, string|number|Function>}
 */
spf.config.defaults = {
  'animation-class': 'spf-animate',
  'animation-duration': 425,
  'cache-lifetime': 10 * 60 * 1000,  // 10 minute cache lifetime (ms).
  'cache-max': 50,  // 50 items.
  'cache-unified': false,
  'history-secure-functions': false,
  'link-class': 'spf-link',
  'nolink-class': 'spf-nolink',
  'navigate-limit': 20,  // 20 navigations per session.
  'navigate-lifetime': 24 * 60 * 60 * 1000,  // 1 day session lifetime (ms).
  'prefetch-on-mousedown': false,
  'process-async': false,
  'request-timeout': 0,  // No request timeout.
  'url-identifier': '?spf=__type__'
};

/**
 * Checks whether a current configuration value exists.
 *
 * @param {string} name The configuration name.
 * @return {boolean} Whether the configuration value exists.
 */
spf.config.has = function(name) {
  var config = spf.config.config_();
  return name in config;
};

/**
 * Gets a current configuration value.
 *
 * @param {string} name The configuration name.
 * @return {*} The configuration value.
 */
spf.config.get = function(name) {
  var config = spf.config.config_();
  return config[name];
};

/**
 * Sets a current configuration value.
 *
 * @param {string} name The configuration name.
 * @param {*} value The configuration value.
 * @return {*} The configuration value.
 */
spf.config.set = function(name, value) {
  var config = spf.config.config_();
  config[name] = value;
  return value;
};

/**
 * Removes all data from the config.
 */
spf.config.clear = function() {
  spf.config.config_({});
};

/**
 * @param {!Object.<string, *>=} opt_config Optional config
 *     object to overwrite the current value.
 * @return {!Object.<string, *>} Current config object.
 * @private
 */
spf.config.config_ = function(opt_config) {
  if (opt_config || !spf.state.has('config')) {
    return /** @type {!Object.<string, *>} */ (
        spf.state.set('config', (opt_config || {})));
  }
  return /** @type {!Object.<string, *>} */ (
      spf.state.get('config'));
};
<|endoftext|>


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

/**
 * A module of methods for object that you want to be able to listen to.
 * This module is consumed by `createStore` and `createAction`
 */
module.exports = {

    /**
     * Hook used by the publisher that is invoked before emitting
     * and before `shouldEmit`. The arguments are the ones that the action
     * is invoked with. If this function returns something other than
     * undefined, that will be passed on as arguments for shouldEmit and
     * emission.
     */
    preEmit: function() {},

    /**
     * Hook used by the publisher after `preEmit` to determine if the
     * event should be emitted with given arguments. This may be overridden
     * in your application, default implementation always returns true.
     *
     * @returns {Boolean} true if event should be emitted
     */
    shouldEmit: function() { return true; },

    /**
     * Subscribes the given callback for action triggered
     *
     * @param {Function} callback The callback to register as event handler
     * @param {Mixed} [optional] bindContext The context to bind the callback with
     * @returns {Function} Callback that unsubscribes the registered event handler
     */
    listen: function(callback, bindContext) {
        bindContext = bindContext || this;
        var eventHandler = function(args) {
            callback.apply(bindContext, args);
        }, me = this;
        this.emitter.addListener(this.eventLabel, eventHandler);
        return function() {
            me.emitter.removeListener(me.eventLabel, eventHandler);
        };
    },

    /**
     * Attach handlers to promise that trigger the completed and failed
     * child publishers, if available.
     *
     * @param {Object} The promise to attach to
     */
    promise: function(promise) {
        var me = this;

        var canHandlePromise =
            this.children.indexOf('completed') >= 0 &&
            this.children.indexOf('failed') >= 0;

        if (!canHandlePromise){
            throw new Error('Publisher must have "completed" and "failed" child publishers');
        }

        promise.then(function(response) {
            return me.completed(response);
        });
        // IE compatibility - catch is a reserved word - without bracket notation source compilation will fail under IE
        promise["catch"](function(error) {
            return me.failed(error);
        });
    },

    /**
     * Subscribes the given callback for action triggered, which should
     * return a promise that in turn is passed to `this.promise`
     *
     * @param {Function} callback The callback to register as event handler
     */
    listenAndPromise: function(callback, bindContext) {
        var me = this;
        bindContext = bindContext || this;

        return this.listen(function() {

            if (!callback) {
                throw new Error('Expected a function returning a promise but got ' + callback);
            }

            var args = arguments,
                promise = callback.apply(bindContext, args);
            return me.promise.call(me, promise);
        }, bindContext);
    },

    /**
     * Publishes an event using `this.emitter` (if `shouldEmit` agrees)
     */
    trigger: function() {
        var args = arguments,
            pre = this.preEmit.apply(this, args);
        args = pre === undefined ? args : _.isArguments(pre) ? pre : [].concat(pre);
        if (this.shouldEmit.apply(this, args)) {
            this.emitter.emit(this.eventLabel, args);
        }
    },

    /**
     * Tries to publish the event on the next tick
     */
    triggerAsync: function(){
        var args = arguments,me = this;
        _.nextTick(function() {
            me.trigger.apply(me, args);
        });
    },

    /**
     * Returns a Promise for the triggered action
     */
    triggerPromise: function(){
        var me = this;
        var args = arguments;

        var canHandlePromise =
            this.children.indexOf('completed') >= 0 &&
            this.children.indexOf('failed') >= 0;

        var promise = _.createPromise(function(resolve, reject) {
            if (canHandlePromise) {
                var removeSuccess = me.completed.listen(function(args) {
                    removeSuccess();
                    removeFailed();
                    resolve(args);
                });

                var removeFailed = me.failed.listen(function(args) {
                    removeSuccess();
                    removeFailed();
                    reject(args);
                });
            }

            me.triggerAsync.apply(me, args);

            if (!canHandlePromise) {
                resolve();
            }
        });

        return promise;
    },
};
<commit_msg>Fixed catch() call in PublisherMethods.promise()<commit_after>var _ = require('./utils');

/**
 * A module of methods for object that you want to be able to listen to.
 * This module is consumed by `createStore` and `createAction`
 */
module.exports = {

    /**
     * Hook used by the publisher that is invoked before emitting
     * and before `shouldEmit`. The arguments are the ones that the action
     * is invoked with. If this function returns something other than
     * undefined, that will be passed on as arguments for shouldEmit and
     * emission.
     */
    preEmit: function() {},

    /**
     * Hook used by the publisher after `preEmit` to determine if the
     * event should be emitted with given arguments. This may be overridden
     * in your application, default implementation always returns true.
     *
     * @returns {Boolean} true if event should be emitted
     */
    shouldEmit: function() { return true; },

    /**
     * Subscribes the given callback for action triggered
     *
     * @param {Function} callback The callback to register as event handler
     * @param {Mixed} [optional] bindContext The context to bind the callback with
     * @returns {Function} Callback that unsubscribes the registered event handler
     */
    listen: function(callback, bindContext) {
        bindContext = bindContext || this;
        var eventHandler = function(args) {
            callback.apply(bindContext, args);
        }, me = this;
        this.emitter.addListener(this.eventLabel, eventHandler);
        return function() {
            me.emitter.removeListener(me.eventLabel, eventHandler);
        };
    },

    /**
     * Attach handlers to promise that trigger the completed and failed
     * child publishers, if available.
     *
     * @param {Object} The promise to attach to
     */
    promise: function(promise) {
        var me = this;

        var canHandlePromise =
            this.children.indexOf('completed') >= 0 &&
            this.children.indexOf('failed') >= 0;

        if (!canHandlePromise){
            throw new Error('Publisher must have "completed" and "failed" child publishers');
        }

        promise.then(function(response) {
            return me.completed(response);
        }, function(error) {
            return me.failed(error);
        });
    },

    /**
     * Subscribes the given callback for action triggered, which should
     * return a promise that in turn is passed to `this.promise`
     *
     * @param {Function} callback The callback to register as event handler
     */
    listenAndPromise: function(callback, bindContext) {
        var me = this;
        bindContext = bindContext || this;

        return this.listen(function() {

            if (!callback) {
                throw new Error('Expected a function returning a promise but got ' + callback);
            }

            var args = arguments,
                promise = callback.apply(bindContext, args);
            return me.promise.call(me, promise);
        }, bindContext);
    },

    /**
     * Publishes an event using `this.emitter` (if `shouldEmit` agrees)
     */
    trigger: function() {
        var args = arguments,
            pre = this.preEmit.apply(this, args);
        args = pre === undefined ? args : _.isArguments(pre) ? pre : [].concat(pre);
        if (this.shouldEmit.apply(this, args)) {
            this.emitter.emit(this.eventLabel, args);
        }
    },

    /**
     * Tries to publish the event on the next tick
     */
    triggerAsync: function(){
        var args = arguments,me = this;
        _.nextTick(function() {
            me.trigger.apply(me, args);
        });
    },

    /**
     * Returns a Promise for the triggered action
     */
    triggerPromise: function(){
        var me = this;
        var args = arguments;

        var canHandlePromise =
            this.children.indexOf('completed') >= 0 &&
            this.children.indexOf('failed') >= 0;

        var promise = _.createPromise(function(resolve, reject) {
            if (canHandlePromise) {
                var removeSuccess = me.completed.listen(function(args) {
                    removeSuccess();
                    removeFailed();
                    resolve(args);
                });

                var removeFailed = me.failed.listen(function(args) {
                    removeSuccess();
                    removeFailed();
                    reject(args);
                });
            }

            me.triggerAsync.apply(me, args);

            if (!canHandlePromise) {
                resolve();
            }
        });

        return promise;
    },
};
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import * as placeholders from './placeholders';

export default class ReactPlaceholder extends React.Component {

  static propTypes = {
    children: PropTypes.oneOfType([
      PropTypes.node,
      PropTypes.element
    ]).isRequired,
    delay: PropTypes.number,
    ready: PropTypes.bool.isRequired,
    firstLaunchOnly: PropTypes.bool,
    type: PropTypes.oneOf(['text', 'media', 'textRow', 'rect', 'round']),
    rows: PropTypes.number,
    color: PropTypes.string,
    showLoadingAnimation: PropTypes.bool,
    customPlaceholder: PropTypes.oneOfType([
      PropTypes.node,
      PropTypes.element
    ])
  }

  static defaultProps = {
    delay: 0,
    type: 'text',
    color: '#CDCDCD'
  }

  state = {
    ready: this.props.ready
  }

  getFiller = () => {
    const {
      firstLaunchOnly, children, ready, className, // eslint-disable-line no-unused-vars
      type, customPlaceholder, showLoadingAnimation, ...rest
    } = this.props;

    const classes = showLoadingAnimation ?
      ['show-loading-animation', className].filter(c => c).join(' ') :
      className;

    if (customPlaceholder && React.isValidElement(customPlaceholder)) {
      const mergedCustomClasses = [
        customPlaceholder.props.className,
        classes
      ].filter(c => c).join(' ');
      return React.cloneElement(customPlaceholder, { className: mergedCustomClasses });
    } else if (customPlaceholder) {
      return customPlaceholder;
    }

    const Placeholder = placeholders[type];

    return <Placeholder {...rest} className={classes} />;
  };

  setNotReady = () => {
    this.timeout = setTimeout(() => {
      this.setState({ ready: false });
    }, this.props.delay);
  }

  setReady = () => {
    clearTimeout(this.timeout);

    if (!this.state.ready) {
      this.setState({ ready: true });
    }
  }

  render() {
    return this.state.ready ? this.props.children : this.getFiller();
  }

  componentWillReceiveProps(nextProps) {
    if (!this.props.firstLaunchOnly && this.state.ready && !nextProps.ready) {
      this.setNotReady();
    } else if (nextProps.ready) {
      this.setReady();
    }
  }
}
<commit_msg>bypass setTimeout if no delay is specified<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import * as placeholders from './placeholders';

export default class ReactPlaceholder extends React.Component {

  static propTypes = {
    children: PropTypes.oneOfType([
      PropTypes.node,
      PropTypes.element
    ]).isRequired,
    delay: PropTypes.number,
    ready: PropTypes.bool.isRequired,
    firstLaunchOnly: PropTypes.bool,
    type: PropTypes.oneOf(['text', 'media', 'textRow', 'rect', 'round']),
    rows: PropTypes.number,
    color: PropTypes.string,
    showLoadingAnimation: PropTypes.bool,
    customPlaceholder: PropTypes.oneOfType([
      PropTypes.node,
      PropTypes.element
    ])
  }

  static defaultProps = {
    delay: 0,
    type: 'text',
    color: '#CDCDCD'
  }

  state = {
    ready: this.props.ready
  }

  getFiller = () => {
    const {
      firstLaunchOnly, children, ready, className, // eslint-disable-line no-unused-vars
      type, customPlaceholder, showLoadingAnimation, ...rest
    } = this.props;

    const classes = showLoadingAnimation ?
      ['show-loading-animation', className].filter(c => c).join(' ') :
      className;

    if (customPlaceholder && React.isValidElement(customPlaceholder)) {
      const mergedCustomClasses = [
        customPlaceholder.props.className,
        classes
      ].filter(c => c).join(' ');
      return React.cloneElement(customPlaceholder, { className: mergedCustomClasses });
    } else if (customPlaceholder) {
      return customPlaceholder;
    }

    const Placeholder = placeholders[type];

    return <Placeholder {...rest} className={classes} />;
  };

  setNotReady = () => {
    const { delay } = this.props;

    if (delay > 0) {
      this.timeout = setTimeout(() => {
        this.setState({ ready: false });
      }, delay);
    } else {
      this.setState({ ready: false });
    }
  }

  setReady = () => {
    if (this.timeout) {
      clearTimeout(this.timeout);
    }

    if (!this.state.ready) {
      this.setState({ ready: true });
    }
  }

  render() {
    return this.state.ready ? this.props.children : this.getFiller();
  }

  componentWillReceiveProps(nextProps) {
    if (!this.props.firstLaunchOnly && this.state.ready && !nextProps.ready) {
      this.setNotReady();
    } else if (nextProps.ready) {
      this.setReady();
    }
  }
}
<|endoftext|>


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

module.exports = new (function() {
    this.parse = function(html, callback) {

        var $ = cheerio.load(html);

        var menu = new Array();
        var soupPattern = new RegExp("[0-9,]+l?$");

        var dnesneMenu = $('.jedlo_polozka', '.dnesne_menu');
        if (dnesneMenu.length == 1)
        {
            menu.push("Dnes nie je menu");
        }
        else
        {
            dnesneMenu.each(function() {
                if ($(this).find('b').length === 0)
                    menu.push($(this).text());
            });
        }
        //convert to menu item object
        menu = menu.map(function(item) {
            return { isSoup: soupPattern.test(item.trim()), text: normalize(item), price: NaN };
        });

        callback(menu);

        function normalize(str) {
            return str.normalizeWhitespace()
                .replace(soupPattern,'')
                .removeMetrics()
                .correctCommaSpacing()
                .removeItemNumbering();
        }
    };
})();<commit_msg>fixes #59<commit_after>var cheerio = require('cheerio');
var parserUtil = require('./parserUtil');

module.exports = new (function() {
    this.parse = function(html, callback) {

        var $ = cheerio.load(html);

        var menu = new Array();
        var soupPattern = /0[\.,]\d+\s?l?$/;

        var dnesneMenu = $('.jedlo_polozka', '.dnesne_menu');
        if (dnesneMenu.length == 1)
        {
            menu.push("Dnes nie je menu");
        }
        else
        {
            dnesneMenu.each(function() {
                if ($(this).find('b').length === 0)
                    menu.push($(this).text());
            });
        }
        //convert to menu item object
        menu = menu.map(function(item) {
            return { isSoup: soupPattern.test(item.trim()), text: normalize(item), price: NaN };
        });

        callback(menu);

        function normalize(str) {
            return str.normalizeWhitespace()
                .replace(soupPattern,'')
                .removeMetrics()
                .correctCommaSpacing()
                .removeItemNumbering();
        }
    };
})();<|endoftext|>


<commit_before>/**
* _Internal Class_, not generally used outside of the engine's internals.
*
* @class SAT
*/

// TODO: true circles and curves

var SAT = {};

(function() {

    /**
     * Description
     * @method collides
     * @param {body} bodyA
     * @param {body} bodyB
     * @param {collision} previousCollision
     * @return {collision} collision
     */
    SAT.collides = function(bodyA, bodyB, previousCollision) {
        var overlapAB,
            overlapBA,
            minOverlap,
            collision,
            prevCol = previousCollision,
            canReusePrevCol = false;

        if (prevCol) {
            // estimate total motion
            var motion = bodyA.speed * bodyA.speed + bodyA.angularSpeed * bodyA.angularSpeed
                       + bodyB.speed * bodyB.speed + bodyB.angularSpeed * bodyB.angularSpeed;

            // we may be able to (partially) reuse collision result
            // but only safe if collision was resting
            canReusePrevCol = prevCol && prevCol.collided && motion < 0.2;

            // reuse collision object
            collision = prevCol;
        } else {
            collision = { collided: false, bodyA: bodyA, bodyB: bodyB };
        }

        if (prevCol && canReusePrevCol) {
            // if we can reuse the collision result
            // we only need to test the previously found axis
            var axes = [prevCol.bodyA.axes[prevCol.axisNumber]];

            minOverlap = _overlapAxes(prevCol.bodyA.vertices, prevCol.bodyB.vertices, axes);
            collision.reused = true;

            if (minOverlap.overlap <= 0) {
                collision.collided = false;
                return collision;
            }
        } else {
            // if we can't reuse a result, perform a full SAT test

            overlapAB = _overlapAxes(bodyA.vertices, bodyB.vertices, bodyA.axes);

            if (overlapAB.overlap <= 0) {
                collision.collided = false;
                return collision;
            }

            overlapBA = _overlapAxes(bodyB.vertices, bodyA.vertices, bodyB.axes);

            if (overlapBA.overlap <= 0) {
                collision.collided = false;
                return collision;
            }

            if (overlapAB.overlap < overlapBA.overlap) {
                minOverlap = overlapAB;
                collision.bodyA = bodyA;
                collision.bodyB = bodyB;
            } else {
                minOverlap = overlapBA;
                collision.bodyA = bodyB;
                collision.bodyB = bodyA;
            }

            // important for reuse later
            collision.axisNumber = minOverlap.axisNumber;
        }

        collision.collided = true;
        collision.normal = minOverlap.axis;
        collision.depth = minOverlap.overlap;

        bodyA = collision.bodyA;
        bodyB = collision.bodyB;

        // ensure normal is facing away from bodyA
        if (Vector.dot(collision.normal, Vector.sub(bodyB.position, bodyA.position)) > 0)
            collision.normal = Vector.neg(collision.normal);

        collision.tangent = Vector.perp(collision.normal);

        collision.penetration = {
            x: collision.normal.x * collision.depth,
            y: collision.normal.y * collision.depth
        };

        // find support points, there is always either exactly one or two
        var verticesB = _findSupports(bodyA, bodyB, collision.normal),
            supports = [verticesB[0]];

        if (Vertices.contains(bodyA.vertices, verticesB[1])) {
            supports.push(verticesB[1]);
        } else {
            var verticesA = _findSupports(bodyB, bodyA, Vector.neg(collision.normal));

            if (Vertices.contains(bodyB.vertices, verticesA[0])) {
                supports.push(verticesA[0]);
            }

            if (supports.length < 2 && Vertices.contains(bodyB.vertices, verticesA[1])) {
                supports.push(verticesA[1]);
            }
        }

        collision.supports = supports;
        collision.supportCorrected = Vector.sub(verticesB[0], collision.penetration);

        return collision;
    };

    /**
     * Description
     * @method _overlapAxes
     * @private
     * @param {} verticesA
     * @param {} verticesB
     * @param {} axes
     * @return result
     */
    var _overlapAxes = function(verticesA, verticesB, axes) {
        var projectionA = {},
            projectionB = {},
            result = { overlap: Number.MAX_VALUE },
            overlap,
            axis;

        for (var i = 0; i < axes.length; i++) {
            axis = axes[i];

            _projectToAxis(projectionA, verticesA, axis);
            _projectToAxis(projectionB, verticesB, axis);

            overlap = projectionA.min < projectionB.min
                        ? projectionA.max - projectionB.min
                        : projectionB.max - projectionA.min;

            if (overlap <= 0) {
                result.overlap = overlap;
                return result;
            }

            if (overlap < result.overlap) {
                result.overlap = overlap;
                result.axis = axis;
                result.axisNumber = i;
            }
        }

        return result;
    };

    /**
     * Description
     * @method _projectToAxis
     * @private
     * @param {} projection
     * @param {} vertices
     * @param {} axis
     */
    var _projectToAxis = function(projection, vertices, axis) {
        var min = Vector.dot(vertices[0], axis),
            max = min;

        for (var i = 1; i < vertices.length; i += 1) {
            var dot = Vector.dot(vertices[i], axis);

            if (dot > max) {
                max = dot;
            } else if (dot < min) {
                min = dot;
            }
        }

        projection.min = min;
        projection.max = max;
    };

    /**
     * Description
     * @method _findSupports
     * @private
     * @param {} bodyA
     * @param {} bodyB
     * @param {} normal
     * @return ArrayExpression
     */
    var _findSupports = function(bodyA, bodyB, normal) {
        var nearestDistance = Number.MAX_VALUE,
            vertexToBody = { x: 0, y: 0 },
            vertices = bodyB.vertices,
            bodyAPosition = bodyA.position,
            distance,
            vertex,
            vertexA = vertices[0],
            vertexB = vertices[1];

        // find closest vertex on bodyB
        for (var i = 0; i < vertices.length; i++) {
            vertex = vertices[i];
            vertexToBody.x = vertex.x - bodyAPosition.x;
            vertexToBody.y = vertex.y - bodyAPosition.y;
            distance = -Vector.dot(normal, vertexToBody);

            if (distance < nearestDistance) {
                nearestDistance = distance;
                vertexA = vertex;
            }
        }

        // find next closest vertex using the two connected to it
        var prevIndex = vertexA.index - 1 >= 0 ? vertexA.index - 1 : vertices.length - 1;
        vertex = vertices[prevIndex];
        vertexToBody.x = vertex.x - bodyAPosition.x;
        vertexToBody.y = vertex.y - bodyAPosition.y;
        nearestDistance = -Vector.dot(normal, vertexToBody);
        vertexB = vertex;

        var nextIndex = (vertexA.index + 1) % vertices.length;
        vertex = vertices[nextIndex];
        vertexToBody.x = vertex.x - bodyAPosition.x;
        vertexToBody.y = vertex.y - bodyAPosition.y;
        distance = -Vector.dot(normal, vertexToBody);
        if (distance < nearestDistance) {
            nearestDistance = distance;
            vertexB = vertex;
        }

        return [vertexA, vertexB];
    };

})();<commit_msg>fixed collision detection issue, closes #12<commit_after>/**
* _Internal Class_, not generally used outside of the engine's internals.
*
* @class SAT
*/

// TODO: true circles and curves

var SAT = {};

(function() {

    /**
     * Description
     * @method collides
     * @param {body} bodyA
     * @param {body} bodyB
     * @param {collision} previousCollision
     * @return {collision} collision
     */
    SAT.collides = function(bodyA, bodyB, previousCollision) {
        var overlapAB,
            overlapBA,
            minOverlap,
            collision,
            prevCol = previousCollision,
            canReusePrevCol = false;

        if (prevCol) {
            // estimate total motion
            var motion = bodyA.speed * bodyA.speed + bodyA.angularSpeed * bodyA.angularSpeed
                       + bodyB.speed * bodyB.speed + bodyB.angularSpeed * bodyB.angularSpeed;

            // we may be able to (partially) reuse collision result
            // but only safe if collision was resting
            canReusePrevCol = prevCol && prevCol.collided && motion < 0.2;

            // reuse collision object
            collision = prevCol;
        } else {
            collision = { collided: false, bodyA: bodyA, bodyB: bodyB };
        }

        if (prevCol && canReusePrevCol) {
            // if we can reuse the collision result
            // we only need to test the previously found axis
            var axes = [prevCol.bodyA.axes[prevCol.axisNumber]];

            minOverlap = _overlapAxes(prevCol.bodyA.vertices, prevCol.bodyB.vertices, axes);
            collision.reused = true;

            if (minOverlap.overlap <= 0) {
                collision.collided = false;
                return collision;
            }
        } else {
            // if we can't reuse a result, perform a full SAT test

            overlapAB = _overlapAxes(bodyA.vertices, bodyB.vertices, bodyA.axes);

            if (overlapAB.overlap <= 0) {
                collision.collided = false;
                return collision;
            }

            overlapBA = _overlapAxes(bodyB.vertices, bodyA.vertices, bodyB.axes);

            if (overlapBA.overlap <= 0) {
                collision.collided = false;
                return collision;
            }

            if (overlapAB.overlap < overlapBA.overlap) {
                minOverlap = overlapAB;
                collision.bodyA = bodyA;
                collision.bodyB = bodyB;
            } else {
                minOverlap = overlapBA;
                collision.bodyA = bodyB;
                collision.bodyB = bodyA;
            }

            // important for reuse later
            collision.axisNumber = minOverlap.axisNumber;
        }

        collision.collided = true;
        collision.normal = minOverlap.axis;
        collision.depth = minOverlap.overlap;

        bodyA = collision.bodyA;
        bodyB = collision.bodyB;

        // ensure normal is facing away from bodyA
        if (Vector.dot(collision.normal, Vector.sub(bodyB.position, bodyA.position)) > 0)
            collision.normal = Vector.neg(collision.normal);

        collision.tangent = Vector.perp(collision.normal);

        collision.penetration = {
            x: collision.normal.x * collision.depth,
            y: collision.normal.y * collision.depth
        };

        // find support points, there is always either exactly one or two
        var verticesB = _findSupports(bodyA, bodyB, collision.normal),
            supports = collision.supports || [];
        supports.length = 0;

        // find the supports from bodyB that are inside bodyA
        if (Vertices.contains(bodyA.vertices, verticesB[0]))
            supports.push(verticesB[0]);

        if (Vertices.contains(bodyA.vertices, verticesB[1]))
            supports.push(verticesB[1]);

        // find the supports from bodyA that are inside bodyB
        if (supports.length < 2) {
            var verticesA = _findSupports(bodyB, bodyA, Vector.neg(collision.normal));

            if (Vertices.contains(bodyB.vertices, verticesA[0]))
                supports.push(verticesA[0]);

            if (supports.length < 2 && Vertices.contains(bodyB.vertices, verticesA[1]))
                supports.push(verticesA[1]);
        }

        // account for the edge case of overlapping but no vertex containment
        if (supports.length < 2)
            supports = [verticesB[0]];

        collision.supports = supports;
        collision.supportCorrected = Vector.sub(supports[0], collision.penetration);

        return collision;
    };

    /**
     * Description
     * @method _overlapAxes
     * @private
     * @param {} verticesA
     * @param {} verticesB
     * @param {} axes
     * @return result
     */
    var _overlapAxes = function(verticesA, verticesB, axes) {
        var projectionA = {},
            projectionB = {},
            result = { overlap: Number.MAX_VALUE },
            overlap,
            axis;

        for (var i = 0; i < axes.length; i++) {
            axis = axes[i];

            _projectToAxis(projectionA, verticesA, axis);
            _projectToAxis(projectionB, verticesB, axis);

            overlap = projectionA.min < projectionB.min
                        ? projectionA.max - projectionB.min
                        : projectionB.max - projectionA.min;

            if (overlap <= 0) {
                result.overlap = overlap;
                return result;
            }

            if (overlap < result.overlap) {
                result.overlap = overlap;
                result.axis = axis;
                result.axisNumber = i;
            }
        }

        return result;
    };

    /**
     * Description
     * @method _projectToAxis
     * @private
     * @param {} projection
     * @param {} vertices
     * @param {} axis
     */
    var _projectToAxis = function(projection, vertices, axis) {
        var min = Vector.dot(vertices[0], axis),
            max = min;

        for (var i = 1; i < vertices.length; i += 1) {
            var dot = Vector.dot(vertices[i], axis);

            if (dot > max) {
                max = dot;
            } else if (dot < min) {
                min = dot;
            }
        }

        projection.min = min;
        projection.max = max;
    };

    /**
     * Description
     * @method _findSupports
     * @private
     * @param {} bodyA
     * @param {} bodyB
     * @param {} normal
     * @return ArrayExpression
     */
    var _findSupports = function(bodyA, bodyB, normal) {
        var nearestDistance = Number.MAX_VALUE,
            vertexToBody = { x: 0, y: 0 },
            vertices = bodyB.vertices,
            bodyAPosition = bodyA.position,
            distance,
            vertex,
            vertexA = vertices[0],
            vertexB = vertices[1];

        // find closest vertex on bodyB
        for (var i = 0; i < vertices.length; i++) {
            vertex = vertices[i];
            vertexToBody.x = vertex.x - bodyAPosition.x;
            vertexToBody.y = vertex.y - bodyAPosition.y;
            distance = -Vector.dot(normal, vertexToBody);

            if (distance < nearestDistance) {
                nearestDistance = distance;
                vertexA = vertex;
            }
        }

        // find next closest vertex using the two connected to it
        var prevIndex = vertexA.index - 1 >= 0 ? vertexA.index - 1 : vertices.length - 1;
        vertex = vertices[prevIndex];
        vertexToBody.x = vertex.x - bodyAPosition.x;
        vertexToBody.y = vertex.y - bodyAPosition.y;
        nearestDistance = -Vector.dot(normal, vertexToBody);
        vertexB = vertex;

        var nextIndex = (vertexA.index + 1) % vertices.length;
        vertex = vertices[nextIndex];
        vertexToBody.x = vertex.x - bodyAPosition.x;
        vertexToBody.y = vertex.y - bodyAPosition.y;
        distance = -Vector.dot(normal, vertexToBody);
        if (distance < nearestDistance) {
            nearestDistance = distance;
            vertexB = vertex;
        }

        return [vertexA, vertexB];
    };

})();<|endoftext|>


<commit_before>/**
 * Wrapper to manage services via PM2
 */
var _ = require('lodash');
var path = require('path');
var pm2 = require('pm2');

require('colors');

function Runner() {
}

Runner.prototype.init = function(bosco, next) {
  this.bosco = bosco;
  pm2.connect(next);
};

Runner.prototype.disconnect = function(next) {
  pm2.disconnect(next);
};

/**
 * List running services
 */
Runner.prototype.listRunning = function(detailed, next) {
  pm2.list(function(err, list) {
    var filteredList = _.filter(list, function(pm2Process) { return pm2Process.pm2_env.status === 'online' || pm2Process.pm2_env.status === 'errored'; });

    if (!detailed) return next(err, _.pluck(filteredList, 'name'));
    next(err, filteredList);
  });
};

/**
 * List services that have been created but are not running
 */
Runner.prototype.listNotRunning = function(detailed, next) {
  pm2.list(function(err, list) {
    var filteredList = _.filter(list, function(pm2Process) { return pm2Process.pm2_env.status !== 'online'; });

    if (!detailed) return next(err, _.pluck(filteredList, 'name'));
    next(err, filteredList);
  });
};

Runner.prototype.getInterpreter = function(bosco, options, next) {
  var self = this;
  var exec = require('child_process').exec;
  var interpreter;
  var hadError;
  var error;
  var installing;
  var found = false;
  var hasNvmRc = bosco.exists(path.join(options.cwd, '.nvmrc'));
  if (hasNvmRc) {
    var e = exec(bosco.options.nvmWhich, {cwd: options.cwd});

    e.stdout.on('data', function(data) {
      if (data.indexOf('Found') === 0) {
        found = true;
      } else {
        if (found) {
          interpreter = data.replace('\n', '');
        }
      }
    });

    e.stderr.on('data', function(data) {
      if (!hadError) {
        hadError = true;
        if (data.startsWith('No .nvmrc file found')) {
          // Use default
        } else {
          error = options.name + ' nvm failed with: ' + data.replace('\n', '') + ', use -i option to install missing node versions!';
          if (bosco.options['install-missing']) {
            installing = true;
            self.installNode(bosco, options, function(err) {
              if (err) return next(err);
              self.getInterpreter(bosco, options, next);
            });
          }
        }
      }
    });

    e.on('exit', function() {
      if (interpreter) {
        bosco.log(options.name + ' using .nvmrc: ' + interpreter.cyan);
      }
      if (!installing) {
        return next(error, interpreter);
      }
    });
  } else {
    bosco.log(options.name + ' no .nvmrc found, using nvm default ...');
    next();
  }
};

Runner.prototype.installNode = function(bosco, options, next) {
  var exec = require('child_process').exec;
  bosco.log(options.name + ' installing required node version ...');
  var hasNvmRc = bosco.exists(path.join(options.cwd, '.nvmrc'));
  if (hasNvmRc) {
    exec(bosco.options.nvmInstall, {cwd: options.cwd}, function(err, stdout, stderr) {
      next(stderr);
    });
  } else {
    next('You cant install node without an .nvmrc');
  }
};

/**
 * Start a specific service
 * options = {cmd, cwd, name}
 */
Runner.prototype.start = function(options, next) {
  var self = this;

  // Remove node from the start script as not req'd for PM2
  var startCmd = options.service.start;
  var start = startCmd;
  var startArr;

  if (startCmd.split(' ')[0] === 'node') {
    startArr = startCmd.split(' ');
    startArr.shift();
    start = startArr.join(' ');

    if (!path.extname(start)) start = start + '.js';
  }

  // Always execute as a forked process to allow node version selection
  var executeCommand = true;

  // If the command has a -- in it then we know it is passing parameters
  // to pm2
  var argumentPos = start.indexOf(' -- ');
  var location = start;
  var scriptArgs = [];
  if (argumentPos > -1) {
    scriptArgs = start.substring(argumentPos + 4, start.length).split(' ');
    location = start.substring(0, argumentPos);
  }

  if (!self.bosco.exists(options.cwd + '/' + location)) {
    self.bosco.warn('Can\'t start ' + options.name.red + ', as I can\'t find script: ' + location.red);
    return next();
  }

  var startOptions = { name: options.name, cwd: options.cwd, watch: options.watch, executeCommand: executeCommand, force: true, scriptArgs: scriptArgs };

  self.getInterpreter(this.bosco, options, function(err, interpreter) {
    if (err) { return next(err); }

    if (interpreter) {
      if (!self.bosco.exists(interpreter)) {
        self.bosco.warn('Unable to locate node version requested: ' + interpreter.cyan + '.  Reverting to default.');
      } else {
        startOptions.interpreter = interpreter;
        self.bosco.log('Starting ' + options.name.cyan + ' via ' + interpreter + ' ...');
      }
    } else {
      self.bosco.log('Starting ' + options.name.cyan + ' via ...');
    }

    pm2.start(location, startOptions, next);
  });
};

/**
 * List running services
 */
Runner.prototype.stop = function(options, next) {
  var self = this;
  self.bosco.log('Stopping ' + options.name.cyan);
  pm2.stop(options.name, function(err) {
    if (err) return next(err);
    pm2.delete(options.name, function(err) {
      next(err);
    });
  });
};

module.exports = new Runner();
<commit_msg>Fix second startsWith<commit_after>/**
 * Wrapper to manage services via PM2
 */
var _ = require('lodash');
var path = require('path');
var pm2 = require('pm2');

require('colors');

function Runner() {
}

Runner.prototype.init = function(bosco, next) {
  this.bosco = bosco;
  pm2.connect(next);
};

Runner.prototype.disconnect = function(next) {
  pm2.disconnect(next);
};

/**
 * List running services
 */
Runner.prototype.listRunning = function(detailed, next) {
  pm2.list(function(err, list) {
    var filteredList = _.filter(list, function(pm2Process) { return pm2Process.pm2_env.status === 'online' || pm2Process.pm2_env.status === 'errored'; });

    if (!detailed) return next(err, _.pluck(filteredList, 'name'));
    next(err, filteredList);
  });
};

/**
 * List services that have been created but are not running
 */
Runner.prototype.listNotRunning = function(detailed, next) {
  pm2.list(function(err, list) {
    var filteredList = _.filter(list, function(pm2Process) { return pm2Process.pm2_env.status !== 'online'; });

    if (!detailed) return next(err, _.pluck(filteredList, 'name'));
    next(err, filteredList);
  });
};

Runner.prototype.getInterpreter = function(bosco, options, next) {
  var self = this;
  var exec = require('child_process').exec;
  var interpreter;
  var hadError;
  var error;
  var installing;
  var found = false;
  var hasNvmRc = bosco.exists(path.join(options.cwd, '.nvmrc'));
  if (hasNvmRc) {
    var e = exec(bosco.options.nvmWhich, {cwd: options.cwd});

    e.stdout.on('data', function(data) {
      if (data.indexOf('Found') === 0) {
        found = true;
      } else {
        if (found) {
          interpreter = data.replace('\n', '');
        }
      }
    });

    e.stderr.on('data', function(data) {
      if (!hadError) {
        hadError = true;
        if (data.indexOf('No .nvmrc file found') === 0) {
          // Use default
        } else {
          error = options.name + ' nvm failed with: ' + data.replace('\n', '') + ', use -i option to install missing node versions!';
          if (bosco.options['install-missing']) {
            installing = true;
            self.installNode(bosco, options, function(err) {
              if (err) return next(err);
              self.getInterpreter(bosco, options, next);
            });
          }
        }
      }
    });

    e.on('exit', function() {
      if (interpreter) {
        bosco.log(options.name + ' using .nvmrc: ' + interpreter.cyan);
      }
      if (!installing) {
        return next(error, interpreter);
      }
    });
  } else {
    bosco.log(options.name + ' no .nvmrc found, using nvm default ...');
    next();
  }
};

Runner.prototype.installNode = function(bosco, options, next) {
  var exec = require('child_process').exec;
  bosco.log(options.name + ' installing required node version ...');
  var hasNvmRc = bosco.exists(path.join(options.cwd, '.nvmrc'));
  if (hasNvmRc) {
    exec(bosco.options.nvmInstall, {cwd: options.cwd}, function(err, stdout, stderr) {
      next(stderr);
    });
  } else {
    next('You cant install node without an .nvmrc');
  }
};

/**
 * Start a specific service
 * options = {cmd, cwd, name}
 */
Runner.prototype.start = function(options, next) {
  var self = this;

  // Remove node from the start script as not req'd for PM2
  var startCmd = options.service.start;
  var start = startCmd;
  var startArr;

  if (startCmd.split(' ')[0] === 'node') {
    startArr = startCmd.split(' ');
    startArr.shift();
    start = startArr.join(' ');

    if (!path.extname(start)) start = start + '.js';
  }

  // Always execute as a forked process to allow node version selection
  var executeCommand = true;

  // If the command has a -- in it then we know it is passing parameters
  // to pm2
  var argumentPos = start.indexOf(' -- ');
  var location = start;
  var scriptArgs = [];
  if (argumentPos > -1) {
    scriptArgs = start.substring(argumentPos + 4, start.length).split(' ');
    location = start.substring(0, argumentPos);
  }

  if (!self.bosco.exists(options.cwd + '/' + location)) {
    self.bosco.warn('Can\'t start ' + options.name.red + ', as I can\'t find script: ' + location.red);
    return next();
  }

  var startOptions = { name: options.name, cwd: options.cwd, watch: options.watch, executeCommand: executeCommand, force: true, scriptArgs: scriptArgs };

  self.getInterpreter(this.bosco, options, function(err, interpreter) {
    if (err) { return next(err); }

    if (interpreter) {
      if (!self.bosco.exists(interpreter)) {
        self.bosco.warn('Unable to locate node version requested: ' + interpreter.cyan + '.  Reverting to default.');
      } else {
        startOptions.interpreter = interpreter;
        self.bosco.log('Starting ' + options.name.cyan + ' via ' + interpreter + ' ...');
      }
    } else {
      self.bosco.log('Starting ' + options.name.cyan + ' via ...');
    }

    pm2.start(location, startOptions, next);
  });
};

/**
 * List running services
 */
Runner.prototype.stop = function(options, next) {
  var self = this;
  self.bosco.log('Stopping ' + options.name.cyan);
  pm2.stop(options.name, function(err) {
    if (err) return next(err);
    pm2.delete(options.name, function(err) {
      next(err);
    });
  });
};

module.exports = new Runner();
<|endoftext|>


<commit_before>"use strict";

/*
 Columns Layout Block
 */

SirTrevor.Blocks.Columns = SirTrevor.Block.extend({

  type: "Columns",

  title: function () {
    return i18n.t('blocks:columns:title') || 'Columns';
  },

  icon_name: 'columns',

  columns_presets: {
    'columns-6-6': [6, 6],
    'columns-3-9': [3, 9],
    'columns-9-3': [9, 3],
    'columns-4-8': [4, 8],
    'columns-8-4': [8, 4],
    'columns-4-4-4': [4, 4, 4],
    'columns-3-6-3': [3, 6, 3],
    'columns-3-3-3-3': [3, 3, 3, 3]
  },

  controllable: true,

  constructor: function (data, editorInstance, mediator, options) {
    SirTrevor.Block.apply(this, arguments);
  },

  beforeBlockRender: function () {
    this.controls = {
      'twocolumns': this.changeColumnsHandler('columns-6-6'),
      'threecolumns': this.changeColumnsHandler('columns-4-4-4'),
      'onetwocolumns': this.changeColumnsHandler('columns-4-8'),
      'twoonecolumns': this.changeColumnsHandler('columns-8-4'),
      'fourcolumns': this.changeColumnsHandler('columns-3-3-3-3'),
      'onethreecolumns': this.changeColumnsHandler('columns-3-9'),
      'threeonecolumns': this.changeColumnsHandler('columns-9-3'),
      'onetwoonecolumns': this.changeColumnsHandler('columns-3-6-3')
    };
  },

  changeColumnsHandler: function (preset) {
    var self = this;
    return function () {
      self.changeColumns(preset, false);
    };
  },

  changeColumns: function (preset) {
    if (this.columns_preset !== preset) {
      this.applyColumns(preset);
    }
  },

  editorHTML: function () {
    return '
'.replace('#{blockID}', this.blockID);
  },

  _setBlockInner: function () {
    SirTrevor.Block.prototype._setBlockInner.apply(this, arguments);
    this.applyColumns('columns-6-6', true);
    /* default */
  },

  applyColumns: function (preset, initial) {
    var self = this;
    var columns_config = this.columns_presets[preset];

    var $to_delete = this.getColumns(':gt(' + (columns_config.length - 1) + ')');
    // if there are unneeded columns
    if ($to_delete.length > 0) {
      // ask confirmation only if there are nested blocks
      if ($to_delete.children('.st-block').length > 0) {
        var txt = $to_delete.length === 1 ? 'column' : ($to_delete.length + ' columns');
        if (!window.confirm('This action will delete last ' + txt + '. Do you really want to proceed?')) {
          return; // interrupt if "Cancel" is pressed
        }
      }
      $to_delete.each(function () {
        var $this = $(this);
        // destroy nested blocks properly
        $this.children('.st-block').each(function () {
          self.editorInstance.removeBlock(this.getAttribute('id'));
        });
        // destroy column itself
        $this.trigger('destroy').remove();
      });
    }

    // apply new configuration
    var total_width = columns_config.reduce(function (total, width) {
      return total + width;
    }, 0);
    var $row = this.$('.columns-row');

    columns_config.forEach(function (ratio, i) {
      var width = Math.round(ratio * 1000 * 100 / total_width) / 1000;

      var $column = self.getColumn(i);
      if ($column.length === 0) {
        $column = $('

');
        var plus = new SirTrevor.FloatingBlockControls($column, self.instanceID, self.mediator);
        // self.listenTo(plus, 'showBlockControls', self.editorInstance.showBlockControls);
        $column.prepend(plus.render().$el);
        $row.append($column);
      }

      $column.css('width', width + '%');
    });

    this.$('.st-block-control-ui-btn').removeClass('active')
        .filter('[data-icon=' + preset + ']').addClass('active');

    this.columns_preset = preset;

    if (!initial) {
      this.trigger('block:columns:change');
    }
  },

  onBlockRender: function () {
    this.$('.st-block-control-ui-btn').filter('[data-icon=' + this.columns_preset + ']').addClass('active');
  },

  getRow: function () {
    if (this.$row) {
      return this.$row;
    }
    this.$row = this.$('#' + this.blockID + '-columns-row');
    return this.$row;
  },

  getColumns: function (filter) {
    return this.getRow().children(filter);
  },

  getColumn: function (index) {
    return this.getRow().children(':eq(' + index + ')');
  },

  _serializeData: function () {
    var self = this;
    var column_config = this.columns_presets[this.columns_preset];
    var dataObj = {columns: [], preset: this.columns_preset};

    this.getColumns().each(function (i) {
      var blocksData = [];
      $(this).children('.st-block').each(function () {
        var block = self.editorInstance.findBlockById(this.getAttribute('id'));
        blocksData.push(block.getData());
      });

      dataObj.columns.push({
        width: column_config[i],
        blocks: blocksData
      });
    });

    return dataObj;
  },

  loadData: function (data) {
    if (data.preset) {
      this.applyColumns(data.preset, true);
    }

    var columns_data = (data.columns || []);
    for (var i = 0; i < columns_data.length; i++) {
      var $block = null;
      var $column = this.getColumn(i);
      for (var j = 0; j < columns_data[i].blocks.length; j++) {
        var block = columns_data[i].blocks[j];
        $block = this.editorInstance.createBlock(block.type, block.data, $block ? $block.$el : $column.children('.st-block-controls__top'));
      }
    }
  },

  performValidations: function () {
    // nothing
  }
});<commit_msg>Methods removeBlock and createBlock were not accessed correctly. They are only available on the block_manager and not the editor instance.<commit_after>"use strict";

/*
 Columns Layout Block
 */

SirTrevor.Blocks.Columns = SirTrevor.Block.extend({

  type: "Columns",

  title: function () {
    return i18n.t('blocks:columns:title') || 'Columns';
  },

  icon_name: 'columns',

  columns_presets: {
    'columns-6-6': [6, 6],
    'columns-3-9': [3, 9],
    'columns-9-3': [9, 3],
    'columns-4-8': [4, 8],
    'columns-8-4': [8, 4],
    'columns-4-4-4': [4, 4, 4],
    'columns-3-6-3': [3, 6, 3],
    'columns-3-3-3-3': [3, 3, 3, 3]
  },

  controllable: true,

  constructor: function (data, editorInstance, mediator, options) {
    SirTrevor.Block.apply(this, arguments);
  },

  beforeBlockRender: function () {
    this.controls = {
      'twocolumns': this.changeColumnsHandler('columns-6-6'),
      'threecolumns': this.changeColumnsHandler('columns-4-4-4'),
      'onetwocolumns': this.changeColumnsHandler('columns-4-8'),
      'twoonecolumns': this.changeColumnsHandler('columns-8-4'),
      'fourcolumns': this.changeColumnsHandler('columns-3-3-3-3'),
      'onethreecolumns': this.changeColumnsHandler('columns-3-9'),
      'threeonecolumns': this.changeColumnsHandler('columns-9-3'),
      'onetwoonecolumns': this.changeColumnsHandler('columns-3-6-3')
    };
  },

  changeColumnsHandler: function (preset) {
    var self = this;
    return function () {
      self.changeColumns(preset, false);
    };
  },

  changeColumns: function (preset) {
    if (this.columns_preset !== preset) {
      this.applyColumns(preset);
    }
  },

  editorHTML: function () {
    return '
'.replace('#{blockID}', this.blockID);
  },

  _setBlockInner: function () {
    SirTrevor.Block.prototype._setBlockInner.apply(this, arguments);
    this.applyColumns('columns-6-6', true);
    /* default */
  },

  applyColumns: function (preset, initial) {
    var self = this;
    var columns_config = this.columns_presets[preset];

    var $to_delete = this.getColumns(':gt(' + (columns_config.length - 1) + ')');
    // if there are unneeded columns
    if ($to_delete.length > 0) {
      // ask confirmation only if there are nested blocks
      if ($to_delete.children('.st-block').length > 0) {
        var txt = $to_delete.length === 1 ? 'column' : ($to_delete.length + ' columns');
        if (!window.confirm('This action will delete last ' + txt + '. Do you really want to proceed?')) {
          return; // interrupt if "Cancel" is pressed
        }
      }
      $to_delete.each(function () {
        var $this = $(this);
        // destroy nested blocks properly
        $this.children('.st-block').each(function () {
          self.editorInstance.block_manager.removeBlock(this.getAttribute('id'));
        });
        // destroy column itself
        $this.trigger('destroy').remove();
      });
    }

    // apply new configuration
    var total_width = columns_config.reduce(function (total, width) {
      return total + width;
    }, 0);
    var $row = this.$('.columns-row');

    columns_config.forEach(function (ratio, i) {
      var width = Math.round(ratio * 1000 * 100 / total_width) / 1000;

      var $column = self.getColumn(i);
      if ($column.length === 0) {
        $column = $('

');
        var plus = new SirTrevor.FloatingBlockControls($column, self.instanceID, self.mediator);
        // self.listenTo(plus, 'showBlockControls', self.editorInstance.showBlockControls);
        $column.prepend(plus.render().$el);
        $row.append($column);
      }

      $column.css('width', width + '%');
    });

    this.$('.st-block-control-ui-btn').removeClass('active')
        .filter('[data-icon=' + preset + ']').addClass('active');

    this.columns_preset = preset;

    if (!initial) {
      this.trigger('block:columns:change');
    }
  },

  onBlockRender: function () {
    this.$('.st-block-control-ui-btn').filter('[data-icon=' + this.columns_preset + ']').addClass('active');
  },

  getRow: function () {
    if (this.$row) {
      return this.$row;
    }
    this.$row = this.$('#' + this.blockID + '-columns-row');
    return this.$row;
  },

  getColumns: function (filter) {
    return this.getRow().children(filter);
  },

  getColumn: function (index) {
    return this.getRow().children(':eq(' + index + ')');
  },

  _serializeData: function () {
    var self = this;
    var column_config = this.columns_presets[this.columns_preset];
    var dataObj = {columns: [], preset: this.columns_preset};

    this.getColumns().each(function (i) {
      var blocksData = [];
      $(this).children('.st-block').each(function () {
        var block = self.editorInstance.findBlockById(this.getAttribute('id'));
        blocksData.push(block.getData());
      });

      dataObj.columns.push({
        width: column_config[i],
        blocks: blocksData
      });
    });

    return dataObj;
  },

  loadData: function (data) {
    if (data.preset) {
      this.applyColumns(data.preset, true);
    }

    var columns_data = (data.columns || []);
    for (var i = 0; i < columns_data.length; i++) {
      var $block = null;
      var $column = this.getColumn(i);
      for (var j = 0; j < columns_data[i].blocks.length; j++) {
        var block = columns_data[i].blocks[j];
        $block = this.editorInstance.block_manager.createBlock(block.type, block.data, $block ? $block.$el : $column.children('.st-block-controls__top'));
      }
    }
  },

  performValidations: function () {
    // nothing
  }
});<|endoftext|>


<commit_before>const config = require("./../config.json");
const MSS = require("./../functions/");
const request = require("request");
const url = require("url");

module.exports = function yt(message) {
	let input = message.content.replace (/\n/g, "").split(" ");
	//Get the voice channel that it's going to play to.
	let voiceChannel = message.member.voiceChannel;
	//Check if the user is inside a voice channel or has inputted anything.
	if (!voiceChannel) {
		MSS.msg.react(message, false, "call");
		return false;
	} else if (!input[1]) {
		MSS.msg.react(message, false, "link");
		return false;
	}

	let sound = url.parse(input[1])

	switch (sound.protocol) {
		case "http:":
			MSS.msg.react(message, true);
			MSS.music.add(message, "http", input[1], input[1], "http://moustacheminer.com/mss.png");
			break;
		case "https:":
			MSS.msg.react(message, true);
			MSS.music.add(message, "https", input[1], input[1], "http://moustacheminer.com/mss.png");
			break;
		default:
			MSS.msg.react(message, false, "link");
			break;
	}
}
<commit_msg>software disable play command<commit_after>const config = require("./../config.json");
const MSS = require("./../functions/");
const request = require("request");
const url = require("url");

module.exports = function yt(message) {
	return message.reply("This function has been disabled in software. Please use the "+config.MSS.prefix+"yt command. See '" + config.MSS.prefix + "man yt' for more details.")

	let input = message.content.replace (/\n/g, "").split(" ");
	//Get the voice channel that it's going to play to.
	let voiceChannel = message.member.voiceChannel;
	//Check if the user is inside a voice channel or has inputted anything.
	if (!voiceChannel) {
		MSS.msg.react(message, false, "call");
		return false;
	} else if (!input[1]) {
		MSS.msg.react(message, false, "link");
		return false;
	}

	let sound = url.parse(input[1])

	switch (sound.protocol) {
		case "http:":
			MSS.msg.react(message, true);
			MSS.music.add(message, "http", input[1], input[1], "http://moustacheminer.com/mss.png");
			break;
		case "https:":
			MSS.msg.react(message, true);
			MSS.music.add(message, "https", input[1], input[1], "http://moustacheminer.com/mss.png");
			break;
		default:
			MSS.msg.react(message, false, "link");
			break;
	}
}
<|endoftext|>


<commit_before>module.exports = {
    "UPDATE_MAP_RESIZE_TIMEOUT": 500,
    "DEFAULT_MAP_SIZE": {
        HEIGHT: 480,
        WIDTH: 640
    }
}<commit_msg>Delete consts.js<commit_after><|endoftext|>


<commit_before>/**
 * Copyright (c) 2017-present, Alejandro Mantilla <@AlejoJamC>.
 * 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 or translated in the assets folder.
 */

/**
 * Module dependencies
 */
var express = require('express');
var mainRouter = express.Router();
var logger = require('../utils/logger').logger;
var request = require('request');

/* GET Index page. */
mainRouter.get('/', function (req, res) {
    // Basic error validator
    var error = '';
    // Error
    if (typeof req.query.error !== 'undefined') {
        error = req.query.error;
    }
    res.render('form', {
        title: 'Formulario de registro para supervisores | IoT',
        level: '',
        isHome: true,
        layout: 'template.hbs',
        error: error
    });
});

/* GET LIst of Watcherman. */
mainRouter.get('/watchermen', function (req, res) {
    // Basic error validator
    var error = '';
    // Error
    if (typeof req.query.error !== 'undefined') {
        error = req.query.error;
    }

    // Request options
    var options = {
        url: process.env.WEB_SERVICE + '/watchermen',
        headers: {
            'Authorization': 'Bearer ' + process.env.BEARER_KEY,
            'Content-Type': 'application/json'
        },
        method: 'GET'
    };

    // Sending customer creation method
    request.get(options, function (err, httpResponse, body) {
        if(err){
            logger.error('Error getting watchermen list: ' + err);
        }
        //Success
        res.json(body);
    });
});

/* POST New Watcherman. */
mainRouter.post('/watchermen', function (req, res) {
    // Basic error validator
    var error = '';
    // Error
    if (typeof req.query.error !== 'undefined') {
        error = req.query.error;
    }

    // Request options
    var options = {
        url: process.env.WEB_SERVICE + '/watchermen',
        headers: {
            'Authorization': 'Bearer ' + process.env.BEARER_KEY,
            'Content-Type': 'application/json'
        },
        method: 'POST',
        json: {
            'mobile' : req.body.mobile,
            'sms' : true,
            'voice': false,
            'status': true
        }
    };

    // Sending customer creation method
    request.post(options, function (err, httpResponse, body) {

    });
});

/* DELETE Watcherman by Id. */
mainRouter.delete('/watchermen/:id', function (req, res) {
    var watchermanId = req.params.id;
    // Basic error validator
    var error = '';
    // Error
    if (typeof req.query.error !== 'undefined') {
        error = req.query.error;
    }

    // Validate id
    if (typeof req.params.id === 'undefined') {
        error = 'El Id del supervisor es obligatorio';
    }

    // Request options
    var options = {
        url: process.env.WEB_SERVICE + '/watchermen/' + watchermanId,
        headers: {
            'Authorization': 'Bearer ' + process.env.BEARER_KEY,
            'Content-Type': 'application/json'
        },
        method: 'DELETE',
        json: {}
    };

    // Sending customer creation method
    request.delete(options, function (err, httpResponse, body) {
    });
});

module.exports = mainRouter;<commit_msg>response from delte and post methods, update parse body data type<commit_after>/**
 * Copyright (c) 2017-present, Alejandro Mantilla <@AlejoJamC>.
 * 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 or translated in the assets folder.
 */

/**
 * Module dependencies
 */
var express = require('express');
var mainRouter = express.Router();
var logger = require('../utils/logger').logger;
var request = require('request');

/* GET Index page. */
mainRouter.get('/', function (req, res) {
    // Basic error validator
    var error = '';
    // Error
    if (typeof req.query.error !== 'undefined') {
        error = req.query.error;
    }
    res.render('form', {
        title: 'Formulario de registro para supervisores | IoT',
        level: '',
        isHome: true,
        layout: 'template.hbs',
        error: error
    });
});

/* GET LIst of Watcherman. */
mainRouter.get('/watchermen', function (req, res) {
    // Basic error validator
    var error = '';
    // Error
    if (typeof req.query.error !== 'undefined') {
        error = req.query.error;
    }

    // Request options
    var options = {
        url: process.env.WEB_SERVICE + '/watchermen',
        headers: {
            'Authorization': 'Bearer ' + process.env.BEARER_KEY,
            'Content-Type': 'application/json'
        },
        method: 'GET'
    };

    // Sending customer creation method
    request.get(options, function (err, httpResponse, body) {
        if(err){
            logger.error('Error getting watchermen list: ' + err);
        }
        //Success
        body = JSON.parse(body);
        //logger.info(typeof body);
        //logger.info(body);
        res.json(body);
    });
});

/* POST New Watcherman. */
mainRouter.post('/watchermen', function (req, res) {
    // Basic error validator
    var error = '';
    // Error
    if (typeof req.query.error !== 'undefined') {
        error = req.query.error;
    }

    // Request options
    var options = {
        url: process.env.WEB_SERVICE + '/watchermen',
        headers: {
            'Authorization': 'Bearer ' + process.env.BEARER_KEY,
            'Content-Type': 'application/json'
        },
        method: 'POST',
        json: {
            'mobile' : req.body.mobile,
            'sms' : true,
            'voice': false,
            'status': true
        }
    };

    // Sending customer creation method
    request.post(options, function (err, httpResponse, body) {
        if(err){
            logger.error('Error saving watchermen: ' + err);
        }
        res.send('ok');
    });
});

/* DELETE Watcherman by Id. */
mainRouter.delete('/watchermen/:id', function (req, res) {
    var watchermanId = req.params.id;
    // Basic error validator
    var error = '';
    // Error
    if (typeof req.query.error !== 'undefined') {
        error = req.query.error;
    }

    // Validate id
    if (typeof req.params.id === 'undefined') {
        error = 'El Id del supervisor es obligatorio';
    }

    // Request options
    var options = {
        url: process.env.WEB_SERVICE + '/watchermen/' + watchermanId,
        headers: {
            'Authorization': 'Bearer ' + process.env.BEARER_KEY,
            'Content-Type': 'application/json'
        },
        method: 'DELETE',
        json: {}
    };

    // Sending customer creation method
    request.delete(options, function (err, httpResponse, body) {
        if(err){
            logger.error('Error removing watchermen: ' + err);
        }
        res.send('ok');
    });
});

module.exports = mainRouter;<|endoftext|>