Some comments (no changes to code)
This commit is contained in:
@@ -11,7 +11,9 @@ ol.ASSUME_TOUCH = false;
|
||||
* @type {Object}
|
||||
*/
|
||||
ol.BrowserFeature = {
|
||||
// Do we have touch events?
|
||||
/**
|
||||
* @type {boolean} True if browser supports touch events
|
||||
*/
|
||||
HAS_TOUCH: ol.ASSUME_TOUCH ||
|
||||
(document && 'ontouchstart' in document.documentElement)
|
||||
};
|
||||
|
||||
@@ -6,10 +6,10 @@ goog.require('goog.color');
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {number} r Red.
|
||||
* @param {number} g Green.
|
||||
* @param {number} b Blue.
|
||||
* @param {number} a Alpha.
|
||||
* @param {number} r Red, 0 to 255.
|
||||
* @param {number} g Green, 0 to 255.
|
||||
* @param {number} b Blue, 0 to 255.
|
||||
* @param {number} a Alpha, 0 (fully transparent) to 255 (fully opaque).
|
||||
*/
|
||||
ol.Color = function(r, g, b, a) {
|
||||
|
||||
|
||||
@@ -20,13 +20,19 @@ goog.require('ol.layer.Layer');
|
||||
|
||||
|
||||
/**
|
||||
* Shows credits / names of data providers for shown map layers.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.control.Control}
|
||||
* @param {ol.control.AttributionOptions} attributionOptions Attribution
|
||||
* options.
|
||||
*/
|
||||
ol.control.Attribution = function(attributionOptions) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Element} List of map's data sources. One list items gets appended
|
||||
* per data source.
|
||||
*/
|
||||
this.ulElement_ = goog.dom.createElement(goog.dom.TagName.UL);
|
||||
|
||||
var element = goog.dom.createDom(goog.dom.TagName.DIV, {
|
||||
@@ -35,7 +41,8 @@ ol.control.Attribution = function(attributionOptions) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
* @type {Array.<number>} Event handler identifiers to change attribution when
|
||||
* layers get added and removed.
|
||||
*/
|
||||
this.layersListenerKeys_ = null;
|
||||
|
||||
@@ -59,7 +66,8 @@ ol.control.Attribution = function(attributionOptions) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
* @type {Array.<number>} Event handler identifiers for handlers that monitor
|
||||
* changes to the map.
|
||||
*/
|
||||
this.mapListenerKeys_ = null;
|
||||
|
||||
@@ -74,6 +82,9 @@ goog.inherits(ol.control.Attribution, ol.control.Control);
|
||||
|
||||
|
||||
/**
|
||||
* Attaches handler to track visibility changes and creates attribution list
|
||||
* item.
|
||||
*
|
||||
* @param {ol.layer.Layer} layer Layer.
|
||||
* @protected
|
||||
*/
|
||||
@@ -297,6 +308,8 @@ ol.control.Attribution.prototype.handleMapChanged = function() {
|
||||
|
||||
|
||||
/**
|
||||
* Clears attribution and triggers refill whenever layers get added to the map
|
||||
* or are removed from the map.
|
||||
* @protected
|
||||
*/
|
||||
ol.control.Attribution.prototype.handleMapLayersChanged = function() {
|
||||
@@ -304,15 +317,19 @@ ol.control.Attribution.prototype.handleMapLayersChanged = function() {
|
||||
goog.array.forEach(this.layersListenerKeys_, goog.events.unlistenByKey);
|
||||
this.layersListenerKeys_ = null;
|
||||
}
|
||||
// Clear all attributions
|
||||
goog.object.forEach(this.attributionElements_, function(attributionElement) {
|
||||
goog.dom.removeNode(attributionElement);
|
||||
}, this);
|
||||
|
||||
this.attributionElements_ = {};
|
||||
this.coverageAreass_ = {};
|
||||
var map = this.getMap();
|
||||
var layers = map.getLayers();
|
||||
if (goog.isDefAndNotNull(layers)) {
|
||||
// Add attribution for layer
|
||||
layers.forEach(this.addLayer, this);
|
||||
|
||||
this.layersListenerKeys_ = [
|
||||
goog.events.listen(layers, ol.CollectionEventType.ADD,
|
||||
this.handleLayersAdd, false, this),
|
||||
@@ -378,6 +395,8 @@ ol.control.Attribution.prototype.setMap = function(map) {
|
||||
|
||||
|
||||
/**
|
||||
* Shows or hides attribution for a layer. The attribution is shown whenever the
|
||||
* layer is visible to the user.
|
||||
* @param {ol.layer.Layer} layer Layer.
|
||||
* @param {boolean} mapIsDef Map is defined.
|
||||
* @param {ol.Extent} mapExtent Map extent.
|
||||
|
||||
@@ -14,6 +14,9 @@ ol.control.ControlOptions;
|
||||
|
||||
|
||||
/**
|
||||
* A thing which is painted over the map to provide a means for interaction
|
||||
* (buttons) of show annotations (status bars).
|
||||
*
|
||||
* @constructor
|
||||
* @extends {goog.Disposable}
|
||||
* @param {ol.control.ControlOptions} controlOptions Control options.
|
||||
@@ -67,6 +70,10 @@ ol.control.Control.prototype.getMap = function() {
|
||||
|
||||
|
||||
/**
|
||||
* Removes the control from its current map and attaches it to the new map.
|
||||
* Subtypes might also wish set up event handlers to get notified about changes
|
||||
* to the map here.
|
||||
*
|
||||
* @param {ol.Map} map Map.
|
||||
*/
|
||||
ol.control.Control.prototype.setMap = function(map) {
|
||||
|
||||
@@ -13,6 +13,8 @@ ol.CoordinateFormatType;
|
||||
|
||||
|
||||
/**
|
||||
* Two dimensional coordinate which does not know its projection.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {goog.math.Vec2}
|
||||
* @param {number} x X.
|
||||
|
||||
@@ -5,6 +5,8 @@ goog.require('ol.Extent');
|
||||
|
||||
|
||||
/**
|
||||
* Represents a rectangular area.
|
||||
*
|
||||
* @constructor
|
||||
* @param {ol.Extent} extent Extent.
|
||||
*/
|
||||
|
||||
@@ -7,6 +7,9 @@ goog.require('ol.TransformFunction');
|
||||
|
||||
|
||||
/**
|
||||
* Rectangular extent which is not rotated. An extent does not know its
|
||||
* projection.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.Rectangle}
|
||||
* @param {number} minX Minimum X.
|
||||
@@ -21,6 +24,8 @@ goog.inherits(ol.Extent, ol.Rectangle);
|
||||
|
||||
|
||||
/**
|
||||
* Builds an extent that includes all given coordinates.
|
||||
*
|
||||
* @param {...ol.Coordinate} var_args Coordinates.
|
||||
* @return {!ol.Extent} Bounding extent.
|
||||
*/
|
||||
@@ -41,6 +46,8 @@ ol.Extent.boundingExtent = function(var_args) {
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the given coordinate is contained or on the edge of the extent.
|
||||
*
|
||||
* @param {ol.Coordinate} coordinate Coordinate.
|
||||
* @return {boolean} Contains.
|
||||
*/
|
||||
|
||||
@@ -80,7 +80,8 @@ ol.RendererHint = {
|
||||
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.RendererHint>}
|
||||
* @type {Array.<ol.RendererHint>} Desired renderers with most favoured renderer
|
||||
* first.
|
||||
*/
|
||||
ol.DEFAULT_RENDERER_HINTS = [
|
||||
ol.RendererHint.WEBGL,
|
||||
@@ -113,6 +114,9 @@ ol.MapProperty = {
|
||||
|
||||
|
||||
/**
|
||||
* Map composed of multiple layers. Maps in OpenLayers are responsible for
|
||||
* binding together the other components.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.Object}
|
||||
* @implements {goog.fx.anim.Animated}
|
||||
@@ -170,7 +174,7 @@ ol.Map = function(mapOptions) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Element}
|
||||
* @type {Element} Container into which the map is painted.
|
||||
*/
|
||||
this.target_ = mapOptionsInternal.target;
|
||||
|
||||
@@ -182,7 +186,7 @@ ol.Map = function(mapOptions) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Element}
|
||||
* @type {Element} Reference to the root element of the map in the DOM.
|
||||
*/
|
||||
this.viewport_ = goog.dom.createDom(goog.dom.TagName.DIV, 'ol-viewport');
|
||||
this.viewport_.style.position = 'relative';
|
||||
@@ -193,7 +197,8 @@ ol.Map = function(mapOptions) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Element}
|
||||
* @type {Element} Captures click events and cancels them so that interactions
|
||||
* within overlays don't influence the map.
|
||||
*/
|
||||
this.overlayContainer_ = goog.dom.createDom(goog.dom.TagName.DIV,
|
||||
'ol-overlaycontainer');
|
||||
@@ -244,7 +249,8 @@ ol.Map = function(mapOptions) {
|
||||
this.interactions_ = mapOptionsInternal.interactions;
|
||||
|
||||
/**
|
||||
* @type {ol.renderer.Map}
|
||||
* @type {ol.renderer.Map} Most favoured renderer given the supported of the
|
||||
* choices.
|
||||
* @private
|
||||
*/
|
||||
this.renderer_ =
|
||||
@@ -271,6 +277,7 @@ ol.Map = function(mapOptions) {
|
||||
|
||||
this.handleBrowserWindowResize();
|
||||
|
||||
// Notify all controls about the map they are assigned to
|
||||
this.controls_.forEach(
|
||||
/**
|
||||
* @param {ol.control.Control} control Control.
|
||||
@@ -292,7 +299,6 @@ ol.Map.prototype.canRotate = function() {
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.Map.prototype.disposeInternal = function() {
|
||||
@@ -359,7 +365,7 @@ goog.exportProperty(
|
||||
|
||||
|
||||
/**
|
||||
* @return {Element} Container.
|
||||
* @return {Element} Container into which the map is painted.
|
||||
*/
|
||||
ol.Map.prototype.getTarget = function() {
|
||||
return this.target_;
|
||||
@@ -644,6 +650,10 @@ ol.Map.prototype.handleUserProjectionChanged = function() {
|
||||
|
||||
|
||||
/**
|
||||
* Adjusts the map to its new size whenever the viewport size changes.
|
||||
* One should react the the resize of the map's viewport instead of the browser
|
||||
* viewport but there is no API to do so.
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
ol.Map.prototype.handleBrowserWindowResize = function() {
|
||||
@@ -1003,10 +1013,16 @@ ol.Map.createOptionsInternal = function(mapOptions) {
|
||||
*/
|
||||
var rendererHints;
|
||||
if (goog.isDef(mapOptions.renderers)) {
|
||||
// Use first supported renderer of the supported ones
|
||||
rendererHints = mapOptions.renderers;
|
||||
} else if (goog.isDef(mapOptions.renderer)) {
|
||||
// Use the given renderer
|
||||
// Support accepting a renderer instead of an array with a single renderer
|
||||
// for mapOptions.renderers.
|
||||
rendererHints = [mapOptions.renderer];
|
||||
} else {
|
||||
// Use the default order of preferred renderers if user did not specify a
|
||||
// preference.
|
||||
rendererHints = ol.DEFAULT_RENDERER_HINTS;
|
||||
}
|
||||
|
||||
@@ -1052,7 +1068,7 @@ ol.Map.createOptionsInternal = function(mapOptions) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {Element}
|
||||
* @type {Element} Container into which the map is painted.
|
||||
*/
|
||||
var target = goog.dom.getElement(mapOptions.target);
|
||||
|
||||
|
||||
@@ -131,6 +131,9 @@ ol.Projection.transforms_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Registers transformation functions that don't alter coordinates. Those allow
|
||||
* to transform between projections with equal meaning.
|
||||
*
|
||||
* @param {Array.<ol.Projection>} projections Projections.
|
||||
* @private
|
||||
*/
|
||||
@@ -148,10 +151,15 @@ ol.Projection.addEquivalentProjections_ = function(projections) {
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array.<ol.Projection>} projections1 Projections.
|
||||
* @param {Array.<ol.Projection>} projections2 Projections.
|
||||
* @param {ol.TransformFunction} forwardTransform Forward transform.
|
||||
* @param {ol.TransformFunction} inverseTransform Inverse transform.
|
||||
* Registers transformation functions to convert coordinates in any projection
|
||||
* in projection1 to any projection in projection2.
|
||||
*
|
||||
* @param {Array.<ol.Projection>} projections1 Projections with equal meaning.
|
||||
* @param {Array.<ol.Projection>} projections2 Projections with equal meaning.
|
||||
* @param {ol.TransformFunction} forwardTransform Transformation from any
|
||||
* projection in projection1 to any projection in projection2.
|
||||
* @param {ol.TransformFunction} inverseTransform Transform from any projection
|
||||
* in projection2 to any projection in projection1..
|
||||
* @private
|
||||
*/
|
||||
ol.Projection.addEquivalentTransforms_ =
|
||||
@@ -217,6 +225,9 @@ ol.Projection.createProjection = function(projection, defaultCode) {
|
||||
|
||||
|
||||
/**
|
||||
* Registers a conversion function to convert coordinates from the source
|
||||
* projection to the destination projection.
|
||||
*
|
||||
* @param {ol.Projection} source Source.
|
||||
* @param {ol.Projection} destination Destination.
|
||||
* @param {ol.TransformFunction} transformFn Transform.
|
||||
@@ -236,7 +247,8 @@ ol.Projection.addTransform = function(source, destination, transformFn) {
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} code Code.
|
||||
* @param {string} code Code which is a combination of authority and identifier
|
||||
* such as “EPSG:4326”.
|
||||
* @return {ol.Projection} Projection.
|
||||
*/
|
||||
ol.Projection.getFromCode = function(code) {
|
||||
@@ -270,6 +282,10 @@ ol.Projection.getProj4jsProjectionFromCode_ = function(code) {
|
||||
|
||||
|
||||
/**
|
||||
* Checks if two projections are the same, that is every coordinate in one
|
||||
* projection does represent the same geographic point as the same coordinate in
|
||||
* the other projection.
|
||||
*
|
||||
* @param {ol.Projection} projection1 Projection 1.
|
||||
* @param {ol.Projection} projection2 Projection 2.
|
||||
* @return {boolean} Equivalent.
|
||||
@@ -287,6 +303,9 @@ ol.Projection.equivalent = function(projection1, projection2) {
|
||||
|
||||
|
||||
/**
|
||||
* Searches a function that can be used to convert coordinates from the source
|
||||
* projection to the destination projection.
|
||||
*
|
||||
* @param {ol.Projection} source Source.
|
||||
* @param {ol.Projection} destination Destination.
|
||||
* @return {ol.TransformFunction} Transform.
|
||||
@@ -339,6 +358,10 @@ ol.Projection.getTransform = function(source, destination) {
|
||||
|
||||
|
||||
/**
|
||||
* Given the projection codes this method searches for a transformation function
|
||||
* to convert coordinate from the source projection to the destination
|
||||
* projection.
|
||||
*
|
||||
* @param {string} sourceCode Source code.
|
||||
* @param {string} destinationCode Destination code.
|
||||
* @return {ol.TransformFunction} Transform.
|
||||
@@ -351,7 +374,7 @@ ol.Projection.getTransformFromCodes = function(sourceCode, destinationCode) {
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Has Proj4js.
|
||||
* @return {boolean} True if Proj4js is available and enabled.
|
||||
*/
|
||||
ol.Projection.isProj4jsSupported = function() {
|
||||
return ol.ENABLE_PROJ4JS && 'Proj4js' in goog.global;
|
||||
@@ -360,7 +383,7 @@ ol.Projection.isProj4jsSupported = function() {
|
||||
|
||||
/**
|
||||
* @param {ol.Coordinate} point Point.
|
||||
* @return {ol.Coordinate} Point.
|
||||
* @return {ol.Coordinate} Unaltered point (same reference).
|
||||
*/
|
||||
ol.Projection.identityTransform = function(point) {
|
||||
return point;
|
||||
@@ -369,7 +392,7 @@ ol.Projection.identityTransform = function(point) {
|
||||
|
||||
/**
|
||||
* @param {ol.Coordinate} point Point.
|
||||
* @return {ol.Coordinate} Point.
|
||||
* @return {ol.Coordinate} Equal point (different reference).
|
||||
*/
|
||||
ol.Projection.cloneTransform = function(point) {
|
||||
return new ol.Coordinate(point.x, point.y);
|
||||
@@ -377,6 +400,8 @@ ol.Projection.cloneTransform = function(point) {
|
||||
|
||||
|
||||
/**
|
||||
* Transforms the given point to the destination projection.
|
||||
*
|
||||
* @param {ol.Coordinate} point Point.
|
||||
* @param {ol.Projection} source Source.
|
||||
* @param {ol.Projection} destination Destination.
|
||||
@@ -410,6 +435,8 @@ ol.Projection.EPSG_3857_RADIUS = 6378137;
|
||||
|
||||
|
||||
/**
|
||||
* Transformation from EPSG:4326 to EPSG:3857.
|
||||
*
|
||||
* @param {ol.Coordinate} point Point.
|
||||
* @return {ol.Coordinate} Point.
|
||||
*/
|
||||
@@ -422,6 +449,8 @@ ol.Projection.forwardSphericalMercator = function(point) {
|
||||
|
||||
|
||||
/**
|
||||
* Transformation from EPSG:3857 to EPSG:4326.
|
||||
*
|
||||
* @param {ol.Coordinate} point Point.
|
||||
* @return {ol.Coordinate} Point.
|
||||
*/
|
||||
@@ -452,6 +481,8 @@ ol.Projection.EPSG_3857_EXTENT = new ol.Extent(
|
||||
|
||||
|
||||
/**
|
||||
* Lists several projection codes with the same meaning as EPSG:3857.
|
||||
*
|
||||
* @private
|
||||
* @type {Array.<string>}
|
||||
*/
|
||||
@@ -464,6 +495,8 @@ ol.Projection.EPSG_3857_LIKE_CODES_ = [
|
||||
|
||||
|
||||
/**
|
||||
* Projections equal to EPSG:3857.
|
||||
*
|
||||
* @const
|
||||
* @private
|
||||
* @type {Array.<ol.Projection>}
|
||||
@@ -479,6 +512,8 @@ ol.Projection.EPSG_3857_LIKE_PROJECTIONS_ = goog.array.map(
|
||||
|
||||
|
||||
/**
|
||||
* Extent of the EPSG:4326 projection which is the whole world.
|
||||
*
|
||||
* @const
|
||||
* @private
|
||||
* @type {ol.Extent}
|
||||
@@ -487,6 +522,7 @@ ol.Projection.EPSG_4326_EXTENT_ = new ol.Extent(-180, -90, 180, 90);
|
||||
|
||||
|
||||
/**
|
||||
* Several projection code with the same meaning as EPSG:4326.
|
||||
* @private
|
||||
* @type {Array.<string>}
|
||||
*/
|
||||
@@ -498,6 +534,8 @@ ol.Projection.EPSG_4326_LIKE_CODES_ = [
|
||||
|
||||
|
||||
/**
|
||||
* Projections equal to EPSG:4326.
|
||||
*
|
||||
* @const
|
||||
* @type {Array.<ol.Projection>}
|
||||
*/
|
||||
@@ -511,10 +549,14 @@ ol.Projection.EPSG_4326_LIKE_PROJECTIONS = goog.array.map(
|
||||
});
|
||||
|
||||
|
||||
// Add transformations that don't alter coordinates to convert within set of
|
||||
// projections with equal meaning.
|
||||
ol.Projection.addEquivalentProjections_(
|
||||
ol.Projection.EPSG_3857_LIKE_PROJECTIONS_);
|
||||
ol.Projection.addEquivalentProjections_(
|
||||
ol.Projection.EPSG_4326_LIKE_PROJECTIONS);
|
||||
// Add transformations to convert EPSG:4326 like coordinates to EPSG:3857 like
|
||||
// coordinates and back.
|
||||
ol.Projection.addEquivalentTransforms_(
|
||||
ol.Projection.EPSG_4326_LIKE_PROJECTIONS,
|
||||
ol.Projection.EPSG_3857_LIKE_PROJECTIONS_,
|
||||
|
||||
@@ -24,7 +24,7 @@ ol.TileState = {
|
||||
* @constructor
|
||||
* @extends {goog.events.EventTarget}
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @param {string} src Source.
|
||||
* @param {string} src Image source URI.
|
||||
* @param {?string} crossOrigin Cross origin.
|
||||
*/
|
||||
ol.Tile = function(tileCoord, src, crossOrigin) {
|
||||
@@ -37,6 +37,8 @@ ol.Tile = function(tileCoord, src, crossOrigin) {
|
||||
this.tileCoord = tileCoord;
|
||||
|
||||
/**
|
||||
* Image URI
|
||||
*
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
@@ -113,6 +115,8 @@ ol.Tile.prototype.getState = function() {
|
||||
|
||||
|
||||
/**
|
||||
* Tracks loading or read errors.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
ol.Tile.prototype.handleImageError_ = function() {
|
||||
@@ -122,6 +126,8 @@ ol.Tile.prototype.handleImageError_ = function() {
|
||||
|
||||
|
||||
/**
|
||||
* Tracks successful image load.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
ol.Tile.prototype.handleImageLoad_ = function() {
|
||||
@@ -132,7 +138,7 @@ ol.Tile.prototype.handleImageLoad_ = function() {
|
||||
|
||||
|
||||
/**
|
||||
* Load.
|
||||
* Load not yet loaded URI.
|
||||
*/
|
||||
ol.Tile.prototype.load = function() {
|
||||
if (this.state_ == ol.TileState.IDLE) {
|
||||
@@ -150,6 +156,8 @@ ol.Tile.prototype.load = function() {
|
||||
|
||||
|
||||
/**
|
||||
* Discards event handlers which listen for load completion or errors.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
ol.Tile.prototype.unlistenImage_ = function() {
|
||||
|
||||
@@ -19,7 +19,7 @@ ol.QuadKeyCharCode = {
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.Coordinate}
|
||||
* @param {number} z Z.
|
||||
* @param {number} z Zoom level.
|
||||
* @param {number} x X.
|
||||
* @param {number} y Y.
|
||||
*/
|
||||
@@ -28,7 +28,7 @@ ol.TileCoord = function(z, x, y) {
|
||||
goog.base(this, x, y);
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @type {number} Zoom level
|
||||
*/
|
||||
this.z = z;
|
||||
|
||||
@@ -64,7 +64,8 @@ ol.TileCoord.createFromQuadKey = function(quadKey) {
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} str String.
|
||||
* @param {string} str String that follows pattern “z/x/y” where x, y and z are
|
||||
* numbers.
|
||||
* @return {ol.TileCoord} Tile coord.
|
||||
*/
|
||||
ol.TileCoord.createFromString = function(str) {
|
||||
|
||||
Reference in New Issue
Block a user