<commit_before>import charm from 'charm';

export const COLORS = {
  RED: 'red',
  YELLOW: 'yellow',
  GREEN: 'green',
  BLUE: 'blue',
  CYAN: 'cyan',
  MAGENTA: 'magenta',
  BLACK: 'black',
  WHITE: 'white'
};

export default class Cursor {
  constructor() {
    this._cursor = charm(process);

    this.reset().on('^C', process.exit);
  }

  destroy() {
    this._cursor.destroy();
    return this;
  }

  write(...args) {
    this._cursor.write(...args);
    return this;
  }

  setPosition(x, y) {
    this._cursor.position(x, y);
    return this;
  }

  async getPosition() {
    return await this._cursor.position();
  }

  move(x, y) {
    this._cursor.move(x, y);
    return this;
  }

  up(y) {
    this._cursor.up(y);
    return this;
  }

  down(y) {
    this._cursor.down(y);
    return this;
  }

  left(x) {
    this._cursor.left(x);
    return this;
  }

  right(x) {
    this._cursor.right(x);
    return this;
  }

  reset() {
    this._cursor.reset();
    return this;
  }

  erase(s) {
    this._cursor.erase(s);
    return this;
  }

  eraseToEnd() {
    return this.erase('end');
  }

  eraseToStart() {
    return this.erase('start');
  }

  eraseLine() {
    return this.erase('line');
  }

  eraseToDown() {
    return this.erase('down');
  }

  eraseToUp() {
    return this.erase('up');
  }

  eraseScreen() {
    return this.erase('screen');
  }

  foreground(color) {
    this._cursor.foreground(color);
  }

  background(color) {
    this._cursor.background(color);
    return this;
  }

  removeAllListeners() {
    this._cursor.removeAllListeners();
    return this;
  }

  on(...args) {
    this._cursor.on(...args);
    return this;
  }
}
<commit_msg>feat(cursor): Adds more wrap methods to work with cursor<commit_after>import charm from 'charm';

export const COLORS = {
  RED: 'red',
  YELLOW: 'yellow',
  GREEN: 'green',
  BLUE: 'blue',
  CYAN: 'cyan',
  MAGENTA: 'magenta',
  BLACK: 'black',
  WHITE: 'white'
};

export const ERASE_REGIONS = {
  FROM_CURSOR_TO_END: 'end',
  FROM_CURSOR_TO_START: 'start',
  FROM_CURSOR_TO_DOWN: 'down',
  FROM_CURSOR_TO_UP: 'up',
  CURRENT_LINE: 'line',
  ENTIRE_SCREEN: 'screen'
};

export const DISPLAY_MODES = {
  RESET: 'reset',
  BRIGHT: 'bright',
  DIM: 'dim',
  UNDERSCORE: 'underscore',
  BLINK: 'blink',
  REVERSE: 'reverse',
  HIDDEN: 'hidden'
};

export default class Cursor {
  constructor() {
    this._cursor = charm(process);

    this.on('^C', process.exit);
  }

  /**
   * Write to the stream
   * @param {String} message Message to write into a stream
   * @returns {Cursor}
   */
  write(message) {
    this._cursor.write(message);
    return this;
  }

  /**
   * Set cursor position to specified point
   * @param {Number} x
   * @param {Number} y
   * @returns {Cursor}
   */
  setPosition(x, y) {
    this._cursor.position(x, y);
    return this;
  }

  /**
   * Get current position of cursor
   * @returns {Promise}
   */
  getPosition() {
    return new Promise((resolve, reject) => this._cursor.position((x, y) => resolve(x, y)));
  }

  /**
   * Move the cursor by the relative coordinates
   * @param {Number} x
   * @param {Number} y
   * @returns {Cursor}
   */
  move(x, y) {
    this._cursor.move(x, y);
    return this;
  }

  /**
   * Move the cursor up
   * @param {Number} y Rows count
   * @returns {Cursor}
   */
  up(y) {
    this._cursor.up(y);
    return this;
  }

  /**
   * Move the cursor down
   * @param {Number} y Rows count
   * @returns {Cursor}
   */
  down(y) {
    this._cursor.down(y);
    return this;
  }

  /**
   * Move the cursor left
   * @param {Number} x Columns count
   * @returns {Cursor}
   */
  left(x) {
    this._cursor.left(x);
    return this;
  }

  /**
   * Move the cursor right
   * @param {Number} x Columns count
   * @returns {Cursor}
   */
  right(x) {
    this._cursor.right(x);
    return this;
  }

  /**
   * Erase a defined region
   * @param {String} region
   * @returns {Cursor}
   */
  erase(region) {
    this._cursor.erase(region);
    return this;
  }

  /**
   * Erase from cursor to the end of the line
   * @returns {Cursor}
   */
  eraseToEnd() {
    return this.erase(ERASE_REGIONS.FROM_CURSOR_TO_END);
  }

  /**
   * Erase from cursor to the start of the line
   * @returns {Cursor}
   */
  eraseToStart() {
    return this.erase(ERASE_REGIONS.FROM_CURSOR_TO_START);
  }

  /**
   * Erase the entire line
   * @returns {Cursor}
   */
  eraseLine() {
    return this.erase(ERASE_REGIONS.CURRENT_LINE);
  }

  /**
   * Erase everything below the current line
   * @returns {Cursor}
   */
  eraseToDown() {
    return this.erase(ERASE_REGIONS.FROM_CURSOR_TO_DOWN);
  }

  /**
   * Erase everything above the current line
   * @returns {Cursor}
   */
  eraseToUp() {
    return this.erase(ERASE_REGIONS.FROM_CURSOR_TO_UP);
  }

  /**
   * Erase the entire screen
   * @returns {Cursor}
   */
  eraseScreen() {
    return this.erase(ERASE_REGIONS.ENTIRE_SCREEN);
  }

  /**
   * Set the foreground color
   * @param {String|Number} color
   * @returns {Cursor}
   */
  foreground(color) {
    this._cursor.foreground(color);
    return this;
  }

  /**
   * Set the background color
   * @param {String|Number} color
   * @returns {Cursor}
   */
  background(color) {
    this._cursor.background(color);
    return this;
  }

  /**
   * Set the cursor invisible
   * @returns {Cursor}
   */
  hide() {
    this._cursor.cursor(false);
    return this;
  }

  /**
   * Set the cursor visible
   * @returns {Cursor}
   */
  show() {
    this._cursor.cursor(true);
    return this;
  }

  /**
   * Set the display mode
   * @param {String} mode
   * @returns {Cursor}
   */
  display(mode) {
    this._cursor.display(mode);
    return this;
  }

  /**
   * Clear the entire screen
   * @returns {Cursor}
   */
  reset() {
    this._cursor.reset();
    return this;
  }

  /**
   * Remove all listeners from cursor
   * @param {String} event
   * @returns {Cursor}
   */
  removeAllListeners(event) {
    this._cursor.removeAllListeners(event);
    return this;
  }

  /**
   * Subscribe to event
   * @param {String} event
   * @param {Function} handler
   * @returns {Cursor}
   */
  on(event, handler) {
    this._cursor.on(event, handler);
    return this;
  }

  /**
   * Push the cursor state
   * @param {Boolean} withAttributes
   * @returns {Cursor}
   */
  push(withAttributes = false) {
    this._cursor.push(withAttributes);
    return this;
  }

  /**
   * Pop the cursor state
   * @param {Boolean} withAttributes
   * @returns {Cursor}
   */
  pop(withAttributes = false) {
    this._cursor.pop(withAttributes);
    return this;
  }

  /**
   * Destroy the cursor and emit end event downstream
   * @returns {Cursor}
   */
  destroy() {
    this._cursor.destroy();
    return this;
  }
}
<|endoftext|>


