Remove lodash clone

(re: #6087)
This commit is contained in:
Bryan Housel
2019-03-22 23:18:25 -04:00
parent ff4f8f005f
commit 0e90167513
28 changed files with 82 additions and 135 deletions
+3 -2
View File
@@ -1,6 +1,5 @@
/* eslint-disable no-console */
const requireESM = require('esm')(module);
const _clone = requireESM('lodash-es/clone').default;
const _cloneDeep = requireESM('lodash-es/cloneDeep').default;
const _forEach = requireESM('lodash-es/forEach').default;
const _isEmpty = requireESM('lodash-es/isEmpty').default;
@@ -520,10 +519,12 @@ function validatePresetFields(presets, fields) {
if (preset.replacement) {
var replacementPreset = presets[preset.replacement];
var p1geometry = preset.geometry.slice().sort.toString();
var p2geometry = replacementPreset.geometry.slice().sort.toString();
if (replacementPreset === undefined) {
console.error('Unknown preset "' + preset.replacement + '" referenced as replacement of preset ' + preset.name);
process.exit(1);
} else if (_clone(preset.geometry).sort().toString() !== _clone(replacementPreset.geometry).sort().toString()) {
} else if (p1geometry !== p2geometry) {
console.error('The preset "' + presetID + '" has different geometry than its replacement preset, "' + preset.replacement + '". They must match for tag upgrades to work.');
process.exit(1);
}
+2 -3
View File
@@ -1,4 +1,3 @@
import _clone from 'lodash-es/clone';
import _groupBy from 'lodash-es/groupBy';
import _omit from 'lodash-es/omit';
@@ -177,7 +176,7 @@ export function actionAddMember(relationId, member, memberIndex, insertPair) {
}
}
var item = _clone(arr[i]);
var item = Object.assign({}, arr[i]); // shallow copy
arr[i].index = -1; // mark as dead
item.index = toIndex;
arr.splice(toIndex, 0, item);
@@ -189,7 +188,7 @@ export function actionAddMember(relationId, member, memberIndex, insertPair) {
function withIndex(arr) {
var result = new Array(arr.length);
for (var i = 0; i < arr.length; i++) {
result[i] = _clone(arr[i]);
result[i] = Object.assign({}, arr[i]); // shallow copy
result[i].index = i;
}
return result;
+1 -2
View File
@@ -1,4 +1,3 @@
import _clone from 'lodash-es/clone';
import _isEqual from 'lodash-es/isEqual';
import _isFunction from 'lodash-es/isFunction';
import _keys from 'lodash-es/keys';
@@ -176,7 +175,7 @@ export function actionMergeRemoteChanges(id, localGraph, remoteGraph, formatUser
var a = target.tags || {};
var b = remote.tags || {};
var keys = _reject(_union(_keys(o), _keys(a), _keys(b)), ignoreKey);
var tags = _clone(a);
var tags = Object.assign({}, a); // shallow copy
var changed = false;
for (var i = 0; i < keys.length; i++) {
+2 -3
View File
@@ -1,4 +1,3 @@
import _clone from 'lodash-es/clone';
import _cloneDeep from 'lodash-es/cloneDeep';
import { actionDeleteNode } from './delete_node';
@@ -33,7 +32,7 @@ export function actionOrthogonalize(wayID, projection, vertexID) {
graph = graph.replace(way);
var isClosed = way.isClosed();
var nodes = _clone(graph.childNodes(way));
var nodes = graph.childNodes(way).slice(); // shallow copy
if (isClosed) nodes.pop();
if (vertexID !== undefined) {
@@ -273,7 +272,7 @@ export function actionOrthogonalize(wayID, projection, vertexID) {
graph = graph.replace(way);
var isClosed = way.isClosed();
var nodes = _clone(graph.childNodes(way));
var nodes = graph.childNodes(way).slice(); // shallow copy
if (isClosed) nodes.pop();
if (vertexID !== undefined) {
+6 -4
View File
@@ -1,10 +1,10 @@
import _clone from 'lodash-es/clone';
export function actionUpgradeTags(entityId, oldTags, replaceTags) {
return function(graph) {
var entity = graph.entity(entityId);
var tags = _clone(entity.tags);
var tags = Object.assign({}, entity.tags); // shallow copy
var transferValue;
for (var oldTagKey in oldTags) {
if (oldTags[oldTagKey] === '*') {
transferValue = tags[oldTagKey];
@@ -20,6 +20,7 @@ export function actionUpgradeTags(entityId, oldTags, replaceTags) {
}
}
}
if (replaceTags) {
for (var replaceKey in replaceTags) {
var replaceValue = replaceTags[replaceKey];
@@ -39,6 +40,7 @@ export function actionUpgradeTags(entityId, oldTags, replaceTags) {
}
}
}
return graph.replace(entity.update({tags: tags}));
return graph.replace(entity.update({ tags: tags }));
};
}
+1 -5
View File
@@ -1,5 +1,3 @@
import _clone from 'lodash-es/clone';
import {
event as d3_event,
select as d3_select
@@ -125,13 +123,11 @@ export function behaviorDrawWay(context, wayID, index, mode, startGraph, baselin
for (var i = 0; i < parents.length; i++) {
var parent = parents[i];
var nodes = _clone(graph.childNodes(parent));
var nodes = graph.childNodes(parent).slice(); // shallow copy
if (origWay.isClosed()) { // Check if Area
if (finishDraw) {
if (nodes.length < 3) return false;
nodes.splice(-2, 1);
entity = nodes[nodes.length-2];
} else {
+2 -5
View File
@@ -1,5 +1,3 @@
import _clone from 'lodash-es/clone';
import { t } from '../util/locale';
import { actionAddEntity, actionChangeTags } from '../actions';
import { behaviorDraw } from '../behavior';
@@ -37,7 +35,7 @@ export function modeAddPoint(context, mode) {
function addWay(loc, edge) {
var node = osmNode({ tags: defaultTags });
var node = osmNode({ tags: defaultTags });
context.perform(
actionAddMidpoint({loc: loc, edge: edge}, node),
@@ -55,13 +53,12 @@ export function modeAddPoint(context, mode) {
function addNode(node) {
if (Object.keys(defaultTags).length === 0) {
enterSelectMode(node);
return;
}
var tags = _clone(node.tags);
var tags = Object.assign({}, node.tags); // shallow copy
for (var key in defaultTags) {
tags[key] = defaultTags[key];
}
+1 -2
View File
@@ -1,4 +1,3 @@
import _clone from 'lodash-es/clone';
import _filter from 'lodash-es/filter';
import _map from 'lodash-es/map';
import _reduce from 'lodash-es/reduce';
@@ -166,7 +165,7 @@ export function modeSave(context) {
}
}
return result;
}, _clone(ids)));
}, ids.slice())); // shallow copy
}
+7 -7
View File
@@ -1,4 +1,3 @@
import _clone from 'lodash-es/clone';
import _keys from 'lodash-es/keys';
import _every from 'lodash-es/every';
import _union from 'lodash-es/union';
@@ -99,7 +98,7 @@ osmEntity.prototype = {
if (copies[this.id])
return copies[this.id];
var copy = osmEntity(this, {id: undefined, user: undefined, version: undefined});
var copy = osmEntity(this, { id: undefined, user: undefined, version: undefined });
copies[this.id] = copy;
return copy;
@@ -117,15 +116,16 @@ osmEntity.prototype = {
update: function(attrs) {
return osmEntity(this, attrs, {v: 1 + (this.v || 0)});
return osmEntity(this, attrs, { v: 1 + (this.v || 0) });
},
mergeTags: function(tags) {
var merged = _clone(this.tags), changed = false;
var merged = Object.assign({}, this.tags); // shallow copy
var changed = false;
for (var k in tags) {
var t1 = merged[k],
t2 = tags[k];
var t1 = merged[k];
var t2 = tags[k];
if (!t1) {
changed = true;
merged[k] = t2;
@@ -134,7 +134,7 @@ osmEntity.prototype = {
merged[k] = _union(t1.split(/;\s*/), t2.split(/;\s*/)).join(';');
}
}
return changed ? this.update({tags: merged}) : this;
return changed ? this.update({ tags: merged }) : this;
},
+5 -17
View File
@@ -1,25 +1,13 @@
import _clone from 'lodash-es/clone';
import _difference from 'lodash-es/difference';
import _extend from 'lodash-es/extend';
import _uniq from 'lodash-es/uniq';
import {
actionDeleteRelation,
actionReverse,
actionSplit
} from '../actions';
import { actionDeleteRelation, actionReverse, actionSplit } from '../actions';
import { coreGraph } from '../core';
import {
geoAngle,
geoSphericalDistance
} from '../geo';
import { geoAngle, geoSphericalDistance } from '../geo';
import { osmEntity } from './entity';
export function osmTurn(turn) {
if (!(this instanceof osmTurn)) {
return new osmTurn(turn);
@@ -373,10 +361,10 @@ export function osmIntersection(graph, startVertexId, maxDistance) {
// traverse the intersection graph and find all the valid paths
function step(entity, currPath, currRestrictions, matchedRestriction) {
currPath = _clone(currPath || []);
currPath = (currPath || []).slice(); // shallow copy
if (currPath.length >= maxPathLength) return;
currPath.push(entity.id);
currRestrictions = _clone(currRestrictions || []);
currRestrictions = (currRestrictions || []).slice(); // shallow copy
var i, j;
if (entity.type === 'node') {
@@ -469,7 +457,7 @@ export function osmIntersection(graph, startVertexId, maxDistance) {
} else { // entity.type === 'way'
if (currPath.length >= 3) { // this is a "complete" path..
var turnPath = _clone(currPath);
var turnPath = currPath.slice(); // shallow copy
// an indirect restriction - only include the partial path (starting at FROM)
if (matchedRestriction && matchedRestriction.direct === false) {
+1 -2
View File
@@ -1,10 +1,9 @@
import _clone from 'lodash-es/clone';
import { t } from '../util/locale';
import { presetCollection } from './collection';
export function presetCategory(id, category, all) {
category = _clone(category);
category = Object.assign({}, category); // shallow copy
category.id = id;
+1 -2
View File
@@ -1,9 +1,8 @@
import _clone from 'lodash-es/clone';
import { t } from '../util/locale';
export function presetField(id, field) {
field = _clone(field);
field = Object.assign({}, field); // shallow copy
field.id = id;
+2 -3
View File
@@ -1,4 +1,3 @@
import _clone from 'lodash-es/clone';
import _omit from 'lodash-es/omit';
import _uniq from 'lodash-es/uniq';
@@ -7,7 +6,7 @@ import { areaKeys } from '../core/context';
export function presetPreset(id, preset, fields, visible, rawPresets) {
preset = _clone(preset);
preset = Object.assign({}, preset); // shallow copy
preset.id = id;
@@ -225,7 +224,7 @@ export function presetPreset(id, preset, fields, visible, rawPresets) {
var addTags = preset.addTags;
var k;
tags = _clone(tags);
tags = Object.assign({}, tags); // shallow copy
for (k in addTags) {
if (addTags[k] === '*') {
+4 -5
View File
@@ -1,4 +1,3 @@
import _clone from 'lodash-es/clone';
import _some from 'lodash-es/some';
import {
@@ -35,7 +34,7 @@ function vintageRange(vintage) {
export function rendererBackgroundSource(data) {
var source = _clone(data);
var source = Object.assign({}, data); // shallow copy
var offset = [0, 0];
var name = source.name;
var description = source.description;
@@ -53,9 +52,9 @@ export function rendererBackgroundSource(data) {
};
source.nudge = function(_, zoomlevel) {
offset[0] += _[0] / Math.pow(2, zoomlevel);
offset[1] += _[1] / Math.pow(2, zoomlevel);
source.nudge = function(val, zoomlevel) {
offset[0] += val[0] / Math.pow(2, zoomlevel);
offset[1] += val[1] / Math.pow(2, zoomlevel);
return source;
};
+1 -2
View File
@@ -1,4 +1,3 @@
import _clone from 'lodash-es/clone';
import _groupBy from 'lodash-es/groupBy';
import _reduce from 'lodash-es/reduce';
import _some from 'lodash-es/some';
@@ -377,7 +376,7 @@ export function rendererFeatures(context) {
//
var pkey = osmEntity.key(parents[0]);
if (_cache[pkey] && _cache[pkey].matches) {
matches = _clone(_cache[pkey].matches);
matches = Object.assign({}, _cache[pkey].matches); // shallow copy
continue;
}
}
+15 -18
View File
@@ -1,35 +1,32 @@
import _clone from 'lodash-es/clone';
import { dispatch as d3_dispatch } from 'd3-dispatch';
import { utilRebind } from '../util/rebind';
import { utilQsString, utilStringQs } from '../util';
export function rendererPhotos(context) {
var dispatch = d3_dispatch('change');
var _layerIDs = ['streetside', 'mapillary', 'mapillary-signs', 'openstreetcam'];
var _allPhotoTypes = ['flat', 'panoramic'];
var _shownPhotoTypes = _clone(_allPhotoTypes);
var _shownPhotoTypes = _allPhotoTypes.slice(); // shallow copy
function photos() {}
function updateStorage() {
if (!window.mocha) {
var q = utilStringQs(window.location.hash.substring(1));
var enabled = context.layers().all().filter(function(d) {
return _layerIDs.indexOf(d.id) !== -1 && d.layer && d.layer.supported() && d.layer.enabled();
}).map(function(d) {
return d.id;
});
if (enabled.length) {
q.photo_overlay = enabled.join(',');
} else {
delete q.photo_overlay;
}
window.location.replace('#' + utilQsString(q, true));
if (window.mocha) return;
var q = utilStringQs(window.location.hash.substring(1));
var enabled = context.layers().all().filter(function(d) {
return _layerIDs.indexOf(d.id) !== -1 && d.layer && d.layer.supported() && d.layer.enabled();
}).map(function(d) {
return d.id;
});
if (enabled.length) {
q.photo_overlay = enabled.join(',');
} else {
delete q.photo_overlay;
}
window.location.replace('#' + utilQsString(q, true));
}
photos.overlayLayerIDs = function() {
+2 -3
View File
@@ -1,4 +1,3 @@
import _clone from 'lodash-es/clone';
import _isEqual from 'lodash-es/isEqual';
import _forEach from 'lodash-es/forEach';
@@ -173,9 +172,9 @@ export default {
if (seen[hash]) continue;
seen[hash] = true;
// return a shallow clone, because the hash may change
// return a shallow copy, because the hash may change
// later if this feature gets merged with another
results.push(_clone(feature));
results.push(Object.assign({}, feature)); // shallow copy
}
}
+4 -5
View File
@@ -1,4 +1,3 @@
import _clone from 'lodash-es/clone';
import _forEach from 'lodash-es/forEach';
import _isEqual from 'lodash-es/isEqual';
import _unionBy from 'lodash-es/unionBy';
@@ -93,7 +92,7 @@ export function uiCommit(context) {
_changeset = new osmChangeset({ tags: tags });
}
tags = _clone(_changeset.tags);
tags = Object.assign({}, _changeset.tags); // shallow copy
// assign tags for imagery used
var imageryUsed = context.history().imageryUsed().join(';').substr(0, 255);
@@ -316,7 +315,7 @@ export function uiCommit(context) {
.call(rawTagEditor
.expanded(expanded)
.readOnlyTags(readOnlyTags)
.tags(_clone(_changeset.tags))
.tags(Object.assign({}, _changeset.tags)) // shallow copy
);
@@ -333,7 +332,7 @@ export function uiCommit(context) {
.call(rawTagEditor
.expanded(expanded)
.readOnlyTags(readOnlyTags)
.tags(_clone(_changeset.tags))
.tags(Object.assign({}, _changeset.tags)) // shallow copy
);
}
}
@@ -424,7 +423,7 @@ export function uiCommit(context) {
function updateChangeset(changed, onInput) {
var tags = _clone(_changeset.tags);
var tags = Object.assign({}, _changeset.tags); // shallow copy
_forEach(changed, function(v, k) {
k = k.trim().substr(0, 255);
+2 -3
View File
@@ -1,4 +1,3 @@
import _clone from 'lodash-es/clone';
import _isEmpty from 'lodash-es/isEmpty';
import _isEqual from 'lodash-es/isEqual';
@@ -47,7 +46,7 @@ export function uiEntityEditor(context) {
function entityEditor(selection) {
var entity = context.entity(_entityID);
var tags = _clone(entity.tags);
var tags = Object.assign({}, entity.tags); // shallow copy
// Header
var header = selection.selectAll('.header')
@@ -273,7 +272,7 @@ export function uiEntityEditor(context) {
function changeTags(changed, onInput) {
var entity = context.entity(_entityID);
var annotation = t('operations.change_tags.annotation');
var tags = _clone(entity.tags);
var tags = Object.assign({}, entity.tags); // shallow copy
for (var k in changed) {
if (!k) continue;
+1 -2
View File
@@ -1,4 +1,3 @@
import _clone from 'lodash-es/clone';
import _extend from 'lodash-es/extend';
import _some from 'lodash-es/some';
@@ -28,7 +27,7 @@ export function uiField(context, presetField, entity, options) {
}, options);
var dispatch = d3_dispatch('change');
var field = _clone(presetField);
var field = Object.assign({}, presetField); // shallow copy
var _show = options.show;
var _state = '';
var _tags = {};
+1 -2
View File
@@ -1,4 +1,3 @@
import _clone from 'lodash-es/clone';
import _pull from 'lodash-es/pull';
import _union from 'lodash-es/union';
@@ -19,7 +18,7 @@ export function uiFieldRadio(field, context) {
var wrap = d3_select(null);
var labels = d3_select(null);
var radios = d3_select(null);
var radioData = _clone(field.options || field.keys);
var radioData = (field.options || field.keys).slice(); // shallow copy
var typeField;
var layerField;
var _oldType = {};
+1 -3
View File
@@ -1,5 +1,3 @@
import _clone from 'lodash-es/clone';
import { dispatch as d3_dispatch } from 'd3-dispatch';
import {
@@ -209,7 +207,7 @@ export function uiFieldWikipedia(field, context) {
var qids = Object.keys(data);
var value = qids && qids.find(function(id) { return id.match(/^Q\d+$/); });
var currTags = _clone(context.entity(initEntityID).tags);
var currTags = Object.assign({}, context.entity(initEntityID).tags); // shallow copy
currTags.wikidata = value;
+4 -11
View File
@@ -1,24 +1,17 @@
import _clone from 'lodash-es/clone';
import _debounce from 'lodash-es/debounce';
import _uniqWith from 'lodash-es/uniqWith';
import { drag as d3_drag } from 'd3-drag';
import { event as d3_event, select as d3_select } from 'd3-selection';
import {
modeAddArea,
modeAddLine,
modeAddPoint,
modeBrowse
} from '../modes';
import { modeAddArea, modeAddLine, modeAddPoint, modeBrowse } from '../modes';
import { t, textDirection } from '../util/locale';
import { tooltip } from '../util/tooltip';
import { uiPresetIcon } from './preset_icon';
import { uiTooltipHtml } from './tooltipHtml';
export function uiModes(context) {
export function uiModes(context) {
function enabled() {
return osmEditable();
@@ -30,7 +23,6 @@ export function uiModes(context) {
}
function toggleMode(d) {
if (!enabled(d)) return;
if (d.button === context.mode().button) {
@@ -126,10 +118,11 @@ export function uiModes(context) {
tooltipTitleID = 'modes.add_preset.' + context.presets().fallback(d.geometry).id + '.title';
}
}
var protoMode = _clone(d);
var protoMode = Object.assign({}, d); // shallow copy
protoMode.button = markerClass;
protoMode.title = presetName;
protoMode.description = t(tooltipTitleID, { feature: '<strong>' + presetName + '</strong>' });
var keyCode;
if (textDirection === 'ltr') {
// use number row order: 1 2 3 4 5 6 7 8 9 0
+6 -10
View File
@@ -1,4 +1,3 @@
import _clone from 'lodash-es/clone';
import _debounce from 'lodash-es/debounce';
import { dispatch as d3_dispatch } from 'd3-dispatch';
@@ -8,12 +7,7 @@ import {
selectAll as d3_selectAll
} from 'd3-selection';
import {
modeAddArea,
modeAddLine,
modeAddPoint
} from '../modes';
import { modeAddArea, modeAddLine, modeAddPoint } from '../modes';
import { t, textDirection } from '../util/locale';
import { svgIcon } from '../svg/index';
import { tooltip } from '../util/tooltip';
@@ -38,10 +32,12 @@ export function uiSearchAdd(context) {
var allowedGeometry = ['area', 'line', 'point', 'vertex'];
var shownGeometry = [];
function updateShownGeometry(geom) {
shownGeometry = geom.sort();
presets = context.presets().matchAnyGeometry(shownGeometry);
}
function toggleShownGeometry(d) {
var geom = shownGeometry;
var index = geom.indexOf(d);
@@ -62,9 +58,9 @@ export function uiSearchAdd(context) {
});
}
function searchAdd(selection) {
updateShownGeometry(_clone(allowedGeometry));
function searchAdd(selection) {
updateShownGeometry(allowedGeometry.slice()); // shallow copy
var key = t('modes.add_feature.key');
@@ -155,7 +151,7 @@ export function uiSearchAdd(context) {
.on('click', function(d) {
toggleShownGeometry(d);
if (shownGeometry.length === 0) {
updateShownGeometry(_clone(allowedGeometry));
updateShownGeometry(allowedGeometry.slice()); // shallow copy
toggleShownGeometry(d);
}
updateFilterButtonsStates();
+1 -2
View File
@@ -1,4 +1,3 @@
import _clone from 'lodash-es/clone';
import { filters } from 'name-suggestion-index';
import { t } from '../util/locale';
@@ -67,7 +66,7 @@ export function validationGenericName() {
title: t('issues.fix.remove_generic_name.title'),
onClick: function() {
var entity = this.issue.entities[0];
var tags = _clone(entity.tags);
var tags = Object.assign({}, entity.tags); // shallow copy
delete tags.name;
context.perform(
actionChangeTags(entity.id, tags),
+2 -4
View File
@@ -1,10 +1,9 @@
import _clone from 'lodash-es/clone';
import { t } from '../util/locale';
import { actionUpgradeTags, actionChangeTags, actionChangePreset } from '../actions';
import { utilDisplayLabel } from '../util';
import { validationIssue, validationIssueFix } from '../core/validator';
export function validationOutdatedTags() {
var type = 'outdated_tags';
@@ -24,7 +23,6 @@ export function validationOutdatedTags() {
var validation = function(entity, context) {
var replacementPresetID = context.presets().match(entity, context.graph()).replacement;
var deprecatedTagsArray = entity.deprecatedTags();
var missingTags = missingRecommendedTags(entity, context, context.graph());
@@ -63,7 +61,7 @@ export function validationOutdatedTags() {
graph = actionUpgradeTags(entityID, deprecatedTags.old, deprecatedTags.replace)(graph);
});
var missingTags = missingRecommendedTags(graph.entity(entityID), context, graph);
var tags = _clone(graph.entity(entityID).tags);
var tags = Object.assign({}, graph.entity(entityID).tags); // shallow copy
for (var key in missingTags) {
tags[key] = missingTags[key];
}
+1 -3
View File
@@ -1,5 +1,3 @@
import _clone from 'lodash-es/clone';
import { actionChangeTags } from '../actions';
import { t } from '../util/locale';
import { utilDisplayLabel } from '../util';
@@ -74,7 +72,7 @@ export function validationPrivateData() {
title: t('issues.fix.' + fixID + '.title'),
onClick: function() {
var entity = this.issue.entities[0];
var tags = _clone(entity.tags);
var tags = Object.assign({}, entity.tags); // shallow copy
var privateKeys = this.issue.info.privateKeys;
for (var index in privateKeys) {
delete tags[privateKeys[index]];
+3 -5
View File
@@ -1,5 +1,3 @@
import _clone from 'lodash-es/clone';
import { actionAddVertex, actionChangeTags, actionMergeNodes } from '../actions';
import { geoHasSelfIntersections, geoSphericalDistance } from '../geo';
import { t } from '../util/locale';
@@ -37,7 +35,7 @@ export function validationTagSuggestsArea() {
// if the distance is very small, attempt to merge the endpoints
if (firstToLastDistanceMeters < 0.75) {
testNodes = _clone(nodes);
testNodes = nodes.slice(); // shallow copy
testNodes.pop();
testNodes.push(testNodes[0]);
// make sure this will not create a self-intersection
@@ -54,7 +52,7 @@ export function validationTagSuggestsArea() {
if (!connectEndpointsOnClick) {
// if the points were not merged, attempt to close the way
testNodes = _clone(nodes);
testNodes = nodes.slice(); // shallow copy
testNodes.push(testNodes[0]);
// make sure this will not create a self-intersection
if (!geoHasSelfIntersections(testNodes, testNodes[0].id)) {
@@ -81,7 +79,7 @@ export function validationTagSuggestsArea() {
title: t('issues.fix.remove_tag.title'),
onClick: function() {
var entity = this.issue.entities[0];
var tags = _clone(entity.tags);
var tags = Object.assign({}, entity.tags); // shallow copy
for (var key in tagSuggestingArea) {
delete tags[key];
}