<commit_before>/**
* leaflet implementation of a map
*/
(function() {

  if(typeof(L) == "undefined")
    return;

  /**
   * leatlef impl
   */
  cdb.geo.LeafletMapView = cdb.geo.MapView.extend({

    initialize: function() {

      _.bindAll(this, '_addLayer', '_removeLayer', '_setZoom', '_setCenter', '_setView');

      cdb.geo.MapView.prototype.initialize.call(this);

      var self = this;

      var center = this.map.get('center');

      var mapConfig = {
        zoomControl: false,
        center: new L.LatLng(center[0], center[1]),
        zoom: this.map.get('zoom'),
        minZoom: this.map.get('minZoom'),
        maxZoom: this.map.get('maxZoom')
      };
      if (this.map.get('bounding_box_ne')) {
        //mapConfig.maxBounds = [this.map.get('bounding_box_ne'), this.map.get('bounding_box_sw')];
      }

      if(!this.options.map_object) {
        this.map_leaflet = new L.Map(this.el, mapConfig);

        // remove the "powered by leaflet"
        this.map_leaflet.attributionControl.setPrefix('');
      } else {
        this.map_leaflet = this.options.map_object;
        this.setElement(this.map_leaflet.getContainer());
        var c = self.map_leaflet.getCenter();
        self._setModelProperty({ center: [c.lat, c.lng] });
        self._setModelProperty({ zoom: self.map_leaflet.getZoom() });
      }

      this.map.bind('set_view', this._setView, this);
      this.map.layers.bind('add', this._addLayer, this);
      this.map.layers.bind('remove', this._removeLayer, this);
      this.map.layers.bind('reset', this._addLayers, this);

      this.map.geometries.bind('add', this._addGeometry, this);
      this.map.geometries.bind('remove', this._removeGeometry, this);

      this._bindModel();

      this._addLayers();

      this.map_leaflet.on('layeradd', function(lyr) {
        this.trigger('layeradd', lyr, self);
      }, this);

      this.map_leaflet.on('zoomstart', function() {
        self.trigger('zoomstart');
      });

      this.map_leaflet.on('click', function(e) {
        self.trigger('click', e.originalEvent, [e.latlng.lat, e.latlng.lng]);
      });

      this.map_leaflet.on('dblclick', function(e) {
        self.trigger('dblclick', e.originalEvent);
      });

      this.map_leaflet.on('zoomend', function() {
        self._setModelProperty({
          zoom: self.map_leaflet.getZoom()
        });
        self.trigger('zoomend');
      }, this);

      this.map_leaflet.on('move', function() {
        var c = self.map_leaflet.getCenter();
        self._setModelProperty({ center: [c.lat, c.lng] });
      });

      this.map_leaflet.on('drag', function() {
        var c = self.map_leaflet.getCenter();
        self._setModelProperty({
          center: [c.lat, c.lng]
        });
        self.trigger('drag');
      }, this);

      this.map.bind('change:maxZoom', function() {
        L.Util.setOptions(self.map_leaflet, { maxZoom: self.map.get('maxZoom') });
      }, this);

      this.map.bind('change:minZoom', function() {
        L.Util.setOptions(self.map_leaflet, { minZoom: self.map.get('minZoom') });
      }, this);

      this.trigger('ready');

      // looks like leaflet dont like to change the bounds just after the inicialization
      var bounds = this.map.getViewBounds();
      if(bounds) {
        this.showBounds(bounds);
      }
    },

    clean: function() {
      //see https://github.com/CloudMade/Leaflet/issues/1101
      L.DomEvent.off(window, 'resize', this.map_leaflet._onResize, this.map_leaflet);
      // do not change by elder
      cdb.core.View.prototype.clean.call(this);
    },

    _setZoom: function(model, z) {
      this._setView();
    },

    _setCenter: function(model, center) {
      this._setView();
    },

    _setView: function() {
      this.map_leaflet.setView(this.map.get("center"), this.map.get("zoom") || 0 );
    },

    _addGeomToMap: function(geom) {
      var geo = cdb.geo.LeafletMapView.createGeometry(geom);
      geo.geom.addTo(this.map_leaflet);
      return geo;
    },

    _removeGeomFromMap: function(geo) {
      this.map_leaflet.removeLayer(geo.geom);
    },

    createLayer: function(layer) {
      return cdb.geo.LeafletMapView.createLayer(layer, this.map_leaflet);
    },

    _addLayer: function(layer, layers, opts) {
      var self = this;
      var lyr, layer_view;

      layer_view = cdb.geo.LeafletMapView.createLayer(layer, this.map_leaflet);
      if(!layer_view) {
        return;
      }

      var appending = !opts || opts.index === undefined || opts.index === _.size(this.layers);
      // since leaflet does not support layer ordering
      // add the layers should be removed and added again
      // if the layer is being appended do not clear
      if(!appending) {
        for(var i in this.layers) {
          this.map_leaflet.removeLayer(this.layers[i]);
        }
      }

      this.layers[layer.cid] = layer_view;

      // add them again, in correct order
      if(appending) {
        cdb.geo.LeafletMapView.addLayerToMap(layer_view, self.map_leaflet);
      } else {
        this.map.layers.each(function(layerModel) {
          var v = self.layers[layerModel.cid];
          if(v) {
            cdb.geo.LeafletMapView.addLayerToMap(v, self.map_leaflet);
          }
        });
      }

      var attribution = layer.get('attribution');

      if (attribution) {
        // Setting attribution in map model
        var attributions = this.map.get('attribution') || [];
        if (!_.contains(attributions, attribution)) {
          attributions.push(attribution);
        }

        this.map.set({ attribution: attributions });
      }

      this.trigger('newLayerView', layer_view, this);
    },

    latLonToPixel: function(latlon) {
      var point = this.map_leaflet.latLngToLayerPoint(new L.LatLng(latlon[0], latlon[1]));
      return this.map_leaflet.layerPointToContainerPoint(point);
    },

    // return the current bounds of the map view
    getBounds: function() {
      var b = this.map_leaflet.getBounds();
      var sw = b.getSouthWest();
      var ne = b.getNorthEast();
      return [
        [sw.lat, sw.lng],
        [ne.lat, ne.lng]
      ];
    },

    setAttribution: function(m) {
      // Leaflet takes care of attribution by its own.
    },

    getSize: function() {
      return this.map_leaflet.getSize();
    },

    panBy: function(p) {
      this.map_leaflet.panBy(new L.Point(p.x, p.y));
    },

    setCursor: function(cursor) {
      $(this.map_leaflet.getContainer()).css('cursor', cursor);
    },

    getNativeMap: function() {
      return this.map_leaflet;
    }

  }, {

    layerTypeMap: {
      "tiled": cdb.geo.LeafLetTiledLayerView,
      "cartodb": cdb.geo.LeafLetLayerCartoDBView,
      "carto": cdb.geo.LeafLetLayerCartoDBView,
      "plain": cdb.geo.LeafLetPlainLayerView,
      // for google maps create a plain layer
      "gmapsbase": cdb.geo.LeafLetPlainLayerView
    },

    createLayer: function(layer, map) {
      var layer_view = null;
      var layerClass = this.layerTypeMap[layer.get('type').toLowerCase()];

      if (layerClass) {
        layer_view = new layerClass(layer, map);
      } else {
        cdb.log.error("MAP: " + layer.get('type') + " can't be created");
      }
      return layer_view;
    },

    addLayerToMap: function(layer_view, map) {
      map.addLayer(layer_view.leafletLayer);
    },

    /**
     * create the view for the geometry model
     */
    createGeometry: function(geometryModel) {
      if(geometryModel.isPoint()) {
        return new cdb.geo.leaflet.PointView(geometryModel);
      }
      return new cdb.geo.leaflet.PathView(geometryModel);
    }

  });
})();
<commit_msg>remove layer views before remove the map<commit_after>/**
* leaflet implementation of a map
*/
(function() {

  if(typeof(L) == "undefined")
    return;

  /**
   * leatlef impl
   */
  cdb.geo.LeafletMapView = cdb.geo.MapView.extend({

    initialize: function() {

      _.bindAll(this, '_addLayer', '_removeLayer', '_setZoom', '_setCenter', '_setView');

      cdb.geo.MapView.prototype.initialize.call(this);

      var self = this;

      var center = this.map.get('center');

      var mapConfig = {
        zoomControl: false,
        center: new L.LatLng(center[0], center[1]),
        zoom: this.map.get('zoom'),
        minZoom: this.map.get('minZoom'),
        maxZoom: this.map.get('maxZoom')
      };
      if (this.map.get('bounding_box_ne')) {
        //mapConfig.maxBounds = [this.map.get('bounding_box_ne'), this.map.get('bounding_box_sw')];
      }

      if(!this.options.map_object) {
        this.map_leaflet = new L.Map(this.el, mapConfig);

        // remove the "powered by leaflet"
        this.map_leaflet.attributionControl.setPrefix('');
      } else {
        this.map_leaflet = this.options.map_object;
        this.setElement(this.map_leaflet.getContainer());
        var c = self.map_leaflet.getCenter();
        self._setModelProperty({ center: [c.lat, c.lng] });
        self._setModelProperty({ zoom: self.map_leaflet.getZoom() });
      }

      this.map.bind('set_view', this._setView, this);
      this.map.layers.bind('add', this._addLayer, this);
      this.map.layers.bind('remove', this._removeLayer, this);
      this.map.layers.bind('reset', this._addLayers, this);

      this.map.geometries.bind('add', this._addGeometry, this);
      this.map.geometries.bind('remove', this._removeGeometry, this);

      this._bindModel();

      this._addLayers();

      this.map_leaflet.on('layeradd', function(lyr) {
        this.trigger('layeradd', lyr, self);
      }, this);

      this.map_leaflet.on('zoomstart', function() {
        self.trigger('zoomstart');
      });

      this.map_leaflet.on('click', function(e) {
        self.trigger('click', e.originalEvent, [e.latlng.lat, e.latlng.lng]);
      });

      this.map_leaflet.on('dblclick', function(e) {
        self.trigger('dblclick', e.originalEvent);
      });

      this.map_leaflet.on('zoomend', function() {
        self._setModelProperty({
          zoom: self.map_leaflet.getZoom()
        });
        self.trigger('zoomend');
      }, this);

      this.map_leaflet.on('move', function() {
        var c = self.map_leaflet.getCenter();
        self._setModelProperty({ center: [c.lat, c.lng] });
      });

      this.map_leaflet.on('drag', function() {
        var c = self.map_leaflet.getCenter();
        self._setModelProperty({
          center: [c.lat, c.lng]
        });
        self.trigger('drag');
      }, this);

      this.map.bind('change:maxZoom', function() {
        L.Util.setOptions(self.map_leaflet, { maxZoom: self.map.get('maxZoom') });
      }, this);

      this.map.bind('change:minZoom', function() {
        L.Util.setOptions(self.map_leaflet, { minZoom: self.map.get('minZoom') });
      }, this);

      this.trigger('ready');

      // looks like leaflet dont like to change the bounds just after the inicialization
      var bounds = this.map.getViewBounds();
      if(bounds) {
        this.showBounds(bounds);
      }
    },

    clean: function() {
      //see https://github.com/CloudMade/Leaflet/issues/1101
      L.DomEvent.off(window, 'resize', this.map_leaflet._onResize, this.map_leaflet);

      // remove layer views
      for(var layer in this.layers) {
        var layer_view = this.layers[layer];
        layer_view.remove();
        delete this.layers[layer];
      }

      // do not change by elder
      cdb.core.View.prototype.clean.call(this);
    },

    _setZoom: function(model, z) {
      this._setView();
    },

    _setCenter: function(model, center) {
      this._setView();
    },

    _setView: function() {
      this.map_leaflet.setView(this.map.get("center"), this.map.get("zoom") || 0 );
    },

    _addGeomToMap: function(geom) {
      var geo = cdb.geo.LeafletMapView.createGeometry(geom);
      geo.geom.addTo(this.map_leaflet);
      return geo;
    },

    _removeGeomFromMap: function(geo) {
      this.map_leaflet.removeLayer(geo.geom);
    },

    createLayer: function(layer) {
      return cdb.geo.LeafletMapView.createLayer(layer, this.map_leaflet);
    },

    _addLayer: function(layer, layers, opts) {
      var self = this;
      var lyr, layer_view;

      layer_view = cdb.geo.LeafletMapView.createLayer(layer, this.map_leaflet);
      if(!layer_view) {
        return;
      }

      var appending = !opts || opts.index === undefined || opts.index === _.size(this.layers);
      // since leaflet does not support layer ordering
      // add the layers should be removed and added again
      // if the layer is being appended do not clear
      if(!appending) {
        for(var i in this.layers) {
          this.map_leaflet.removeLayer(this.layers[i]);
        }
      }

      this.layers[layer.cid] = layer_view;

      // add them again, in correct order
      if(appending) {
        cdb.geo.LeafletMapView.addLayerToMap(layer_view, self.map_leaflet);
      } else {
        this.map.layers.each(function(layerModel) {
          var v = self.layers[layerModel.cid];
          if(v) {
            cdb.geo.LeafletMapView.addLayerToMap(v, self.map_leaflet);
          }
        });
      }

      var attribution = layer.get('attribution');

      if (attribution) {
        // Setting attribution in map model
        var attributions = this.map.get('attribution') || [];
        if (!_.contains(attributions, attribution)) {
          attributions.push(attribution);
        }

        this.map.set({ attribution: attributions });
      }

      this.trigger('newLayerView', layer_view, this);
    },

    latLonToPixel: function(latlon) {
      var point = this.map_leaflet.latLngToLayerPoint(new L.LatLng(latlon[0], latlon[1]));
      return this.map_leaflet.layerPointToContainerPoint(point);
    },

    // return the current bounds of the map view
    getBounds: function() {
      var b = this.map_leaflet.getBounds();
      var sw = b.getSouthWest();
      var ne = b.getNorthEast();
      return [
        [sw.lat, sw.lng],
        [ne.lat, ne.lng]
      ];
    },

    setAttribution: function(m) {
      // Leaflet takes care of attribution by its own.
    },

    getSize: function() {
      return this.map_leaflet.getSize();
    },

    panBy: function(p) {
      this.map_leaflet.panBy(new L.Point(p.x, p.y));
    },

    setCursor: function(cursor) {
      $(this.map_leaflet.getContainer()).css('cursor', cursor);
    },

    getNativeMap: function() {
      return this.map_leaflet;
    }

  }, {

    layerTypeMap: {
      "tiled": cdb.geo.LeafLetTiledLayerView,
      "cartodb": cdb.geo.LeafLetLayerCartoDBView,
      "carto": cdb.geo.LeafLetLayerCartoDBView,
      "plain": cdb.geo.LeafLetPlainLayerView,
      // for google maps create a plain layer
      "gmapsbase": cdb.geo.LeafLetPlainLayerView
    },

    createLayer: function(layer, map) {
      var layer_view = null;
      var layerClass = this.layerTypeMap[layer.get('type').toLowerCase()];

      if (layerClass) {
        layer_view = new layerClass(layer, map);
      } else {
        cdb.log.error("MAP: " + layer.get('type') + " can't be created");
      }
      return layer_view;
    },

    addLayerToMap: function(layer_view, map) {
      map.addLayer(layer_view.leafletLayer);
    },

    /**
     * create the view for the geometry model
     */
    createGeometry: function(geometryModel) {
      if(geometryModel.isPoint()) {
        return new cdb.geo.leaflet.PointView(geometryModel);
      }
      return new cdb.geo.leaflet.PathView(geometryModel);
    }

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


<commit_before>JSM.CutPolygonInternal = function (polygon, geometryInterface, aSidePolygons, bSidePolygons, cutPolygons)
{
	function DetectOriginalVertexTypes (polygon)
	{
		var cutInformation = {
			originalVertexTypes : [],
			backFound : false,
			frontFound : false
		};
		var i, vertex, type;
		for (i = 0; i < polygon.VertexCount (); i++) {
			vertex = polygon.GetVertex (i);
			type = geometryInterface.getVertexSide (vertex);
			if (type == 1) {
				cutInformation.frontFound = true;
			} else if (type == -1) {
				cutInformation.backFound = true;
			}
			cutInformation.originalVertexTypes.push (type);
		}
		return cutInformation;
	}

	function AddCutVerticesToPolygon (polygon, cutPolygon, originalVertexTypes)
	{
		function AddVertex (polygon, index, cutPolygon, originalVertexTypes, cutVertexTypes)
		{
			function IsIntersectionVertex (cutVertexTypes, originalType)
			{
				if (cutVertexTypes.length === 0) {
					return false;
				}
				var prevType = cutVertexTypes[cutVertexTypes.length - 1];
				return prevType !== 0 && originalType !== 0 && prevType != originalType;
			}

			function AddIntersectionVertex (polygon, cutPolygon, cutVertexTypes, currIndex)
			{
				var prevIndex = polygon.GetPrevVertex (currIndex);
				var prevVertex = polygon.GetVertex (prevIndex);
				var currVertex = polygon.GetVertex (currIndex);
				var intersection = geometryInterface.getIntersectionVertex (prevVertex, currVertex);
				if (intersection !== null) {
					cutPolygon.AddVertexCoord (intersection);
					cutVertexTypes.push (0);
				}
			}

			function AddOriginalVertex (polygon, cutPolygon, cutVertexTypes, currIndex, originalType)
			{
				cutPolygon.AddVertexCoord (polygon.GetVertex (currIndex).Clone ());
				cutVertexTypes.push (originalType);
			}

			var lastVertex = (index === polygon.VertexCount ());
			var currIndex = index;
			if (lastVertex) {
				currIndex = 0;
			}

			var originalType = originalVertexTypes[currIndex];
			if (IsIntersectionVertex (cutVertexTypes, originalType)) {
				AddIntersectionVertex (polygon, cutPolygon, cutVertexTypes, currIndex);
			}
			if (!lastVertex) {
				AddOriginalVertex (polygon, cutPolygon, cutVertexTypes, currIndex, originalType);
			}
		}

		var cutVertexTypes = [];
		var i;
		for (i = 0; i <= polygon.VertexCount (); i++) {
			AddVertex (polygon, i, cutPolygon, originalVertexTypes, cutVertexTypes);
		}
		return cutVertexTypes;
	}

	function AddCuttedPolygons (cutPolygon, cutVertexTypes, aSidePolygons, bSidePolygons)
	{
		function GetEntryVertices (cutVertexTypes)
		{
			function FindPrevSideType (index, cutVertexTypes)
			{
				var currIndex = JSM.PrevIndex (index, cutVertexTypes.length);
				while (currIndex != index) {
					if (cutVertexTypes[currIndex] !== 0) {
						return cutVertexTypes[currIndex];
					}
					currIndex = JSM.PrevIndex (currIndex, cutVertexTypes.length);
				}
				return 0;
			}

			var entryVertices = [];
			var i, currSide, prevIndex, nextIndex, prevSideType, nextSideType;
			for (i = 0; i < cutVertexTypes.length; i++) {
				currSide = cutVertexTypes[i];
				if (currSide === 0) {
					prevIndex = JSM.PrevIndex (i, cutVertexTypes.length);
					nextIndex = JSM.NextIndex (i, cutVertexTypes.length);
					prevSideType = cutVertexTypes[prevIndex];
					nextSideType = cutVertexTypes[nextIndex];
					if (nextSideType !== 0 && prevSideType === 0) {
						prevSideType = FindPrevSideType (prevIndex, cutVertexTypes);
					}
					if ((prevSideType == -1 && nextSideType == 1) || (prevSideType == 1 && nextSideType == -1)) {
						entryVertices.push (i);
					}
				}
			}
			return entryVertices;
		}

		function SortEntryVertices (cutPolygon, entryVertices)
		{
			function SwapArrayValues (array, from, to)
			{
				var temp = array[from];
				array[from] = array[to];
				array[to] = temp;
			}

			if (entryVertices.length < 2) {
				return;
			}

			var referenceCoord1 = cutPolygon.GetVertex (entryVertices[0]);
			var referenceCoord2 = cutPolygon.GetVertex (entryVertices[1]);
			var distances = geometryInterface.getVertexDistances (cutPolygon, entryVertices, referenceCoord1, referenceCoord2);
			var i, j;
			for (i = 0; i < entryVertices.length - 1; i++) {
				for (j = 0; j < entryVertices.length - i - 1; j++) {
					if (JSM.IsGreater (distances[j], distances[j + 1])) {
						SwapArrayValues (distances, j, j + 1);
						SwapArrayValues (entryVertices, j, j + 1);
					}
				}
			}
		}

		function GetOneSideCuttedPolygons (cutPolygon, entryVertices, cutVertexTypes, aSidePolygons, bSidePolygons, reversed)
		{
			function AddEntryPairToArray (entryPairs, entryVertices, index)
			{
				entryPairs[entryVertices[index]] = entryVertices[index + 1];
				entryPairs[entryVertices[index + 1]] = entryVertices[index];
			}

			function RemoveEntryPairFromArray (entryPairs, index)
			{
				entryPairs[entryPairs[index]] = -1;
				entryPairs[index] = -1;
			}

			function CreateEntryPairsArray (cutPolygon, entryVertices, entryPairs)
			{
				var i;
				for (i = 0; i < cutPolygon.VertexCount (); i++) {
					entryPairs.push (-1);
				}
				for (i = 0; i < entryVertices.length; i = i + 2) {
					AddEntryPairToArray (entryPairs, entryVertices, i);
				}
			}

			function GetNextVertex (currVertexIndex, cutPolygon, entryPairs)
			{
				if (entryPairs[currVertexIndex] != -1) {
					var nextVertex = entryPairs[currVertexIndex];
					RemoveEntryPairFromArray (entryPairs, currVertexIndex);
					return nextVertex;
				} else {
					return JSM.NextIndex (currVertexIndex, cutPolygon.VertexCount ());
				}
			}

			var entryPairs = [];
			CreateEntryPairsArray (cutPolygon, entryVertices, entryPairs);

			var polygonSide = null;
			var currEntryVertex = reversed ? entryVertices.length - 1 : 0;
			var startVertexIndex, currVertexIndex, currPolygon;
			while (currEntryVertex >= 0 && currEntryVertex < entryVertices.length) {
				startVertexIndex = entryVertices[currEntryVertex];
				if (entryPairs[startVertexIndex] !== -1) {
					currPolygon = geometryInterface.createPolygon ();
					currPolygon.AddVertexCoord (cutPolygon.GetVertex (startVertexIndex).Clone ());
					currVertexIndex = GetNextVertex (startVertexIndex, cutPolygon, entryPairs);
					while (currVertexIndex != startVertexIndex) {
						if (polygonSide === null) {
							if (cutVertexTypes[currVertexIndex] !== 0) {
								polygonSide = cutVertexTypes[currVertexIndex];
							}
						}
						currPolygon.AddVertexCoord (cutPolygon.GetVertex (currVertexIndex).Clone ());
						currVertexIndex = GetNextVertex (currVertexIndex, cutPolygon, entryPairs);
					}
					if (polygonSide == 1) {
						aSidePolygons.push (currPolygon);
					} else if (polygonSide == -1) {
						bSidePolygons.push (currPolygon);
					}
				}
				currEntryVertex = reversed ? currEntryVertex - 2 : currEntryVertex + 2;
			}
		}

		var entryVertices = GetEntryVertices (cutVertexTypes);
		if (entryVertices.length === 0 || entryVertices.length % 2 !== 0) {
			return;
		}

		SortEntryVertices (cutPolygon, entryVertices);
		GetOneSideCuttedPolygons (cutPolygon, entryVertices, cutVertexTypes, aSidePolygons, bSidePolygons, false);
		GetOneSideCuttedPolygons (cutPolygon, entryVertices, cutVertexTypes, aSidePolygons, bSidePolygons, true);
	}

	var cutPolygon = geometryInterface.createPolygon ();
	var cutInformation = DetectOriginalVertexTypes (polygon);

	if (cutInformation.backFound && cutInformation.frontFound) {
		var cutVertexTypes = AddCutVerticesToPolygon (polygon, cutPolygon, cutInformation.originalVertexTypes);
		AddCuttedPolygons (cutPolygon, cutVertexTypes, aSidePolygons, bSidePolygons);
	} else {
		var cloned = polygon.Clone ();
		if (cutInformation.frontFound) {
			aSidePolygons.push (cloned);
		} else if (cutInformation.backFound) {
			bSidePolygons.push (cloned);
		} else {
			cutPolygons.push (cloned);
		}
	}

	if (aSidePolygons.length + bSidePolygons.length + cutPolygons.length === 0) {
		return false;
	}
	return true;
};

/**
* Function: CutPolygon2DWithLine
* Description:
*	Cuts a polygon with a line. The result array contains cutted
*	polygons grouped by their position to the line.
* Parameters:
*	polygon {Polygon2D} the polygon
*	line {Line2D} the line
*	leftPolygons {Polygon2D[*]} (out) polygons on the left of the line
*	rightPolygons {Polygon2D[*]} (out) polygons on the right of the line
*	cutPolygons {Polygon2D[*]} (out) polygons on the line
* Returns:
*	{boolean} success
*/
JSM.CutPolygon2DWithLine = function (polygon, line, leftPolygons, rightPolygons, cutPolygons)
{
	var geometryInterface = {
		createPolygon : function () {
			return new JSM.Polygon2D ();
		},
		getVertexSide : function (vertex) {
			var position = line.CoordPosition (vertex);
			var type = 0;
			if (position == JSM.CoordLinePosition2D.CoordAtLineLeft) {
				type = 1;
			} else if (position == JSM.CoordLinePosition2D.CoordAtLineRight) {
				type = -1;
			}
			return type;
		},
		getIntersectionVertex : function (prevVertex, currVertex) {
			var edgeLine = new JSM.Line2D (currVertex, JSM.CoordSub2D (currVertex, prevVertex));
			var intersection = new JSM.Coord2D (0.0, 0.0);
			var lineLinePosition = line.LinePosition (edgeLine, intersection);
			if (lineLinePosition != JSM.LineLinePosition2D.LinesIntersectsOnePoint) {
				return null;
			}
			return intersection;
		},
		getVertexDistances : function (polygon, vertexIndices, referenceCoord1, referenceCoord2) {
			var direction = JSM.CoordSub2D (referenceCoord2, referenceCoord1);
			var i, vertex;
			var distances = [];
			for (i = 0; i < vertexIndices.length; i++) {
				vertex = polygon.GetVertex (vertexIndices[i]);
				distances.push (JSM.CoordSignedDistance2D (referenceCoord1, vertex, direction));
			}
			return distances;
		}
	};

	return JSM.CutPolygonInternal (polygon, geometryInterface, leftPolygons, rightPolygons, cutPolygons);
};

/**
* Function: CutPolygonWithPlane
* Description:
*	Cuts a polygon with a plane. The result array contains cutted
*	polygons grouped by their position to the plane.
* Parameters:
*	polygon {Polygon} the polygon
*	plane {Plane} the plane
*	frontPolygons {Polygon[*]} (out) polygons in front of the plane
*	backPolygons {Polygon[*]} (out) polygons at the back of the plane
*	cutPolygons {Polygon[*]} (out) polygons on the plane
* Returns:
*	{boolean} success
*/
JSM.CutPolygonWithPlane = function (polygon, plane, frontPolygons, backPolygons, cutPolygons)
{
	var geometryInterface = {
		createPolygon : function () {
			return new JSM.Polygon ();
		},
		getVertexSide : function (vertex) {
			var position = plane.CoordPosition (vertex);
			var type = 0;
			if (position == JSM.CoordPlanePosition.CoordInFrontOfPlane) {
				type = 1;
			} else if (position == JSM.CoordPlanePosition.CoordAtBackOfPlane) {
				type = -1;
			}
			return type;
		},
		getIntersectionVertex : function (prevVertex, currVertex) {
			var line = new JSM.Line (currVertex, JSM.CoordSub (currVertex, prevVertex));
			var intersection = new JSM.Coord (0.0, 0.0, 0.0);
			var linePlanePosition = plane.LinePosition (line, intersection);
			if (linePlanePosition != JSM.LinePlanePosition.LineIntersectsPlane) {
				return null;
			}
			return intersection;
		},
		getVertexDistances : function (polygon, vertexIndices, referenceCoord1, referenceCoord2) {
			var direction = JSM.CoordSub (referenceCoord2, referenceCoord1);
			var referencePlane = JSM.GetPlaneFromCoordAndDirection (referenceCoord1, direction);
			var i, vertex;
			var distances = [];
			for (i = 0; i < vertexIndices.length; i++) {
				vertex = polygon.GetVertex (vertexIndices[i]);
				distances.push (referencePlane.CoordSignedDistance (vertex));
			}
			return distances;
		}
	};

	return JSM.CutPolygonInternal (polygon, geometryInterface, frontPolygons, backPolygons, cutPolygons);
};
<commit_msg>Some refactoring.<commit_after>JSM.CutPolygonInternal = function (polygon, geometryInterface, aSidePolygons, bSidePolygons, cutPolygons)
{
	function DetectOriginalVertexTypes (polygon)
	{
		var cutInformation = {
			originalVertexTypes : [],
			backFound : false,
			frontFound : false
		};
		var i, vertex, type;
		for (i = 0; i < polygon.VertexCount (); i++) {
			vertex = polygon.GetVertex (i);
			type = geometryInterface.getVertexSide (vertex);
			if (type == 1) {
				cutInformation.frontFound = true;
			} else if (type == -1) {
				cutInformation.backFound = true;
			}
			cutInformation.originalVertexTypes.push (type);
		}
		return cutInformation;
	}

	function AddCutVerticesToPolygon (polygon, cutPolygon, originalVertexTypes)
	{
		function AddVertex (polygon, index, cutPolygon, originalVertexTypes, cutVertexTypes)
		{
			function IsIntersectionVertex (cutVertexTypes, originalType)
			{
				if (cutVertexTypes.length === 0) {
					return false;
				}
				var prevType = cutVertexTypes[cutVertexTypes.length - 1];
				return prevType !== 0 && originalType !== 0 && prevType != originalType;
			}

			function AddIntersectionVertex (polygon, cutPolygon, cutVertexTypes, currIndex)
			{
				var prevIndex = polygon.GetPrevVertex (currIndex);
				var prevVertex = polygon.GetVertex (prevIndex);
				var currVertex = polygon.GetVertex (currIndex);
				var intersection = geometryInterface.getIntersectionVertex (prevVertex, currVertex);
				if (intersection !== null) {
					cutPolygon.AddVertexCoord (intersection);
					cutVertexTypes.push (0);
				}
			}

			function AddOriginalVertex (polygon, cutPolygon, cutVertexTypes, currIndex, originalType)
			{
				cutPolygon.AddVertexCoord (polygon.GetVertex (currIndex).Clone ());
				cutVertexTypes.push (originalType);
			}

			var lastVertex = (index === polygon.VertexCount ());
			var currIndex = index;
			if (lastVertex) {
				currIndex = 0;
			}

			var originalType = originalVertexTypes[currIndex];
			if (IsIntersectionVertex (cutVertexTypes, originalType)) {
				AddIntersectionVertex (polygon, cutPolygon, cutVertexTypes, currIndex);
			}
			if (!lastVertex) {
				AddOriginalVertex (polygon, cutPolygon, cutVertexTypes, currIndex, originalType);
			}
		}

		var cutVertexTypes = [];
		var i;
		for (i = 0; i <= polygon.VertexCount (); i++) {
			AddVertex (polygon, i, cutPolygon, originalVertexTypes, cutVertexTypes);
		}
		return cutVertexTypes;
	}

	function AddCuttedPolygons (cutPolygon, cutVertexTypes, aSidePolygons, bSidePolygons)
	{
		function GetEntryVertices (cutVertexTypes)
		{
			function FindPrevSideType (index, cutVertexTypes)
			{
				var currIndex = JSM.PrevIndex (index, cutVertexTypes.length);
				while (currIndex != index) {
					if (cutVertexTypes[currIndex] !== 0) {
						return cutVertexTypes[currIndex];
					}
					currIndex = JSM.PrevIndex (currIndex, cutVertexTypes.length);
				}
				return 0;
			}

			var entryVertices = [];
			var i, currSide, prevIndex, nextIndex, prevSideType, nextSideType;
			for (i = 0; i < cutVertexTypes.length; i++) {
				currSide = cutVertexTypes[i];
				if (currSide === 0) {
					prevIndex = JSM.PrevIndex (i, cutVertexTypes.length);
					nextIndex = JSM.NextIndex (i, cutVertexTypes.length);
					prevSideType = cutVertexTypes[prevIndex];
					nextSideType = cutVertexTypes[nextIndex];
					if (nextSideType !== 0 && prevSideType === 0) {
						prevSideType = FindPrevSideType (prevIndex, cutVertexTypes);
					}
					if ((prevSideType == -1 && nextSideType == 1) || (prevSideType == 1 && nextSideType == -1)) {
						entryVertices.push (i);
					}
				}
			}
			return entryVertices;
		}

		function SortEntryVertices (cutPolygon, entryVertices)
		{
			function SwapArrayValues (array, from, to)
			{
				var temp = array[from];
				array[from] = array[to];
				array[to] = temp;
			}

			if (entryVertices.length < 2) {
				return;
			}

			var referenceCoord1 = cutPolygon.GetVertex (entryVertices[0]);
			var referenceCoord2 = cutPolygon.GetVertex (entryVertices[1]);
			var distances = geometryInterface.getVertexDistances (cutPolygon, entryVertices, referenceCoord1, referenceCoord2);
			var i, j;
			for (i = 0; i < entryVertices.length - 1; i++) {
				for (j = 0; j < entryVertices.length - i - 1; j++) {
					if (JSM.IsGreater (distances[j], distances[j + 1])) {
						SwapArrayValues (distances, j, j + 1);
						SwapArrayValues (entryVertices, j, j + 1);
					}
				}
			}
		}

		function GetOneSideCuttedPolygons (cutPolygon, entryVertices, cutVertexTypes, aSidePolygons, bSidePolygons, reversed)
		{
			function AddEntryPairToArray (entryPairs, entryVertices, index)
			{
				entryPairs[entryVertices[index]] = entryVertices[index + 1];
				entryPairs[entryVertices[index + 1]] = entryVertices[index];
			}

			function RemoveEntryPairFromArray (entryPairs, index)
			{
				entryPairs[entryPairs[index]] = -1;
				entryPairs[index] = -1;
			}

			function CreateEntryPairsArray (cutPolygon, entryVertices, entryPairs)
			{
				var i;
				for (i = 0; i < cutPolygon.VertexCount (); i++) {
					entryPairs.push (-1);
				}
				for (i = 0; i < entryVertices.length; i = i + 2) {
					AddEntryPairToArray (entryPairs, entryVertices, i);
				}
			}

			function GetNextVertex (currVertexIndex, cutPolygon, entryPairs)
			{
				if (entryPairs[currVertexIndex] != -1) {
					var nextVertex = entryPairs[currVertexIndex];
					RemoveEntryPairFromArray (entryPairs, currVertexIndex);
					return nextVertex;
				} else {
					return JSM.NextIndex (currVertexIndex, cutPolygon.VertexCount ());
				}
			}

			function AddCutPolygon (cutPolygon, cutVertexTypes, entryVertices, currEntryVertex, aSidePolygons, bSidePolygons)
			{
				var startVertexIndex = entryVertices[currEntryVertex];
				if (entryPairs[startVertexIndex] !== -1) {
					var currPolygon = geometryInterface.createPolygon ();
					currPolygon.AddVertexCoord (cutPolygon.GetVertex (startVertexIndex).Clone ());
					var currVertexIndex = GetNextVertex (startVertexIndex, cutPolygon, entryPairs);
					var polygonSide = null;
					while (currVertexIndex != startVertexIndex) {
						if (polygonSide === null) {
							if (cutVertexTypes[currVertexIndex] !== 0) {
								polygonSide = cutVertexTypes[currVertexIndex];
							}
						}
						currPolygon.AddVertexCoord (cutPolygon.GetVertex (currVertexIndex).Clone ());
						currVertexIndex = GetNextVertex (currVertexIndex, cutPolygon, entryPairs);
					}
					if (polygonSide == 1) {
						aSidePolygons.push (currPolygon);
					} else if (polygonSide == -1) {
						bSidePolygons.push (currPolygon);
					}
				}

			}

			var entryPairs = [];
			CreateEntryPairsArray (cutPolygon, entryVertices, entryPairs);
			var currEntryVertex = reversed ? entryVertices.length - 1 : 0;
			while (currEntryVertex >= 0 && currEntryVertex < entryVertices.length) {
				AddCutPolygon (cutPolygon, cutVertexTypes, entryVertices, currEntryVertex, aSidePolygons, bSidePolygons);
				currEntryVertex = reversed ? currEntryVertex - 2 : currEntryVertex + 2;
			}
		}

		var entryVertices = GetEntryVertices (cutVertexTypes);
		if (entryVertices.length === 0 || entryVertices.length % 2 !== 0) {
			return;
		}

		SortEntryVertices (cutPolygon, entryVertices);
		GetOneSideCuttedPolygons (cutPolygon, entryVertices, cutVertexTypes, aSidePolygons, bSidePolygons, false);
		GetOneSideCuttedPolygons (cutPolygon, entryVertices, cutVertexTypes, aSidePolygons, bSidePolygons, true);
	}

	var cutPolygon = geometryInterface.createPolygon ();
	var cutInformation = DetectOriginalVertexTypes (polygon);

	if (cutInformation.backFound && cutInformation.frontFound) {
		var cutVertexTypes = AddCutVerticesToPolygon (polygon, cutPolygon, cutInformation.originalVertexTypes);
		AddCuttedPolygons (cutPolygon, cutVertexTypes, aSidePolygons, bSidePolygons);
	} else {
		var cloned = polygon.Clone ();
		if (cutInformation.frontFound) {
			aSidePolygons.push (cloned);
		} else if (cutInformation.backFound) {
			bSidePolygons.push (cloned);
		} else {
			cutPolygons.push (cloned);
		}
	}

	if (aSidePolygons.length + bSidePolygons.length + cutPolygons.length === 0) {
		return false;
	}
	return true;
};

/**
* Function: CutPolygon2DWithLine
* Description:
*	Cuts a polygon with a line. The result array contains cutted
*	polygons grouped by their position to the line.
* Parameters:
*	polygon {Polygon2D} the polygon
*	line {Line2D} the line
*	leftPolygons {Polygon2D[*]} (out) polygons on the left of the line
*	rightPolygons {Polygon2D[*]} (out) polygons on the right of the line
*	cutPolygons {Polygon2D[*]} (out) polygons on the line
* Returns:
*	{boolean} success
*/
JSM.CutPolygon2DWithLine = function (polygon, line, leftPolygons, rightPolygons, cutPolygons)
{
	var geometryInterface = {
		createPolygon : function () {
			return new JSM.Polygon2D ();
		},
		getVertexSide : function (vertex) {
			var position = line.CoordPosition (vertex);
			var type = 0;
			if (position == JSM.CoordLinePosition2D.CoordAtLineLeft) {
				type = 1;
			} else if (position == JSM.CoordLinePosition2D.CoordAtLineRight) {
				type = -1;
			}
			return type;
		},
		getIntersectionVertex : function (prevVertex, currVertex) {
			var edgeLine = new JSM.Line2D (currVertex, JSM.CoordSub2D (currVertex, prevVertex));
			var intersection = new JSM.Coord2D (0.0, 0.0);
			var lineLinePosition = line.LinePosition (edgeLine, intersection);
			if (lineLinePosition != JSM.LineLinePosition2D.LinesIntersectsOnePoint) {
				return null;
			}
			return intersection;
		},
		getVertexDistances : function (polygon, vertexIndices, referenceCoord1, referenceCoord2) {
			var direction = JSM.CoordSub2D (referenceCoord2, referenceCoord1);
			var i, vertex;
			var distances = [];
			for (i = 0; i < vertexIndices.length; i++) {
				vertex = polygon.GetVertex (vertexIndices[i]);
				distances.push (JSM.CoordSignedDistance2D (referenceCoord1, vertex, direction));
			}
			return distances;
		}
	};

	return JSM.CutPolygonInternal (polygon, geometryInterface, leftPolygons, rightPolygons, cutPolygons);
};

/**
* Function: CutPolygonWithPlane
* Description:
*	Cuts a polygon with a plane. The result array contains cutted
*	polygons grouped by their position to the plane.
* Parameters:
*	polygon {Polygon} the polygon
*	plane {Plane} the plane
*	frontPolygons {Polygon[*]} (out) polygons in front of the plane
*	backPolygons {Polygon[*]} (out) polygons at the back of the plane
*	cutPolygons {Polygon[*]} (out) polygons on the plane
* Returns:
*	{boolean} success
*/
JSM.CutPolygonWithPlane = function (polygon, plane, frontPolygons, backPolygons, cutPolygons)
{
	var geometryInterface = {
		createPolygon : function () {
			return new JSM.Polygon ();
		},
		getVertexSide : function (vertex) {
			var position = plane.CoordPosition (vertex);
			var type = 0;
			if (position == JSM.CoordPlanePosition.CoordInFrontOfPlane) {
				type = 1;
			} else if (position == JSM.CoordPlanePosition.CoordAtBackOfPlane) {
				type = -1;
			}
			return type;
		},
		getIntersectionVertex : function (prevVertex, currVertex) {
			var line = new JSM.Line (currVertex, JSM.CoordSub (currVertex, prevVertex));
			var intersection = new JSM.Coord (0.0, 0.0, 0.0);
			var linePlanePosition = plane.LinePosition (line, intersection);
			if (linePlanePosition != JSM.LinePlanePosition.LineIntersectsPlane) {
				return null;
			}
			return intersection;
		},
		getVertexDistances : function (polygon, vertexIndices, referenceCoord1, referenceCoord2) {
			var direction = JSM.CoordSub (referenceCoord2, referenceCoord1);
			var referencePlane = JSM.GetPlaneFromCoordAndDirection (referenceCoord1, direction);
			var i, vertex;
			var distances = [];
			for (i = 0; i < vertexIndices.length; i++) {
				vertex = polygon.GetVertex (vertexIndices[i]);
				distances.push (referencePlane.CoordSignedDistance (vertex));
			}
			return distances;
		}
	};

	return JSM.CutPolygonInternal (polygon, geometryInterface, frontPolygons, backPolygons, cutPolygons);
};
<|endoftext|>


<commit_before>/*
 +--------------------------------------------------------------------+
 | CiviCRM Widget Creation Interface (WCI) Version 1.0                |
 +--------------------------------------------------------------------+
 | Copyright Zyxware Technologies (c) 2014                            |
 +--------------------------------------------------------------------+
 | This file is a part of CiviCRM WCI.                                |
 |                                                                    |
 | CiviCRM WCI is free software; you can copy, modify, and distribute |
 | it under the terms of the GNU Affero General Public License        |
 | Version 3, 19 November 2007.                                       |
 |                                                                    |
 | CiviCRM WCI is distributed in the hope that it will be useful,     |
 | but WITHOUT ANY WARRANTY; without even the implied warranty of     |
 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
 | See the GNU Affero General Public License for more details.        |
 |                                                                    |
 | You should have received a copy of the GNU Affero General Public   |
 | License along with this program; if not, contact Zyxware           |
 | Technologies at info[AT]zyxware[DOT]com.                           |
 +--------------------------------------------------------------------+
*/

cj(function ( $ ) {
  $("#ProgressBar").validate({
    rules: {
      starting_amount: {
        required: true,
        number: true
      },
      progressbar_name: {
        required: true
      },
      goal_amount: {
        required: true,
        number: true
      },
      contribution_page_1: {
        required: true
      },
      percentage_1: {
        required: true,
        max: 100,
        number: true
      }
    }
  });

  $('#addmore_link').on('click', function( e ) {
    e.preventDefault();
    var count = parseInt($('input[name=contrib_count]').val());
    lastElem = "#addmore_link";
    eval("fname = $('"+lastElem+"').parent().parent();");

    count++;
    dataUrl = "civicrm/wci/progress-bar/add?PBSource_block=1&snippet=4&PBblockId=" + count;

    cj.ajax({
        url     : dataUrl,
        async   : false,
        success : function(html){
            cj(fname).before(html);
        }
    });
    $('input[name=contrib_count]').val(count);

  });

  $(document).on('click', '#remove_link', function( e ) {
    e.preventDefault();

    var rem_name = e.target.name;
    //assuming that - is the delimiter. second string will be the count
    var rem_name_ar = rem_name.split('-');

    $('input[name=rem_ids]').val($('input[name=contrib_elem_'+ rem_name_ar[1]+']').val() + ',' + $('input[name=rem_ids]').val());

    $('#PBSource-'+ rem_name_ar[1]).remove();
    $('#contrib_elem_'+ rem_name_ar[1]).remove();

    $('input[name=contrib_elem_'+ rem_name_ar[1]+']').remove();

    var count = parseInt($('input[name=contrib_count]').val());
    count--;
    $('input[name=contrib_count]').val(count);
  });
});
<commit_msg>#33104 corrected addmore.js location to paste ajax return<commit_after>/*
 +--------------------------------------------------------------------+
 | CiviCRM Widget Creation Interface (WCI) Version 1.0                |
 +--------------------------------------------------------------------+
 | Copyright Zyxware Technologies (c) 2014                            |
 +--------------------------------------------------------------------+
 | This file is a part of CiviCRM WCI.                                |
 |                                                                    |
 | CiviCRM WCI is free software; you can copy, modify, and distribute |
 | it under the terms of the GNU Affero General Public License        |
 | Version 3, 19 November 2007.                                       |
 |                                                                    |
 | CiviCRM WCI is distributed in the hope that it will be useful,     |
 | but WITHOUT ANY WARRANTY; without even the implied warranty of     |
 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
 | See the GNU Affero General Public License for more details.        |
 |                                                                    |
 | You should have received a copy of the GNU Affero General Public   |
 | License along with this program; if not, contact Zyxware           |
 | Technologies at info[AT]zyxware[DOT]com.                           |
 +--------------------------------------------------------------------+
*/

cj(function ( $ ) {
  $("#ProgressBar").validate({
    rules: {
      starting_amount: {
        required: true,
        number: true
      },
      progressbar_name: {
        required: true
      },
      goal_amount: {
        required: true,
        number: true
      },
      contribution_page_1: {
        required: true
      },
      percentage_1: {
        required: true,
        max: 100,
        number: true
      }
    }
  });

  $('#addmore_link').on('click', function( e ) {
    e.preventDefault();
    var count = parseInt($('input[name=contrib_count]').val());
    fname = $('#addmore_link').parent().parent();

    count++;
    dataUrl = "civicrm/wci/progress-bar/add?PBSource_block=1&snippet=4&PBblockId=" + count;

    cj.ajax({
        url     : dataUrl,
        async   : false,
        success : function(html){
            fname.before(html);
        }
    });
    $('input[name=contrib_count]').val(count);

  });

  $(document).on('click', '#remove_link', function( e ) {
    e.preventDefault();

    var rem_name = e.target.name;
    //assuming that - is the delimiter. second string will be the count
    var rem_name_ar = rem_name.split('-');

    $('input[name=rem_ids]').val($('input[name=contrib_elem_'+ rem_name_ar[1]+']').val() + ',' + $('input[name=rem_ids]').val());

    $('#PBSource-'+ rem_name_ar[1]).remove();
    $('#contrib_elem_'+ rem_name_ar[1]).remove();

    $('input[name=contrib_elem_'+ rem_name_ar[1]+']').remove();

    var count = parseInt($('input[name=contrib_count]').val());
    count--;
    $('input[name=contrib_count]').val(count);
  });
});
<|endoftext|>


<commit_before>import React, { Component } from 'react';

export default class Footer extends Component {
  trackDonate() {
    mixpanel.track('Clicked Donate');
  }

  render() {
    let styleObj = {
      textAlign: 'center',
    };
    return (

            Feedback

          Brought to you by the good folks at Evil Corp
          Donate Here

    )
  }
};
<commit_msg>Added MixPanel image<commit_after>import React, { Component } from 'react';

export default class Footer extends Component {
  trackDonate() {
    mixpanel.track('Clicked Donate');
  }

  render() {
    let styleObj = {
      textAlign: 'center',
    };

    let mixPanelImg = {
      margin: 'auto',
      paddingRight: '30px'
    };

    return (

            Feedback

          Brought to you by the good folks at Evil Corp
          Donate Here

    )
  }
};
<|endoftext|>


<commit_before><commit_msg>fix non string message<commit_after><|endoftext|>


<commit_before><commit_msg>Formio: add onload param to requireLibrary<commit_after><|endoftext|>


<commit_before>// @flow

import React, { Component, Children, cloneElement, type ReactElement } from 'react';
import { View, Animated, StyleSheet, ScrollView, Dimensions } from 'react-native';
import AnimatedOverlay from 'react-native-animated-overlay';
import _ from 'lodash';

import Separator from './Separator';
import Animation from './Animation';

const { width: WIDTH, height: HEIGHT } = Dimensions.get('window');

// action sheet states
const ACTION_SHEET_OPENING: string = 'opening';
const ACTION_SHEET_OPENED: string = 'opened';
const ACTION_SHEET_CLOSING: string = 'closing';
const ACTION_SHEET_CLOSED: string = 'closed';

const DEFAULT_ANIMATION_DURATION: number = 250;

const INITIAL_TOP_POSITION: number = -180;
const INITIAL_BOTTOM_POSITION: number = HEIGHT * -1;

const styles = StyleSheet.create({
  container: {
    position: 'absolute',
    top: 0,
    left: 0,
    backgroundColor: 'white',
  },
  contentContainer: {
    width: WIDTH,
    position: 'absolute',
    backgroundColor: 'white',
  },
  scrollView: {
  },
  hidden: {
    top: -10000,
    left: 0,
    height: 0,
    width: 0,
  },
});

type Props = {
  onShow?: () => void;
  onHide?: () => void;
  show?: boolean;
  animationDuration?: number;
  overlayOpacity?: number;
  position?: 'top' | 'bottom';
  onChange?: () => void;
  multiple?: boolean;
  showSparator?: boolean;
  value?: any;
  defaultValue?: any;
  hideOnSelceted?: boolean;
  children?: any;
};

const defaultProps = {
  onShow: () => {},
  onHide: () => {},
  show: false,
  animationDuration: DEFAULT_ANIMATION_DURATION,
  overlayOpacity: 0.3,
  position: 'top',
  onChange: () => {},
  multiple: false,
  showSparator: true,
  value: null,
  defaultValue: null,
  hideOnSelceted: true,
  children: null,
};

class ActionSheet extends Component {
  props: Props

  static defaultProps = defaultProps

  constructor(props: Props) {
    super(props);

    let initValue = (props.value || props.defaultValue);
    initValue = Array.isArray(initValue)
      ? initValue
      : (initValue === null && []) || [initValue];

    this.state = {
      show: props.show,
      selectedData: initValue,
      actionSheetState: ACTION_SHEET_CLOSED,
      actionSheetAnimation: new Animation(this.hideActionSheetPosition),
    };
  }

  componentDidMount() {
    if (this.props.show) {
      this.show();
    }
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.position !== nextProps.position) {
      this.setState({ actionSheetAnimation: new Animation(this.hideActionSheetPosition) });
    }

    if (this.props.show !== nextProps.show) {
      if (nextProps.show) {
        this.show();
      } else {
        this.hide();
      }
    }

    if (!_.isEqual(this.props.value, nextProps.value)) {
      const selectedData = [];
      nextProps.value.forEach((value) => {
        if (!this.props.multiple && selectedData.length !== 0) {
          return;
        }
        selectedData.push(value);
      });
      this.setState({ selectedData });
    }
  }

  get showActionSheetPosition(): string {
    const { position } = this.props;
    if (position === 'top') {
      return INITIAL_TOP_POSITION * -1;
    }
    return 0;
  }

  get hideActionSheetPosition(): string {
    const { position } = this.props;
    if (position === 'top') {
      return INITIAL_TOP_POSITION;
    }
    return INITIAL_BOTTOM_POSITION * -1;
  }

  onOverlayPress = (): void => {
    this.hide();
  }

  setActionSheetState(toValue: number, callback?: Function = () => {}): void {
    const { animationDuration } = this.props;
    const isClosed = (this.state.actionSheetState === ACTION_SHEET_CLOSED);

    let actionSheetState = isClosed ? ACTION_SHEET_OPENING : ACTION_SHEET_CLOSING;

    this.setState({ actionSheetState });

    this.state.actionSheetAnimation.toValue(toValue, animationDuration, () => {
      const isClosing = (this.state.actionSheetState === ACTION_SHEET_CLOSING);
      actionSheetState = isClosing ? ACTION_SHEET_CLOSED : ACTION_SHEET_OPENED;

      this.setState({ actionSheetState });
      callback();
    });
  }

  show = (callback?: Function = () => {}): void => {
    if ([ACTION_SHEET_OPENING, ACTION_SHEET_OPENED].includes(this.state.actionSheetState)) {
      return;
    }

    const { onShow } = this.props;

    this.setState({ show: true });
    this.setActionSheetState(this.showActionSheetPosition);
    onShow();
    callback();
  }

  hide = (callback?: Function = () => {}): void => {
    if ([ACTION_SHEET_CLOSING, ACTION_SHEET_CLOSED].includes(this.state.actionSheetState)) {
      return;
    }

    const { onHide } = this.props;

    this.setState({ show: false });
    this.setActionSheetState(this.hideActionSheetPosition);
    onHide();
    callback();
  }

  onItemPress(value, index): void {
    const { hideOnSelceted } = this.props;
    if (hideOnSelceted) {
      this.hide();
    }

    if (Object.values(this.state.selectedData).includes(value)) {
      this.unselectItem(value, index);
      return;
    }

    this.selectItem(value, index);
  }

  selectItem(value, index) {
    const { multiple: isMultiSelect, onChange } = this.props;
    let selectedData = [];

    if (isMultiSelect) {
      selectedData = [...this.state.selectedData];
    }

    selectedData.push(value);
    this.setState({ selectedData });
    onChange(value, index, selectedData);
  }

  unselectItem(value, index) {
    const { multiple: isMultiSelect, onChange } = this.props;
    let selectedData = [];

    if (isMultiSelect) {
      selectedData = [...this.state.selectedData];
      selectedData.splice(index, 1);
    }

    this.setState({ selectedData });
    onChange(value, index, selectedData);
  }

  isItemSelected(index): boolean {
    return !!this.state.selectedData[index];
  }

  renderItems(): ReactElement {
    const { children, showSparator } = this.props;

    return Children.map(children, (child, i) => {
      let separator = null;
      const index = this.state.selectedData.indexOf(child.value);

      if (showSparator && i < children.length - 1) {
        separator = <Separator />;
      }

      const item = cloneElement(child, {
        index,
        selected: this.state.selectedData.includes(child.props.value),
        onPress: (selectedValue, selectedIndex) => {
          child.props.onPress(selectedValue, selectedIndex);
          this.onItemPress(selectedValue, selectedIndex);
        },
      });

      return (
        <View style={{ flex: 1 }}>
          {item}
          {separator}
        </View>
      );
    });
  }

  render() {
    const { animationDuration, overlayOpacity, position } = this.props;
    const { actionSheetState, actionSheetAnimation: { animations } } = this.state;

    const overlayShow = [ACTION_SHEET_OPENED, ACTION_SHEET_OPENING].includes(actionSheetState);
    const pointerEvents = (actionSheetState === ACTION_SHEET_OPENED) ? 'auto' : 'none';
    const hidden = actionSheetState === ACTION_SHEET_CLOSED && styles.hidden;

    const actionSheetPosition = (position === 'top')
      ? { top: INITIAL_TOP_POSITION }
      : { bottom: INITIAL_BOTTOM_POSITION };

    const scrollView = (position === 'top')
      ? { paddingTop: 30 }
      : null;

    return (
      <View style={[styles.container, hidden]}>
        <AnimatedOverlay
          onPress={this.onOverlayPress}
          overlayShow={overlayShow}
          duration={animationDuration}
          opacity={overlayOpacity}
          pointerEvents={pointerEvents}
        />
        <Animated.View
          style={[styles.contentContainer, actionSheetPosition, animations]}
        >
          <ScrollView style={[styles.scrollView, scrollView]}>
            {this.renderItems()}
          </ScrollView>
        </Animated.View>
      </View>
    );
  }
}

export default ActionSheet;
<commit_msg>add back press event handler and bug fixes and code refactoring.<commit_after>// @flow

import React, { Component, Children, cloneElement, type ReactElement } from 'react';
import { View, Animated, StyleSheet, ScrollView, Dimensions, BackAndroid } from 'react-native';
import AnimatedOverlay from 'react-native-animated-overlay';
import _ from 'lodash';

import Separator from './Separator';
import Animation from './Animation';

const { width: WIDTH, height: HEIGHT } = Dimensions.get('window');

// action sheet states
const ACTION_SHEET_OPENING: string = 'opening';
const ACTION_SHEET_OPENED: string = 'opened';
const ACTION_SHEET_CLOSING: string = 'closing';
const ACTION_SHEET_CLOSED: string = 'closed';

const DEFAULT_ANIMATION_DURATION: number = 250;
const INITIAL_TOP_POSITION: number = -180;
const INITIAL_BOTTOM_POSITION: number = HEIGHT * -1;

// events
const HARDWARE_BACK_PRESS_EVENT: string = 'hardwareBackPress';

const styles = StyleSheet.create({
  container: {
    position: 'absolute',
    top: 0,
    left: 0,
    backgroundColor: 'white',
  },
  contentContainer: {
    width: WIDTH,
    position: 'absolute',
    backgroundColor: 'white',
  },
  scrollView: {
  },
  hidden: {
    top: -10000,
    left: 0,
    height: 0,
    width: 0,
  },
});

type Props = {
  onShow?: () => void;
  onHide?: () => void;
  show?: boolean;
  animationDuration?: number;
  overlayOpacity?: number;
  position?: 'top' | 'bottom';
  onChange?: () => void;
  multiple?: boolean;
  showSparator?: boolean;
  value?: any;
  defaultValue?: any;
  hideOnSelceted?: boolean;
  hideOnHardwareBackPress?: boolean;
  children?: any;
};

const defaultProps = {
  onShow: () => {},
  onHide: () => {},
  show: false,
  animationDuration: DEFAULT_ANIMATION_DURATION,
  overlayOpacity: 0.3,
  position: 'top',
  onChange: () => {},
  multiple: false,
  showSparator: true,
  value: null,
  defaultValue: null,
  hideOnSelceted: true,
  hideOnHardwareBackPress: true,
  children: null,
};

class ActionSheet extends Component {
  props: Props

  static defaultProps = defaultProps

  constructor(props: Props) {
    super(props);

    let initValue = (props.value || props.defaultValue);
    initValue = Array.isArray(initValue)
      ? initValue
      : (initValue === null && []) || [initValue];

    this.state = {
      show: props.show,
      selectedData: initValue,
      actionSheetState: ACTION_SHEET_CLOSED,
      actionSheetAnimation: new Animation(this.hideActionSheetPosition),
    };
  }

  componentDidMount() {
    if (this.props.show) {
      this.show();
    }

    BackAndroid.addEventListener(HARDWARE_BACK_PRESS_EVENT, this.hardwareBackPressHandler);
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.position !== nextProps.position) {
      this.setState({ actionSheetAnimation: new Animation(this.hideActionSheetPosition) });
    }

    if (this.props.show !== nextProps.show) {
      if (nextProps.show) {
        this.show();
      } else {
        this.hide();
      }
    }

    if (!_.isEqual(this.props.value, nextProps.value)) {
      const selectedData = [];
      nextProps.value.forEach((value) => {
        if (!this.props.multiple && selectedData.length !== 0) {
          return;
        }
        selectedData.push(value);
      });
      this.setState({ selectedData });
    }
  }

  componentWillUnmount() {
    BackAndroid.removeEventListener(HARDWARE_BACK_PRESS_EVENT);
  }

  get showActionSheetPosition(): number {
    const { position } = this.props;
    if (position === 'top') {
      return INITIAL_TOP_POSITION * -1;
    }
    return 0;
  }

  get hideActionSheetPosition(): number {
    const { position } = this.props;
    if (position === 'top') {
      return INITIAL_TOP_POSITION;
    }
    return INITIAL_BOTTOM_POSITION * -1;
  }

  onOverlayPress = (): void => {
    this.hide();
  }

  setActionSheetState(toValue: number, callback?: Function = () => {}): void {
    const { animationDuration } = this.props;
    const isClosed = (this.state.actionSheetState === ACTION_SHEET_CLOSED);

    let actionSheetState = isClosed ? ACTION_SHEET_OPENING : ACTION_SHEET_CLOSING;

    this.setState({ actionSheetState });

    this.state.actionSheetAnimation.toValue(toValue, animationDuration, () => {
      const isClosing = (this.state.actionSheetState === ACTION_SHEET_CLOSING);
      actionSheetState = isClosing ? ACTION_SHEET_CLOSED : ACTION_SHEET_OPENED;

      this.setState({ actionSheetState });
      callback();
    });
  }

  hardwareBackPressHandler = (): boolean => {
    const { hideOnHardwareBackPress } = this.props;

    if (hideOnHardwareBackPress && this.state.show) {
      this.hide();
      return true;
    }

    return false;
  }

  show = (callback?: Function = () => {}): void => {
    if ([ACTION_SHEET_OPENING, ACTION_SHEET_OPENED].includes(this.state.actionSheetState)) {
      return;
    }

    const { onShow } = this.props;

    this.setState({ show: true });
    this.setActionSheetState(this.showActionSheetPosition);
    onShow();
    callback();
  }

  hide = (callback?: Function = () => {}): void => {
    if ([ACTION_SHEET_CLOSING, ACTION_SHEET_CLOSED].includes(this.state.actionSheetState)) {
      return;
    }

    const { onHide } = this.props;

    this.setState({ show: false });
    this.setActionSheetState(this.hideActionSheetPosition);
    onHide();
    callback();
  }

  onItemPress = (value, index): void => {
    const { hideOnSelceted } = this.props;
    if (hideOnSelceted) {
      this.hide();
    }

    if (Object.values(this.state.selectedData).includes(value)) {
      this.unselectItem(value, index);
      return;
    }

    this.selectItem(value, index);
  }

  selectItem(value, index) {
    const { multiple: isMultiSelect, onChange } = this.props;
    let selectedData = [];

    if (isMultiSelect) {
      selectedData = [...this.state.selectedData];
    }

    selectedData.push(value);
    this.setState({ selectedData });
    onChange(value, index, selectedData);
  }

  unselectItem(value, index) {
    const { multiple: isMultiSelect, onChange } = this.props;
    let selectedData = [];

    if (isMultiSelect) {
      selectedData = [...this.state.selectedData];
      selectedData.splice(index, 1);
    }

    this.setState({ selectedData });
    onChange(value, index, selectedData);
  }

  renderItems(): ReactElement {
    const { children, showSparator } = this.props;

    return Children.map(children, (child, childIndex) => {
      let separator = null;
      const selectedIndex = this.state.selectedData.indexOf(child.props.value);

      // don't show parator for last action sheet item. just because more beautiful.
      if (showSparator && childIndex < children.length - 1) {
        separator = <Separator />;
      }

      const item = cloneElement(child, {
        index: selectedIndex,
        selected: this.state.selectedData.includes(child.props.value),
        onPress: (_selectedValue, _selectedIndex) => {
          child.props.onPress(_selectedValue, _selectedIndex);
          this.onItemPress(_selectedValue, _selectedIndex);
        },
      });

      return (
        <View style={{ flex: 1 }}>
          {item}
          {separator}
        </View>
      );
    });
  }

  render() {
    const { animationDuration, overlayOpacity, position } = this.props;
    const { actionSheetState, actionSheetAnimation: { animations } } = this.state;

    const overlayShow = [ACTION_SHEET_OPENED, ACTION_SHEET_OPENING].includes(actionSheetState);
    const pointerEvents = (actionSheetState === ACTION_SHEET_OPENED) ? 'auto' : 'none';
    const hidden = actionSheetState === ACTION_SHEET_CLOSED && styles.hidden;

    const actionSheetPosition = (position === 'top')
      ? { top: INITIAL_TOP_POSITION }
      : { bottom: INITIAL_BOTTOM_POSITION };

    const scrollView = (position === 'top')
      ? { paddingTop: 30 }
      : null;

    return (
      <View style={[styles.container, hidden]}>
        <AnimatedOverlay
          onPress={this.onOverlayPress}
          overlayShow={overlayShow}
          duration={animationDuration}
          opacity={overlayOpacity}
          pointerEvents={pointerEvents}
        />
        <Animated.View
          style={[styles.contentContainer, actionSheetPosition, animations]}
        >
          <ScrollView style={[styles.scrollView, scrollView]}>
            {this.renderItems()}
          </ScrollView>
        </Animated.View>
      </View>
    );
  }
}

export default ActionSheet;
<|endoftext|>