activemodel (= 7.2.2.1)
activesupport (= 7.2.2.1)
timeout (>= 0.4.0)
- activerecord-import (2.0.0)
+ activerecord-import (2.1.0)
activerecord (>= 4.2)
activestorage (7.2.2.1)
actionpack (= 7.2.2.1)
autoprefixer-rails (10.4.19.0)
execjs (~> 2)
aws-eventstream (1.3.0)
- aws-partitions (1.1043.0)
- aws-sdk-core (3.217.0)
+ aws-partitions (1.1044.0)
+ aws-sdk-core (3.217.1)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
aws-sdk-kms (1.97.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sigv4 (~> 1.5)
- aws-sdk-s3 (1.178.0)
+ aws-sdk-s3 (1.179.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
dry-logic (>= 1.4, < 2)
dry-types (>= 1.7, < 2)
zeitwerk (~> 2.6)
- dry-types (1.8.1)
+ dry-types (1.8.2)
bigdecimal (~> 3.0)
concurrent-ruby (~> 1.0)
dry-core (~> 1.0)
erubi (1.13.1)
execjs (2.10.0)
exifr (1.4.1)
- factory_bot (6.5.0)
- activesupport (>= 5.0.0)
+ factory_bot (6.5.1)
+ activesupport (>= 6.1.0)
factory_bot_rails (6.4.4)
factory_bot (~> 6.5)
railties (>= 5.0.0)
open4 (1.3.4)
openstreetmap-deadlock_retry (1.3.1)
ostruct (0.6.1)
- overcommit (0.65.0)
+ overcommit (0.66.0)
childprocess (>= 0.6.3, < 6)
iniparse (~> 1.4)
rexml (>= 3.3.9)
rouge (4.5.1)
rtlcss (0.2.1)
mini_racer (>= 0.6.3)
- rubocop (1.71.0)
+ rubocop (1.71.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.9.3, < 3.0)
- rubocop-ast (>= 1.36.2, < 2.0)
+ rubocop-ast (>= 1.38.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.38.0)
//= require oauth
//= require matomo
//= require richtext
-//= require qs/dist/qs
{
const application_data = $("head").data();
*/
window.updateLinks = function (loc, zoom, layers, object) {
$(".geolink").each(function (index, link) {
- var href = link.href.split(/[?#]/)[0],
- args = Qs.parse(link.search.substring(1)),
- editlink = $(link).hasClass("editlink");
+ let href = link.href.split(/[?#]/)[0];
+ const queryArgs = new URLSearchParams(link.search),
+ editlink = $(link).hasClass("editlink");
- delete args.node;
- delete args.way;
- delete args.relation;
- delete args.changeset;
- delete args.note;
+ queryArgs.delete("node");
+ queryArgs.delete("way");
+ queryArgs.delete("relation");
+ queryArgs.delete("changeset");
+ queryArgs.delete("note");
if (object && editlink) {
- args[object.type] = object.id;
+ queryArgs.set(object.type, object.id);
}
- var query = Qs.stringify(args);
+ const query = queryArgs.toString();
if (query) href += "?" + query;
- args = {
+ const hashArgs = {
lat: loc.lat,
lon: "lon" in loc ? loc.lon : loc.lng,
zoom: zoom
};
if (layers && !editlink) {
- args.layers = layers;
+ hashArgs.layers = layers;
}
- href += OSM.formatHash(args);
+ href += OSM.formatHash(hashArgs);
link.href = href;
});
-//= require qs/dist/qs
-
$(document).ready(function () {
// Attach referer to authentication buttons
$(".auth_button").each(function () {
- var params = Qs.parse(this.search.substring(1));
- params.referer = $("#referer").val();
- this.search = Qs.stringify(params);
+ const params = new URLSearchParams(this.search);
+ params.set("referer", $("#referer").val());
+ this.search = params.toString();
});
});
-//= require qs/dist/qs
-
$(document).ready(function () {
var id = $("#id-embed");
var hash = location.hash.substring(1);
var hashParams = hash ? OSM.params(hash) : {};
var mapParams = OSM.mapParams();
- var params = {};
+ var params = new URLSearchParams();
if (mapParams.object) {
- params.id = mapParams.object.type + "/" + mapParams.object.id;
+ params.set("id", mapParams.object.type + "/" + mapParams.object.id);
mapParams = OSM.parseHash(location.hash);
if (mapParams.center) {
- params.map = mapParams.zoom + "/" + mapParams.center.lat + "/" + mapParams.center.lng;
+ params.set("map", mapParams.zoom + "/" + mapParams.center.lat + "/" + mapParams.center.lng);
}
} else if (id.data("lat") && id.data("lon")) {
- params.map = "16/" + id.data("lat") + "/" + id.data("lon");
+ params.set("map", "16/" + id.data("lat") + "/" + id.data("lon"));
} else {
- params.map = (mapParams.zoom || 17) + "/" + mapParams.lat + "/" + mapParams.lon;
+ params.set("map", (mapParams.zoom || 17) + "/" + mapParams.lat + "/" + mapParams.lon);
}
- if (hashParams.background) params.background = hashParams.background;
- if (hashParams.comment) params.comment = hashParams.comment;
- if (hashParams.disable_features) params.disable_features = hashParams.disable_features;
- if (hashParams.hashtags) params.hashtags = hashParams.hashtags;
- if (hashParams.locale) params.locale = hashParams.locale;
- if (hashParams.maprules) params.maprules = hashParams.maprules;
- if (hashParams.offset) params.offset = hashParams.offset;
- if (hashParams.photo) params.photo = hashParams.photo;
- if (hashParams.photo_dates) params.photo_dates = hashParams.photo_dates;
- if (hashParams.photo_overlay) params.photo_overlay = hashParams.photo_overlay;
- if (hashParams.photo_username) params.photo_username = hashParams.photo_username;
- if (hashParams.presets) params.presets = hashParams.presets;
- if (hashParams.source) params.source = hashParams.source;
- if (hashParams.validationDisable) params.validationDisable = hashParams.validationDisable;
- if (hashParams.validationWarning) params.validationWarning = hashParams.validationWarning;
- if (hashParams.validationError) params.validationError = hashParams.validationError;
- if (hashParams.walkthrough) params.walkthrough = hashParams.walkthrough;
+ if (hashParams.background) params.set("background", hashParams.background);
+ if (hashParams.comment) params.set("comment", hashParams.comment);
+ if (hashParams.disable_features) params.set("disable_features", hashParams.disable_features);
+ if (hashParams.hashtags) params.set("hashtags", hashParams.hashtags);
+ if (hashParams.locale) params.set("locale", hashParams.locale);
+ if (hashParams.maprules) params.set("maprules", hashParams.maprules);
+ if (hashParams.offset) params.set("offset", hashParams.offset);
+ if (hashParams.photo) params.set("photo", hashParams.photo);
+ if (hashParams.photo_dates) params.set("photo_dates", hashParams.photo_dates);
+ if (hashParams.photo_overlay) params.set("photo_overlay", hashParams.photo_overlay);
+ if (hashParams.photo_username) params.set("photo_username", hashParams.photo_username);
+ if (hashParams.presets) params.set("presets", hashParams.presets);
+ if (hashParams.source) params.set("source", hashParams.source);
+ if (hashParams.validationDisable) params.set("validationDisable", hashParams.validationDisable);
+ if (hashParams.validationWarning) params.set("validationWarning", hashParams.validationWarning);
+ if (hashParams.validationError) params.set("validationError", hashParams.validationError);
+ if (hashParams.walkthrough) params.set("walkthrough", hashParams.walkthrough);
if (id.data("gpx")) {
- params.gpx = id.data("gpx");
+ params.set("gpx", id.data("gpx"));
} else if (hashParams.gpx) {
- params.gpx = hashParams.gpx;
+ params.set("gpx", hashParams.gpx);
}
- id.attr("src", id.data("url") + "#" + Qs.stringify(params));
+ id.attr("src", id.data("url") + "#" + params);
} else {
alert(I18n.t("site.edit.id_not_configured"));
}
map.attributionControl.setPrefix("");
map.removeControl(map.attributionControl);
+ const isDarkTheme = args.theme === "dark" || (args.theme !== "light" && window.matchMedia("(prefers-color-scheme: dark)").matches);
const layers = <%=
YAML.load_file(Rails.root.join("config/layers.yml"))
.select { |entry| entry["canEmbed"] }
.each_with_object({}) do |entry, obj|
obj[entry["layerId"]] = {
layer: entry["leafletOsmId"],
+ darkLayer: entry["leafletOsmDarkId"],
apiKeyId: entry["apiKeyId"]
}.compact
end.to_json
const layerId = (args.layer || "").replaceAll(" ", "");
const layerConfig = layers[layerId] || layers.mapnik;
const { layer, ...options } = {
- layer: layerConfig.layer,
+ layer: layerConfig.darkLayer && isDarkTheme ? layerConfig.darkLayer : layerConfig.layer,
apikey: apiKeys[layerConfig.apiKeyId],
...tileOptions[layerId]
};
//= require index/changeset
//= require index/query
//= require router
-//= require qs/dist/qs
$(document).ready(function () {
var map = new L.OSM.Map("map", {
function remoteEditHandler(bbox, object) {
var remoteEditHost = "http://127.0.0.1:8111",
osmHost = location.protocol + "//" + location.host,
- query = {
+ query = new URLSearchParams({
left: bbox.getWest() - 0.0001,
top: bbox.getNorth() + 0.0001,
right: bbox.getEast() + 0.0001,
bottom: bbox.getSouth() - 0.0001
- };
+ });
- if (object && object.type !== "note") query.select = object.type + object.id; // can't select notes
- sendRemoteEditCommand(remoteEditHost + "/load_and_zoom?" + Qs.stringify(query), function () {
+ if (object && object.type !== "note") query.set("select", object.type + object.id); // can't select notes
+ sendRemoteEditCommand(remoteEditHost + "/load_and_zoom?" + query, function () {
if (object && object.type === "note") {
- var noteQuery = { url: osmHost + OSM.apiUrl(object) };
- sendRemoteEditCommand(remoteEditHost + "/import?" + Qs.stringify(noteQuery));
+ const noteQuery = new URLSearchParams({ url: osmHost + OSM.apiUrl(object) });
+ sendRemoteEditCommand(remoteEditHost + "/import?" + noteQuery);
}
});
};
page.load = function () {
- var params = Qs.parse(location.search.substring(1));
- if (params.query) {
- $("#sidebar .search_form input[name=query]").value(params.query);
+ const params = new URLSearchParams(location.search);
+ if (params.has("query")) {
+ $("#sidebar .search_form input[name=query]").value(params.get("query"));
}
if (!("autofocus" in document.createElement("input"))) {
$("#sidebar .search_form input[name=query]").focus();
-//= require qs/dist/qs
-
OSM.initializeContextMenu = function (map) {
map.contextmenu.addItem({
text: I18n.t("javascripts.context.directions_from"),
callback: function directionsFromHere(e) {
- var precision = OSM.zoomPrecision(map.getZoom()),
- latlng = e.latlng.wrap(),
- lat = latlng.lat.toFixed(precision),
- lng = latlng.lng.toFixed(precision);
+ const latlng = OSM.cropLocation(e.latlng, map.getZoom());
- OSM.router.route("/directions?" + Qs.stringify({
- from: lat + "," + lng,
+ OSM.router.route("/directions?" + new URLSearchParams({
+ from: latlng.join(","),
to: getDirectionsEndpointCoordinatesFromInput($("#route_to"))
}));
}
map.contextmenu.addItem({
text: I18n.t("javascripts.context.directions_to"),
callback: function directionsToHere(e) {
- var precision = OSM.zoomPrecision(map.getZoom()),
- latlng = e.latlng.wrap(),
- lat = latlng.lat.toFixed(precision),
- lng = latlng.lng.toFixed(precision);
+ const latlng = OSM.cropLocation(e.latlng, map.getZoom());
- OSM.router.route("/directions?" + Qs.stringify({
+ OSM.router.route("/directions?" + new URLSearchParams({
from: getDirectionsEndpointCoordinatesFromInput($("#route_from")),
- to: lat + "," + lng
+ to: latlng.join(",")
}));
}
});
map.contextmenu.addItem({
text: I18n.t("javascripts.context.add_note"),
callback: function addNoteHere(e) {
- var precision = OSM.zoomPrecision(map.getZoom()),
- latlng = e.latlng.wrap(),
- lat = latlng.lat.toFixed(precision),
- lng = latlng.lng.toFixed(precision);
+ const [lat, lon] = OSM.cropLocation(e.latlng, map.getZoom());
- OSM.router.route("/note/new?lat=" + lat + "&lon=" + lng);
+ OSM.router.route("/note/new?" + new URLSearchParams({ lat, lon }));
}
});
map.contextmenu.addItem({
text: I18n.t("javascripts.context.show_address"),
callback: function describeLocation(e) {
- var precision = OSM.zoomPrecision(map.getZoom()),
- latlng = e.latlng.wrap(),
- lat = latlng.lat.toFixed(precision),
- lng = latlng.lng.toFixed(precision);
+ const [lat, lon] = OSM.cropLocation(e.latlng, map.getZoom());
- OSM.router.route("/search?lat=" + encodeURIComponent(lat) + "&lon=" + encodeURIComponent(lng));
+ OSM.router.route("/search?" + new URLSearchParams({ lat, lon }));
}
});
map.contextmenu.addItem({
text: I18n.t("javascripts.context.query_features"),
callback: function queryFeatures(e) {
- var precision = OSM.zoomPrecision(map.getZoom()),
- latlng = e.latlng.wrap(),
- lat = latlng.lat.toFixed(precision),
- lng = latlng.lng.toFixed(precision);
+ const [lat, lon] = OSM.cropLocation(e.latlng, map.getZoom());
- OSM.router.route("/query?lat=" + lat + "&lon=" + lng);
+ OSM.router.route("/query?" + new URLSearchParams({ lat, lon }));
}
});
};
function markerDragListener(e) {
- var latlng = convertLatLngToZoomPrecision(e.target.getLatLng());
+ const latlng = L.latLng(OSM.cropLocation(e.target.getLatLng(), map.getZoom()));
+
+ if (endpoint.geocodeRequest) endpoint.geocodeRequest.abort();
+ delete endpoint.geocodeRequest;
setLatLng(latlng);
setInputValueFromLatLng(latlng);
endpoint.value = input.val();
+ if (e.type === "dragend") getReverseGeocode();
dragCallback(e.type === "drag");
}
endpoint.setValue(value);
}
- endpoint.setValue = function (value, latlng) {
+ endpoint.setValue = function (value) {
+ if (endpoint.geocodeRequest) endpoint.geocodeRequest.abort();
+ delete endpoint.geocodeRequest;
+ input.removeClass("is-invalid");
+
+ var coordinatesMatch = value.match(/^\s*([+-]?\d+(?:\.\d*)?)(?:\s+|\s*[/,]\s*)([+-]?\d+(?:\.\d*)?)\s*$/);
+ var latlng = coordinatesMatch && L.latLng(coordinatesMatch[1], coordinatesMatch[2]);
+
+ if (latlng && endpoint.cachedReverseGeocode && endpoint.cachedReverseGeocode.latlng.equals(latlng)) {
+ setLatLng(latlng);
+ if (endpoint.cachedReverseGeocode.notFound) {
+ endpoint.value = value;
+ input.addClass("is-invalid");
+ } else {
+ endpoint.value = endpoint.cachedReverseGeocode.value;
+ }
+ input.val(endpoint.value);
+ changeCallback();
+ return;
+ }
+
endpoint.value = value;
removeLatLng();
- input.removeClass("is-invalid");
input.val(value);
if (latlng) {
setLatLng(latlng);
setInputValueFromLatLng(latlng);
+ getReverseGeocode();
changeCallback();
} else if (endpoint.value) {
getGeocode();
}
};
+ endpoint.swapCachedReverseGeocodes = function (otherEndpoint) {
+ var g0 = endpoint.cachedReverseGeocode;
+ var g1 = otherEndpoint.cachedReverseGeocode;
+ delete endpoint.cachedReverseGeocode;
+ delete otherEndpoint.cachedReverseGeocode;
+ if (g0) otherEndpoint.cachedReverseGeocode = g0;
+ if (g1) endpoint.cachedReverseGeocode = g1;
+ };
+
function getGeocode() {
var viewbox = map.getBounds().toBBoxString(); // <sw lon>,<sw lat>,<ne lon>,<ne lat>
var geocodeUrl = OSM.NOMINATIM_URL + "search?q=" + encodeURIComponent(endpoint.value) + "&format=json&viewbox=" + viewbox;
- if (endpoint.geocodeRequest) endpoint.geocodeRequest.abort();
endpoint.geocodeRequest = $.getJSON(geocodeUrl, function (json) {
delete endpoint.geocodeRequest;
if (json.length === 0) {
setLatLng(L.latLng(json[0]));
+ endpoint.value = json[0].display_name;
input.val(json[0].display_name);
changeCallback();
});
}
+ function getReverseGeocode() {
+ var latlng = endpoint.latlng.clone();
+ var reverseGeocodeUrl = OSM.NOMINATIM_URL + "reverse?lat=" + latlng.lat + "&lon=" + latlng.lng + "&format=json";
+
+ endpoint.geocodeRequest = $.getJSON(reverseGeocodeUrl, function (json) {
+ delete endpoint.geocodeRequest;
+ if (!json || !json.display_name) {
+ endpoint.cachedReverseGeocode = { latlng: latlng, notFound: true };
+ return;
+ }
+
+ endpoint.value = json.display_name;
+ input.val(json.display_name);
+ endpoint.cachedReverseGeocode = { latlng: latlng, value: endpoint.value };
+ });
+ }
+
function setLatLng(ll) {
input
.attr("data-lat", ll.lat)
input.val(latlng.lat + ", " + latlng.lng);
}
- function convertLatLngToZoomPrecision(latlng) {
- var precision = OSM.zoomPrecision(map.getZoom());
-
- return L.latLng(latlng.lat.toFixed(precision), latlng.lng.toFixed(precision));
- }
-
return endpoint;
};
//= require ./directions-endpoint
//= require_self
//= require_tree ./directions
-//= require qs/dist/qs
OSM.Directions = function (map) {
var routeRequest = null; // jqXHR object of an ongoing route request or null
if (coordTo) {
routeTo = coordTo.lat + "," + coordTo.lng;
}
+ endpoints[0].swapCachedReverseGeocodes(endpoints[1]);
- OSM.router.route("/directions?" + Qs.stringify({
- from: $("#route_to").val(),
- to: $("#route_from").val(),
+ OSM.router.route("/directions?" + new URLSearchParams({
route: routeTo + ";" + routeFrom
}));
});
// Cancel any route that is already in progress
if (routeRequest) routeRequest.abort();
- var o = endpoints[0].latlng,
- d = endpoints[1].latlng;
+ const points = endpoints.map(p => p.latlng);
- if (!o || !d) return;
+ if (!points[0] || !points[1]) return;
$("header").addClass("closed");
- var precision = OSM.zoomPrecision(map.getZoom());
-
- OSM.router.replace("/directions?" + Qs.stringify({
+ OSM.router.replace("/directions?" + new URLSearchParams({
engine: chosenEngine.id,
- route: o.lat.toFixed(precision) + "," + o.lng.toFixed(precision) + ";" +
- d.lat.toFixed(precision) + "," + d.lng.toFixed(precision)
+ route: points.map(p => OSM.cropLocation(p, map.getZoom()).join()).join(";")
}));
// copy loading item to sidebar and display it. we copy it, rather than
$("#sidebar_content").html($(".directions_form .loader_copy").html());
map.setSidebarOverlaid(false);
- routeRequest = chosenEngine.getRoute([o, d], function (err, route) {
+ routeRequest = chosenEngine.getRoute(points, function (err, route) {
routeRequest = null;
if (err) {
var pt = L.DomEvent.getMousePosition(oe, map.getContainer()); // co-ordinates of the mouse pointer at present
pt.y += 20;
var ll = map.containerPointToLatLng(pt);
- var precision = OSM.zoomPrecision(map.getZoom());
- var value = ll.lat.toFixed(precision) + ", " + ll.lng.toFixed(precision);
- var llWithPrecision = L.latLng(ll.lat.toFixed(precision), ll.lng.toFixed(precision));
- endpoints[type === "from" ? 0 : 1].setValue(value, llWithPrecision);
+ const llWithPrecision = OSM.cropLocation(ll, map.getZoom());
+ endpoints[type === "from" ? 0 : 1].setValue(llWithPrecision.join(", "));
});
endpoints[0].enable();
endpoints[1].enable();
- var params = Qs.parse(location.search.substring(1)),
- route = (params.route || "").split(";"),
- from = route[0] && L.latLng(route[0].split(",")),
- to = route[1] && L.latLng(route[1].split(","));
+ const params = new URLSearchParams(location.search),
+ route = (params.get("route") || "").split(";");
- if (params.engine) {
- var engineIndex = findEngine(params.engine);
+ if (params.has("engine")) {
+ var engineIndex = findEngine(params.get("engine"));
if (engineIndex >= 0) {
setEngine(engineIndex);
}
}
- endpoints[0].setValue(params.from || "", from);
- endpoints[1].setValue(params.to || "", to);
+ endpoints[0].setValue(params.get("from") || route[0] || "");
+ endpoints[1].setValue(params.get("to") || route[1] || "");
- map.setSidebarOverlaid(!from || !to);
+ map.setSidebarOverlaid(!endpoints[0].latlng || !endpoints[1].latlng);
};
page.load = function () {
}
function setBounds(bounds) {
- var precision = OSM.zoomPrecision(map.getZoom());
- $("#minlon").val(bounds.getWest().toFixed(precision));
- $("#minlat").val(bounds.getSouth().toFixed(precision));
- $("#maxlon").val(bounds.getEast().toFixed(precision));
- $("#maxlat").val(bounds.getNorth().toFixed(precision));
+ const truncated = [bounds.getSouthWest(), bounds.getNorthEast()]
+ .map(c => OSM.cropLocation(c, map.getZoom()));
+ $("#minlon").val(truncated[0][1]);
+ $("#minlat").val(truncated[0][0]);
+ $("#maxlon").val(truncated[1][1]);
+ $("#maxlat").val(truncated[1][0]);
$("#export_overpass").attr("href",
"https://overpass-api.de/api/map?bbox=" +
- $("#minlon").val() + "," + $("#minlat").val() + "," +
- $("#maxlon").val() + "," + $("#maxlat").val());
+ truncated.map(p => p.reverse()).join());
}
function validateControls() {
-//= require qs/dist/qs
-
OSM.NewNote = function (map) {
var noteLayer = map.noteLayer,
content = $("#sidebar_content"),
map.addLayer(noteLayer);
- var params = Qs.parse(path.substring(path.indexOf("?") + 1));
+ const params = new URLSearchParams(path.substring(path.indexOf("?")));
var markerLatlng;
- if (params.lat && params.lon) {
- markerLatlng = L.latLng(params.lat, params.lon);
+ if (params.has("lat") && params.has("lon")) {
+ markerLatlng = L.latLng(params.get("lat"), params.get("lon"));
} else {
markerLatlng = map.getCenter();
}
-//= require qs/dist/qs
-
OSM.Query = function (map) {
var url = OSM.OVERPASS_URL,
credentials = OSM.OVERPASS_CREDENTIALS,
function queryOverpass(lat, lng) {
var latlng = L.latLng(lat, lng).wrap(),
bounds = map.getBounds().wrap(),
- precision = OSM.zoomPrecision(map.getZoom()),
- bbox = bounds.getSouth().toFixed(precision) + "," +
- bounds.getWest().toFixed(precision) + "," +
- bounds.getNorth().toFixed(precision) + "," +
- bounds.getEast().toFixed(precision),
- radius = 10 * Math.pow(1.5, 19 - map.getZoom()),
- around = "around:" + radius + "," + lat + "," + lng,
- nodes = "node(" + around + ")",
- ways = "way(" + around + ")",
- relations = "relation(" + around + ")",
- nearby = "(" + nodes + ";" + ways + ";);out tags geom(" + bbox + ");" + relations + ";out geom(" + bbox + ");",
- isin = "is_in(" + lat + "," + lng + ")->.a;way(pivot.a);out tags bb;out ids geom(" + bbox + ");relation(pivot.a);out tags bb;";
+ zoom = map.getZoom(),
+ bbox = [bounds.getSouthWest(), bounds.getNorthEast()]
+ .map(c => OSM.cropLocation(c, zoom))
+ .join(),
+ geombbox = "geom(" + bbox + ");",
+ radius = 10 * Math.pow(1.5, 19 - zoom),
+ around = "(around:" + radius + "," + lat + "," + lng + ")",
+ nodes = "node" + around,
+ ways = "way" + around,
+ relations = "relation" + around,
+ nearby = "(" + nodes + ";" + ways + ";);out tags " + geombbox + relations + ";out " + geombbox,
+ isin = "is_in(" + lat + "," + lng + ")->.a;way(pivot.a);out tags bb;out ids " + geombbox + "relation(pivot.a);out tags bb;";
$("#sidebar_content .query-intro")
.hide();
}
function clickHandler(e) {
- var precision = OSM.zoomPrecision(map.getZoom()),
- latlng = e.latlng.wrap(),
- lat = latlng.lat.toFixed(precision),
- lng = latlng.lng.toFixed(precision);
+ const [lat, lon] = OSM.cropLocation(e.latlng, map.getZoom());
- OSM.router.route("/query?lat=" + lat + "&lon=" + lng);
+ OSM.router.route("/query?" + new URLSearchParams({ lat, lon }));
}
function enableQueryMode() {
};
page.load = function (path, noCentre) {
- var params = Qs.parse(path.substring(path.indexOf("?") + 1)),
- latlng = L.latLng(params.lat, params.lon);
+ const params = new URLSearchParams(path.substring(path.indexOf("?"))),
+ latlng = L.latLng(params.get("lat"), params.get("lon"));
if (!window.location.hash && !noCentre && !map.getBounds().contains(latlng)) {
OSM.router.withoutMoveListener(function () {
});
}
- queryOverpass(params.lat, params.lon);
+ queryOverpass(params.get("lat"), params.get("lon"));
};
page.unload = function (sameController) {
-//= require qs/dist/qs
-
OSM.Search = function (map) {
$(".search_form input[name=query]").on("input", function (e) {
if ($(e.target).val() === "") {
$(".describe_location").on("click", function (e) {
e.preventDefault();
$("header").addClass("closed");
- var center = map.getCenter().wrap(),
- precision = OSM.zoomPrecision(map.getZoom()),
- lat = center.lat.toFixed(precision),
- lng = center.lng.toFixed(precision);
+ const [lat, lon] = OSM.cropLocation(map.getCenter(), map.getZoom());
- OSM.router.route("/search?lat=" + encodeURIComponent(lat) + "&lon=" + encodeURIComponent(lng));
+ OSM.router.route("/search?" + new URLSearchParams({ lat, lon }));
});
$("#sidebar_content")
var page = {};
page.pushstate = page.popstate = function (path) {
- var params = Qs.parse(path.substring(path.indexOf("?") + 1));
- if (params.query) {
- $(".search_form input[name=query]").val(params.query);
+ const params = new URLSearchParams(path.substring(path.indexOf("?")));
+ if (params.has("query")) {
+ $(".search_form input[name=query]").val(params.get("query"));
$(".describe_location").hide();
- } else if (params.lat && params.lon) {
- $(".search_form input[name=query]").val(params.lat + ", " + params.lon);
+ } else if (params.has("lat") && params.has("lon")) {
+ $(".search_form input[name=query]").val(params.get("lat") + ", " + params.get("lon"));
$(".describe_location").hide();
}
OSM.loadSidebarContent(path, page.load);
-//= require qs/dist/qs
-
L.extend(L.LatLngBounds.prototype, {
getSize: function () {
return (this._northEast.lat - this._southWest.lat) *
},
getUrl: function (marker) {
- var precision = OSM.zoomPrecision(this.getZoom()),
- params = {};
+ const params = {};
if (marker && this.hasLayer(marker)) {
- var latLng = marker.getLatLng().wrap();
- params.mlat = latLng.lat.toFixed(precision);
- params.mlon = latLng.lng.toFixed(precision);
+ [params.mlat, params.mlon] = OSM.cropLocation(marker.getLatLng(), this.getZoom());
}
var url = window.location.protocol + "//" + OSM.SERVER_URL + "/",
- query = Qs.stringify(params),
+ query = new URLSearchParams(params),
hash = OSM.formatHash(this);
if (query) url += "?" + query;
return (interlaced_x << 1) | interlaced_y;
}
- var params = {};
+ const params = new URLSearchParams();
var layers = this.getLayersCode().replace("M", "");
if (layers) {
- params.layers = layers;
+ params.set("layers", layers);
}
if (marker && this.hasLayer(marker)) {
- params.m = "";
+ params.set("m", "");
}
if (this._object) {
- params[this._object.type] = this._object.id;
+ params.set(this._object.type, this._object.id);
}
- var query = Qs.stringify(params);
+ const query = params.toString();
if (query) {
str += "?" + query;
}
},
getGeoUri: function (marker) {
- var precision = OSM.zoomPrecision(this.getZoom()),
- latLng,
- params = {};
+ let latLng = this.getCenter();
+ const zoom = this.getZoom();
if (marker && this.hasLayer(marker)) {
- latLng = marker.getLatLng().wrap();
- } else {
- latLng = this.getCenter();
+ latLng = marker.getLatLng();
}
- params.lat = latLng.lat.toFixed(precision);
- params.lon = latLng.lng.toFixed(precision);
- params.zoom = this.getZoom();
-
- return "geo:" + params.lat + "," + params.lon + "?z=" + params.zoom;
+ return `geo:${OSM.cropLocation(latLng, zoom).join(",")}?z=${zoom}`;
},
addObject: function (object, callback) {
//= depend_on settings.local.yml
//= depend_on layers.yml
//= depend_on key.yml
-//= require qs/dist/qs
OSM = {
-<% if defined?(Settings.matomo) %>
- MATOMO: <%= Settings.matomo.to_json %>,
-<% end %>
-
- MAX_REQUEST_AREA: <%= Settings.max_request_area.to_json %>,
- SERVER_PROTOCOL: <%= Settings.server_protocol.to_json %>,
- SERVER_URL: <%= Settings.server_url.to_json %>,
- API_VERSION: <%= Settings.api_version.to_json %>,
- STATUS: <%= Settings.status.to_json %>,
- MAX_NOTE_REQUEST_AREA: <%= Settings.max_note_request_area.to_json %>,
- OVERPASS_URL: <%= Settings.overpass_url.to_json %>,
- OVERPASS_CREDENTIALS: <%= Settings.overpass_credentials.to_json %>,
- NOMINATIM_URL: <%= Settings.nominatim_url.to_json %>,
- GRAPHHOPPER_URL: <%= Settings.graphhopper_url.to_json %>,
- FOSSGIS_OSRM_URL: <%= Settings.fossgis_osrm_url.to_json %>,
- FOSSGIS_VALHALLA_URL: <%= Settings.fossgis_valhalla_url.to_json %>,
- DEFAULT_LOCALE: <%= I18n.default_locale.to_json %>,
-
-<% if Settings.key?(:thunderforest_key) %>
- THUNDERFOREST_KEY: <%= Settings.thunderforest_key.to_json %>,
-<% end %>
-
-<% if Settings.key?(:tracestrack_key) %>
- TRACESTRACK_KEY: <%= Settings.tracestrack_key.to_json %>,
-<% end %>
-
- LAYER_DEFINITIONS: <%= YAML.load_file(Rails.root.join("config/layers.yml")).to_json %>,
- LAYERS_WITH_MAP_KEY: <%= YAML.load_file(Rails.root.join("config/key.yml")).keys.to_json %>,
-
- MARKER_GREEN: <%= image_path("marker-green.png").to_json %>,
- MARKER_RED: <%= image_path("marker-red.png").to_json %>,
-
- MARKER_ICON: <%= image_path("leaflet/dist/images/marker-icon.png").to_json %>,
- MARKER_ICON_2X: <%= image_path("leaflet/dist/images/marker-icon-2x.png").to_json %>,
- MARKER_SHADOW: <%= image_path("leaflet/dist/images/marker-shadow.png").to_json %>,
-
- NEW_NOTE_MARKER: <%= image_path("new_note_marker.svg").to_json %>,
- OPEN_NOTE_MARKER: <%= image_path("open_note_marker.svg").to_json %>,
- CLOSED_NOTE_MARKER: <%= image_path("closed_note_marker.svg").to_json %>,
+ ...<%=
+ %i[
+ matomo
+ max_request_area
+ server_protocol
+ server_url
+ api_version
+ status
+ max_note_request_area
+ overpass_url
+ overpass_credentials
+ nominatim_url
+ graphhopper_url
+ fossgis_osrm_url
+ fossgis_valhalla_url
+ thunderforest_key
+ tracestrack_key
+ ]
+ .each_with_object({}) do |key, hash|
+ hash[key.to_s.upcase] = Settings.send(key) if Settings.respond_to?(key)
+ end.to_json
+ %>,
+
+ DEFAULT_LOCALE: <%= I18n.default_locale.to_json %>,
+
+ LAYER_DEFINITIONS: <%= YAML.load_file(Rails.root.join("config/layers.yml")).to_json %>,
+ LAYERS_WITH_MAP_KEY: <%= YAML.load_file(Rails.root.join("config/key.yml")).keys.to_json %>,
+
+ MARKER_GREEN: <%= image_path("marker-green.png").to_json %>,
+ MARKER_RED: <%= image_path("marker-red.png").to_json %>,
+
+ MARKER_ICON: <%= image_path("leaflet/dist/images/marker-icon.png").to_json %>,
+ MARKER_ICON_2X: <%= image_path("leaflet/dist/images/marker-icon-2x.png").to_json %>,
+ MARKER_SHADOW: <%= image_path("leaflet/dist/images/marker-shadow.png").to_json %>,
+
+ NEW_NOTE_MARKER: <%= image_path("new_note_marker.svg").to_json %>,
+ OPEN_NOTE_MARKER: <%= image_path("open_note_marker.svg").to_json %>,
+ CLOSED_NOTE_MARKER: <%= image_path("closed_note_marker.svg").to_json %>,
apiUrl: function (object) {
var apiType = object.type === "note" ? "notes" : object.type;
},
params: function (search) {
- var params = {};
-
- search = (search || window.location.search).replace("?", "").split(/&|;/);
-
- for (var i = 0; i < search.length; ++i) {
- var pair = search[i],
- j = pair.indexOf("="),
- key = pair.slice(0, j),
- val = pair.slice(++j);
-
- try {
- params[key] = decodeURIComponent(val);
- } catch (e) {
- // Ignore parse exceptions
- }
- }
-
- return params;
+ var query = search || window.location.search;
+ return Object.fromEntries(new URLSearchParams(query));
},
mapParams: function (search) {
- var params = OSM.params(search), mapParams = {}, match;
+ var params = OSM.params(search), mapParams = {};
if (params.mlon && params.mlat) {
mapParams.marker = true;
return args;
}
- hash = Qs.parse(hash.slice(i + 1));
+ const hashParams = new URLSearchParams(hash.slice(i + 1));
- var map = (hash.map || "").split("/"),
+ var map = (hashParams.get("map") || "").split("/"),
zoom = parseInt(map[0], 10),
lat = parseFloat(map[1]),
lon = parseFloat(map[2]);
args.zoom = zoom;
}
- if (hash.layers) {
- args.layers = hash.layers;
+ if (hashParams.has("layers")) {
+ args.layers = hashParams.get("layers");
}
return args;
layers = args.layers || "";
}
- center = center.wrap();
layers = layers.replace("M", "");
- var precision = OSM.zoomPrecision(zoom),
- hash = "#map=" + zoom +
- "/" + center.lat.toFixed(precision) +
- "/" + center.lng.toFixed(precision);
+ let hash = "#map=" + [zoom, ...OSM.cropLocation(center, zoom)].join("/");
if (layers) {
hash += "&layers=" + layers;
return Math.ceil(Math.log10(pixels / degrees));
},
+ cropLocation: function (latLng, zoom) {
+ const precision = OSM.zoomPrecision(zoom),
+ wrapped = latLng.wrap();
+ return [wrapped.lat, wrapped.lng].map(c => c.toFixed(precision));
+ },
+
locationCookie: function (map) {
- var center = map.getCenter().wrap(),
- zoom = map.getZoom(),
- precision = OSM.zoomPrecision(zoom);
- return [center.lng.toFixed(precision), center.lat.toFixed(precision), zoom, map.getLayersCode()].join("|");
+ const zoom = map.getZoom(),
+ center = OSM.cropLocation(map.getCenter(), zoom).reverse();
+ return [...center, zoom, map.getLayersCode()].join("|");
},
distance: function (latlng1, latlng2) {
return 6372795 * 2 * Math.asin(
Math.sqrt(
Math.pow(Math.sin(latdiff / 2), 2) +
- Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(lngdiff / 2), 2)
+ (Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(lngdiff / 2), 2))
));
}
};
map.on("click", function (e) {
if (!$("#updatehome").is(":checked")) return;
- var zoom = map.getZoom(),
- precision = OSM.zoomPrecision(zoom),
- location = e.latlng.wrap();
+ const [lat, lon] = OSM.cropLocation(e.latlng);
- $("#home_lat").val(location.lat.toFixed(precision));
- $("#home_lon").val(location.lng.toFixed(precision));
+ $("#home_lat").val(lat);
+ $("#home_lon").val(lon);
deleted_lat = null;
deleted_lon = null;
/* Rules for the issues page */
.issues.issues-index {
- td.reporter_users {
+ td.reporting_users {
max-width: 5rem;
}
}
way_ids = way_nodes.collect { |way_node| way_node.id[0] }
ways = Way.preload(:way_nodes, :way_tags).find(way_ids)
- list_of_way_nodes = ways.collect do |way|
- way.way_nodes.collect(&:node_id)
- end
- list_of_way_nodes.flatten!
+ list_of_way_nodes = ways.flat_map { |way| way.way_nodes.map(&:node_id) }
end
# - [0] in case some thing links to node 0 which doesn't exist. Shouldn't actually ever happen but it does. FIXME: file a ticket for this
nodes += Node.includes(:node_tags).find(nodes_to_fetch) unless nodes_to_fetch.empty?
- visible_nodes = {}
- @nodes = []
- nodes.each do |node|
- if node.visible?
- visible_nodes[node.id] = node
- @nodes << node
- end
- end
+ @nodes = nodes.filter(&:visible?)
- @ways = []
- way_ids = []
- ways.each do |way|
- if way.visible?
- way_ids << way.id
- @ways << way
- end
- end
+ @ways = ways.filter(&:visible?)
- @relations = Relation.nodes(visible_nodes.keys).visible +
- Relation.ways(way_ids).visible
+ @relations = Relation.nodes(@nodes).visible +
+ Relation.ways(@ways).visible
# we do not normally return the "other" partners referenced by an relation,
# e.g. if we return a way A that is referenced by relation X, and there's
module NoteHelper
include ActionView::Helpers::TranslationHelper
+ def note_description(author, description)
+ if !author.nil? && author.status == "deleted"
+ RichText.new("text", t("notes.show.description_when_author_is_deleted"))
+ else
+ description
+ end
+ end
+
def note_event(event, at, by)
if by.nil?
t("notes.show.event_#{event}_by_anonymous_html",
def generate_share_url(site, title, url)
site = site.to_sym
- title = URI.encode_www_form_component(title)
- url = URI.encode_www_form_component(url)
+ title = URI.encode_uri_component(title)
+ url = URI.encode_uri_component(url)
case site
when :email
class Note < ApplicationRecord
include GeoRecord
+ belongs_to :author, :class_name => "User", :foreign_key => "user_id", :optional => true
+
has_many :comments, -> { left_joins(:author).where(:visible => true, :users => { :status => [nil, "active", "confirmed"] }).order(:created_at) }, :class_name => "NoteComment", :foreign_key => :note_id
has_many :all_comments, -> { left_joins(:author).order(:created_at) }, :class_name => "NoteComment", :foreign_key => :note_id, :inverse_of => :note
has_many :subscriptions, :class_name => "NoteSubscription"
# Return the note's description, derived from the first comment
def description
- comments.first.body
+ if user_ip.nil? && user_id.nil?
+ comments.first.body
+ else
+ RichText.new("text", super)
+ end
end
# Return the note's author object, derived from the first comment
def author
- comments.first.author
+ if user_ip.nil? && user_id.nil?
+ comments.first.author
+ else
+ super
+ end
end
private
xml.guid api_note_url(note)
xml.description render(:partial => "description", :object => note, :formats => [:html])
- xml.dc :creator, note.author.display_name if note.author
+ xml.dc :creator, note.author.display_name unless note.author.nil? || note.author.status == "deleted"
xml.pubDate note.created_at.to_fs(:rfc822)
xml.geo :lat, note.lat
<%= bootstrap_form_for @new_comment, :url => issue_comments_path(@issue) do |f| %>
<%= f.richtext_field :body, :cols => 80, :rows => 20, :hide_label => true %>
<%= f.form_group do %>
- <%= f.check_box :reassign, { :label => t(".reassign_param"), :id => "reassign", :name => "reassign", :checked => false }, true, false %>
+ <%= f.check_box :reassign, { :label => @issue.assigned_role == "administrator" ? t(".reassign_to_moderators") : t(".reassign_to_administrators"),
+ :id => "reassign", :name => "reassign", :checked => false }, true, false %>
<% end %>
<%= f.primary %>
<% end %>
<th><%= t ".reports" %></th>
<th><%= t ".reported_item" %></th>
<th><%= t ".reported_user" %></th>
- <th class="reporter_users"><%= t ".reporter_users" %></th>
+ <th class="reporting_users"><%= t ".reporting_users" %></th>
<th><%= t ".last_updated" %></th>
</tr>
</thead>
<td class="text-nowrap"><%= link_to t(".reports_count", :count => issue.reports_count), issue %></td>
<td><%= link_to reportable_title(issue.reportable), reportable_url(issue.reportable) %></td>
<td><%= link_to issue.reported_user.display_name, issue.reported_user if issue.reported_user %></td>
- <td class="reporter_users text-truncate">
+ <td class="reporting_users text-truncate">
<% @unique_reporters[issue.id][:users].each do |reporter| %>
<%= link_to reporter.display_name, reporter, :class => "d-block text-truncate", :title => reporter.display_name %>
<% end %>
</td>
<td><%= link_to note.id, note %></td>
<td><%= note_author(note.author) %></td>
- <td><%= note.description.to_html %></td>
+ <td><%= note_description(note.author, note.description).to_html %></td>
<td><%= friendly_date_ago(note.created_at) %></td>
<td><%= friendly_date_ago(note.updated_at) %></td>
</tr>
<div>
<h4><%= t(".description") %></h4>
<div class="overflow-hidden ms-2">
- <%= h(@note.description.to_html) %>
+ <%= h(note_description(@note.author, @note.description).to_html) %>
</div>
<div class="details" data-coordinates="<%= @note.lat %>,<%= @note.lon %>" data-status="<%= @note.status %>">
const globals = require("globals");
const js = require("@eslint/js");
+const erb = require("eslint-plugin-erb");
+const stylisticJs = require("@stylistic/eslint-plugin-js");
module.exports = [
js.configs.recommended,
+ erb.configs.recommended,
{
+ plugins: {
+ "@stylistic": stylisticJs
+ },
languageOptions: {
ecmaVersion: 2021,
sourceType: "script",
L: "readonly",
OSM: "writable",
Matomo: "readonly",
- Qs: "readonly",
Turbo: "readonly",
updateLinks: "readonly"
}
},
+ linterOptions: {
+ // The "unused disable directive" is set to "warn" by default.
+ // For the ERB plugin to work correctly, you must disable
+ // this directive to avoid issues described here
+ // https://github.com/eslint/eslint/discussions/18114
+ // If you're using the CLI, you might also use the following flag:
+ // --report-unused-disable-directives-severity=off
+ reportUnusedDisableDirectives: "off"
+ },
rules: {
- "accessor-pairs": "error",
- "array-bracket-newline": ["error", "consistent"],
- "array-bracket-spacing": "error",
- "array-callback-return": "error",
- "block-scoped-var": "error",
- "block-spacing": "error",
- "brace-style": ["error", "1tbs", { allowSingleLine: true }],
- "comma-dangle": "error",
- "comma-spacing": "error",
- "comma-style": "error",
- "computed-property-spacing": "error",
- "curly": ["error", "multi-line", "consistent"],
- "dot-location": ["error", "property"],
- "dot-notation": "error",
- "eol-last": "error",
- "eqeqeq": ["error", "smart"],
- "func-call-spacing": "error",
- "indent": ["error", 2, {
+ "@stylistic/array-bracket-newline": ["error", "consistent"],
+ "@stylistic/array-bracket-spacing": "error",
+ "@stylistic/block-spacing": "error",
+ "@stylistic/brace-style": ["error", "1tbs", { allowSingleLine: true }],
+ "@stylistic/comma-dangle": "error",
+ "@stylistic/comma-spacing": "error",
+ "@stylistic/comma-style": "error",
+ "@stylistic/computed-property-spacing": "error",
+ "@stylistic/dot-location": ["error", "property"],
+ "@stylistic/eol-last": "error",
+ "@stylistic/func-call-spacing": "error",
+ "@stylistic/indent": ["error", 2, {
SwitchCase: 1,
VariableDeclarator: "first",
FunctionDeclaration: { parameters: "first" },
FunctionExpression: { parameters: "first" },
CallExpression: { arguments: "first" }
}],
- "key-spacing": "error",
- "keyword-spacing": "error",
+ "@stylistic/key-spacing": "error",
+ "@stylistic/keyword-spacing": "error",
+ "@stylistic/no-floating-decimal": "error",
+ "@stylistic/no-mixed-operators": "error",
+ "@stylistic/no-multiple-empty-lines": "error",
+ "@stylistic/no-multi-spaces": "error",
+ "@stylistic/no-trailing-spaces": "error",
+ "@stylistic/no-whitespace-before-property": "error",
+ "@stylistic/object-curly-newline": ["error", { consistent: true }],
+ "@stylistic/object-curly-spacing": ["error", "always"],
+ "@stylistic/object-property-newline": ["error", { allowAllPropertiesOnSameLine: true }],
+ "@stylistic/operator-linebreak": ["error", "after"],
+ "@stylistic/padded-blocks": ["error", "never"],
+ "@stylistic/quote-props": ["error", "consistent-as-needed", { keywords: true, numbers: true }],
+ "@stylistic/quotes": ["error", "double"],
+ "@stylistic/semi": ["error", "always"],
+ "@stylistic/semi-spacing": "error",
+ "@stylistic/semi-style": "error",
+ "@stylistic/space-before-blocks": "error",
+ "@stylistic/space-before-function-paren": ["error", { named: "never" }],
+ "@stylistic/space-in-parens": "error",
+ "@stylistic/space-infix-ops": "error",
+ "@stylistic/space-unary-ops": "error",
+ "@stylistic/switch-colon-spacing": "error",
+ "@stylistic/wrap-iife": "error",
+ "@stylistic/wrap-regex": "error",
+
+ "accessor-pairs": "error",
+ "array-callback-return": "error",
+ "block-scoped-var": "error",
+ "curly": ["error", "multi-line", "consistent"],
+ "dot-notation": "error",
+ "eqeqeq": ["error", "smart"],
"no-alert": "warn",
"no-array-constructor": "error",
"no-caller": "error",
"no-extend-native": "error",
"no-extra-bind": "error",
"no-extra-label": "error",
- "no-floating-decimal": "error",
"no-implicit-coercion": "warn",
"no-implicit-globals": "warn",
"no-implied-eval": "error",
"no-lone-blocks": "error",
"no-lonely-if": "error",
"no-loop-func": "error",
- "no-mixed-operators": "error",
- "no-multiple-empty-lines": "error",
- "no-multi-spaces": "error",
"no-multi-str": "error",
"no-negated-condition": "error",
"no-nested-ternary": "error",
"no-self-compare": "error",
"no-sequences": "error",
"no-throw-literal": "error",
- "no-trailing-spaces": "error",
"no-undef-init": "error",
"no-undefined": "error",
"no-unmodified-loop-condition": "error",
"no-use-before-define": ["error", { functions: false }],
"no-void": "error",
"no-warning-comments": "warn",
- "no-whitespace-before-property": "error",
- "object-curly-newline": ["error", { consistent: true }],
- "object-curly-spacing": ["error", "always"],
- "object-property-newline": ["error", { allowAllPropertiesOnSameLine: true }],
- "operator-linebreak": ["error", "after"],
- "padded-blocks": ["error", "never"],
- "quote-props": ["error", "consistent-as-needed", { keywords: true, numbers: true }],
- "quotes": ["error", "double"],
"radix": ["error", "always"],
- "semi": ["error", "always"],
- "semi-spacing": "error",
- "semi-style": "error",
- "space-before-blocks": "error",
- "space-before-function-paren": ["error", { named: "never" }],
- "space-in-parens": "error",
- "space-infix-ops": "error",
- "space-unary-ops": "error",
- "switch-colon-spacing": "error",
- "wrap-iife": "error",
- "wrap-regex": "error",
"yoda": "error"
}
},
reports: Reports
last_updated: Last Updated
last_updated_time_ago_user_html: "%{time_ago} by %{user}"
- reporter_users: Reporter Users
+ reporting_users: Reporting Users
reports_count:
one: "%{count} Report"
other: "%{count} Reports"
reopened: Issue status has been set to 'Open'
comments:
comment_from_html: "Comment from %{user_link} on %{comment_created_at}"
- reassign_param: Reassign Issue?
+ reassign_to_moderators: Reassign Issue to Moderators
+ reassign_to_administrators: Reassign Issue to Administrators
reports:
reported_by_html: "Reported as %{category} by %{user} on %{updated_at}"
helper:
open_title: "Unresolved note #%{note_name}"
closed_title: "Resolved note #%{note_name}"
hidden_title: "Hidden note #%{note_name}"
+ description_when_author_is_deleted: "deleted"
event_opened_by_html: "Created by %{user} %{time_ago}"
event_opened_by_anonymous_html: "Created by anonymous %{time_ago}"
event_commented_by_html: "Comment from %{user} %{time_ago}"
def js_files
Rails.application.assets.each_file.select do |file|
- file.ends_with?(".js") && !file.match?(%r{/(gems|vendor|i18n|node_modules)/})
+ (file.ends_with?(".js") || file.ends_with?(".js.erb")) && !file.match?(%r{/(gems|vendor|i18n|node_modules)/})
end
end
"js-cookie": "^3.0.0",
"leaflet": "^1.8.0",
"leaflet.locatecontrol": "^0.83.0",
- "osm-community-index": "^5.2.0",
- "qs": "^6.9.4"
+ "osm-community-index": "^5.2.0"
},
"devDependencies": {
"eslint": "^9.0.0",
+ "eslint-plugin-erb": "^2.1.0",
+ "@stylistic/eslint-plugin-js": "^3.0.0",
"eslint-formatter-compact": "^8.40.0"
}
}
get changeset_show_path(changeset)
assert_response :success, "cannot get first changeset"
- assert_select "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
- assert_single_changeset changeset
- assert_select "osm>changeset>discussion", 0
+ assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
+ assert_single_changeset changeset do
+ assert_dom "> discussion", 0
+ end
get changeset_show_path(changeset), :params => { :include_discussion => true }
assert_response :success, "cannot get first changeset with comments"
- assert_select "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
- assert_single_changeset changeset
- assert_select "osm>changeset>discussion", 1
- assert_select "osm>changeset>discussion>comment", 0
+ assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
+ assert_single_changeset changeset do
+ assert_dom "> discussion", 1
+ assert_dom "> discussion > comment", 0
+ end
end
def test_show_comments
get changeset_show_path(changeset), :params => { :include_discussion => true }
assert_response :success, "cannot get closed changeset with comments"
- assert_select "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
- assert_single_changeset changeset
- assert_select "osm>changeset>discussion", 1
- assert_select "osm>changeset>discussion>comment", 3
- assert_select "osm>changeset>discussion>comment:nth-child(1)>@id", comment1.id.to_s
- assert_select "osm>changeset>discussion>comment:nth-child(1)>@visible", "true"
- assert_select "osm>changeset>discussion>comment:nth-child(2)>@id", comment2.id.to_s
- assert_select "osm>changeset>discussion>comment:nth-child(2)>@visible", "true"
- assert_select "osm>changeset>discussion>comment:nth-child(3)>@id", comment3.id.to_s
- assert_select "osm>changeset>discussion>comment:nth-child(3)>@visible", "true"
+ assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
+ assert_single_changeset changeset do
+ assert_dom "> discussion", 1 do
+ assert_dom "> comment", 3 do |dom_comments|
+ assert_dom dom_comments[0], "> @id", comment1.id.to_s
+ assert_dom dom_comments[0], "> @visible", "true"
+ assert_dom dom_comments[1], "> @id", comment2.id.to_s
+ assert_dom dom_comments[1], "> @visible", "true"
+ assert_dom dom_comments[2], "> @id", comment3.id.to_s
+ assert_dom dom_comments[2], "> @visible", "true"
+ end
+ end
+ end
+ end
# one hidden comment not included because not asked for
comment2.update(:visible => false)
get changeset_show_path(changeset), :params => { :include_discussion => true }
assert_response :success, "cannot get closed changeset with comments"
- assert_select "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
- assert_single_changeset changeset
- assert_select "osm>changeset>discussion", 1
- assert_select "osm>changeset>discussion>comment", 2
- assert_select "osm>changeset>discussion>comment:nth-child(1)>@id", comment1.id.to_s
- assert_select "osm>changeset>discussion>comment:nth-child(1)>@visible", "true"
- assert_select "osm>changeset>discussion>comment:nth-child(2)>@id", comment3.id.to_s
- assert_select "osm>changeset>discussion>comment:nth-child(2)>@visible", "true"
+ assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
+ assert_single_changeset changeset do
+ assert_dom "> discussion", 1 do
+ assert_dom "> comment", 2 do |dom_comments|
+ assert_dom dom_comments[0], "> @id", comment1.id.to_s
+ assert_dom dom_comments[0], "> @visible", "true"
+ assert_dom dom_comments[1], "> @id", comment3.id.to_s
+ assert_dom dom_comments[1], "> @visible", "true"
+ end
+ end
+ end
# one hidden comment not included because no permissions
get changeset_show_path(changeset), :params => { :include_discussion => true, :show_hidden_comments => true }
assert_response :success, "cannot get closed changeset with comments"
- assert_select "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
- assert_single_changeset changeset
- assert_select "osm>changeset>discussion", 1
- assert_select "osm>changeset>discussion>comment", 2
- assert_select "osm>changeset>discussion>comment:nth-child(1)>@id", comment1.id.to_s
- assert_select "osm>changeset>discussion>comment:nth-child(1)>@visible", "true"
- # maybe will show an empty comment element with visible=false in the future
- assert_select "osm>changeset>discussion>comment:nth-child(2)>@id", comment3.id.to_s
- assert_select "osm>changeset>discussion>comment:nth-child(2)>@visible", "true"
+ assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
+ assert_single_changeset changeset do
+ assert_dom "> discussion", 1 do
+ assert_dom "> comment", 2 do |dom_comments|
+ assert_dom dom_comments[0], "> @id", comment1.id.to_s
+ assert_dom dom_comments[0], "> @visible", "true"
+ # maybe will show an empty comment element with visible=false in the future
+ assert_dom dom_comments[1], "> @id", comment3.id.to_s
+ assert_dom dom_comments[1], "> @visible", "true"
+ end
+ end
+ end
# one hidden comment shown to moderators
moderator_user = create(:moderator_user)
:headers => auth_header
assert_response :success, "cannot get closed changeset with comments"
- assert_select "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
- assert_single_changeset changeset
- assert_select "osm>changeset>discussion", 1
- assert_select "osm>changeset>discussion>comment", 3
- assert_select "osm>changeset>discussion>comment:nth-child(1)>@id", comment1.id.to_s
- assert_select "osm>changeset>discussion>comment:nth-child(1)>@visible", "true"
- assert_select "osm>changeset>discussion>comment:nth-child(2)>@id", comment2.id.to_s
- assert_select "osm>changeset>discussion>comment:nth-child(2)>@visible", "false"
- assert_select "osm>changeset>discussion>comment:nth-child(3)>@id", comment3.id.to_s
- assert_select "osm>changeset>discussion>comment:nth-child(3)>@visible", "true"
+ assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
+ assert_single_changeset changeset do
+ assert_dom "> discussion", 1 do
+ assert_dom "> comment", 3 do |dom_comments|
+ assert_dom dom_comments[0], "> @id", comment1.id.to_s
+ assert_dom dom_comments[0], "> @visible", "true"
+ assert_dom dom_comments[1], "> @id", comment2.id.to_s
+ assert_dom dom_comments[1], "> @visible", "false"
+ assert_dom dom_comments[2], "> @id", comment3.id.to_s
+ assert_dom dom_comments[2], "> @visible", "true"
+ end
+ end
+ end
end
def test_show_json
##
# check that the output consists of one specific changeset
- def assert_single_changeset(changeset)
- assert_select "osm>changeset", 1
- assert_select "osm>changeset>@id", changeset.id.to_s
- assert_select "osm>changeset>@created_at", changeset.created_at.xmlschema
- if changeset.open?
- assert_select "osm>changeset>@open", "true"
- assert_select "osm>changeset>@closed_at", 0
- else
- assert_select "osm>changeset>@open", "false"
- assert_select "osm>changeset>@closed_at", changeset.closed_at.xmlschema
+ def assert_single_changeset(changeset, &)
+ assert_dom "> changeset", 1 do
+ assert_dom "> @id", changeset.id.to_s
+ assert_dom "> @created_at", changeset.created_at.xmlschema
+ if changeset.open?
+ assert_dom "> @open", "true"
+ assert_dom "> @closed_at", 0
+ else
+ assert_dom "> @open", "false"
+ assert_dom "> @closed_at", changeset.closed_at.xmlschema
+ end
+ yield if block_given?
end
end
SOCIAL_SHARE_CONFIG.each_value do |icon|
assert_dom buttons_dom, "div:has(a img[src='/images/#{icon}'])", :count => 1 do
- assert_dom "a[href*='Test+Title']"
+ assert_dom "a[href*='Test%20Title']"
assert_dom "a[href*='https%3A%2F%2Fexample.com']"
end
end
end
+
+ def test_generate_share_url_email
+ url = generate_share_url(:email, "Diary Entry Title", "https://osm.example.com/some/diary/entry")
+ assert_equal "mailto:?subject=Diary%20Entry%20Title&body=https%3A%2F%2Fosm.example.com%2Fsome%2Fdiary%2Fentry", url
+ end
end
//= require leaflet.osm
//= require leaflet.map
//= require i18n/translations
-//= require qs/dist/qs
describe("OSM", function () {
describe(".apiUrl", function () {
fill_in "text", :with => "Some newly added note description"
click_on "Add Note"
- assert_content "Unresolved note ##{Note.last.id}"
+ assert_content "Unresolved note #"
assert_content "Some newly added note description"
end
end
click_on "Add Note"
- assert_content "Unresolved note ##{Note.last.id}"
+ assert_content "Unresolved note #"
assert_content "Some newly added note description"
end
end
assert_equal("test comment", issue.comments.first.body)
end
- def test_reassign_issue
- issue = create(:issue)
- assert_equal "administrator", issue.assigned_role
+ def test_reassign_issue_to_moderators
+ issue = create(:issue, :assigned_role => "administrator")
sign_in_as(create(:administrator_user))
visit issue_path(issue)
+ assert_unchecked_field "Reassign Issue to Moderators"
fill_in :issue_comment_body, :with => "reassigning to moderators"
- check :reassign
+ check "Reassign Issue to Moderators"
click_on "Add Comment"
assert_content "and the issue was reassigned"
assert_equal "moderator", issue.assigned_role
end
+ def test_reassign_issue_to_administrators
+ issue = create(:issue, :assigned_role => "moderator")
+ sign_in_as(create(:moderator_user))
+
+ visit issue_path(issue)
+
+ assert_unchecked_field "Reassign Issue to Administrators"
+ fill_in :issue_comment_body, :with => "reassigning to administrators"
+ check "Reassign Issue to Administrators"
+ click_on "Add Comment"
+
+ assert_content "and the issue was reassigned"
+ assert_current_path issues_path(:status => "open")
+
+ issue.reload
+ assert_equal "administrator", issue.assigned_role
+ end
+
def test_reassign_issue_as_super_user
issue = create(:issue)
sign_in_as(create(:super_user))
visit issue_path(issue)
fill_in :issue_comment_body, :with => "reassigning to moderators"
- check :reassign
+ check "Reassign Issue to Moderators"
click_on "Add Comment"
assert_content "and the issue was reassigned"
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.1.tgz#9a96ce501bc62df46c4031fbd970e3cc6b10f07b"
integrity sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==
+"@stylistic/eslint-plugin-js@^3.0.0":
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin-js/-/eslint-plugin-js-3.0.1.tgz#15638c55a9adab2c110243a9f0d812264b067aab"
+ integrity sha512-hjp6BKXSUdlY4l20pDb0EjIB5PtQDGihk2EUKCjJ5gaRVfcmMMkaIyVd/yK3oH7OLxWWBxJ8qSSo+zEdkmpnYA==
+ dependencies:
+ eslint-visitor-keys "^4.2.0"
+ espree "^10.3.0"
+
"@types/estree@^1.0.6":
version "1.0.6"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
balanced-match "^1.0.0"
concat-map "0.0.1"
-call-bind-apply-helpers@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz#32e5892e6361b29b0b545ba6f7763378daca2840"
- integrity sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==
- dependencies:
- es-errors "^1.3.0"
- function-bind "^1.1.2"
-
-call-bound@^1.0.2:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.3.tgz#41cfd032b593e39176a71533ab4f384aa04fd681"
- integrity sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==
- dependencies:
- call-bind-apply-helpers "^1.0.1"
- get-intrinsic "^1.2.6"
-
callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
resolved "https://registry.yarnpkg.com/diacritics/-/diacritics-1.3.0.tgz#3efa87323ebb863e6696cebb0082d48ff3d6f7a1"
integrity sha512-wlwEkqcsaxvPJML+rDh/2iS824jbREk6DUMUKkEaSlxdYHeS43cClJtsWglvw2RfeXGm6ohKDqsXteJ5sP5enA==
-dunder-proto@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a"
- integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
- dependencies:
- call-bind-apply-helpers "^1.0.1"
- es-errors "^1.3.0"
- gopd "^1.2.0"
-
-es-define-property@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa"
- integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
-
-es-errors@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
- integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
-
-es-object-atoms@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.0.tgz#095de9ecceeb2ca79668212b60ead450ffd323bf"
- integrity sha512-Ujz8Al/KfOVR7fkaghAB1WvnLsdYxHDWmfoi2vlA2jZWRg31XhIC1a4B+/I24muD8iSbHxJ1JkrfqmWb65P/Mw==
- dependencies:
- es-errors "^1.3.0"
-
escape-string-regexp@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
resolved "https://registry.yarnpkg.com/eslint-formatter-compact/-/eslint-formatter-compact-8.40.0.tgz#d7455b2d75fd70e8c0e7a98a5e189f168e9dfe2d"
integrity sha512-cwGUs113TgmTQXecx5kfRjB7m0y2wkDLSadPTE2pK6M/wO4N8PjmUaoWOFNCP9MHgsiZwgqd5bZFnDCnszC56Q==
+eslint-plugin-erb@^2.1.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-erb/-/eslint-plugin-erb-2.1.1.tgz#8a0a6c2bcaf3a8573c381b595969145aff93cfc6"
+ integrity sha512-AhznaVwRpQqR8NADjN4SZnKNbaIdAbGxTjCg6cj3UhwGyQOUJ6kXwhYrl1LYrGDNx7Ouyd8xuEG7wepFZyPgFw==
+
eslint-scope@^8.2.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.2.0.tgz#377aa6f1cb5dc7592cfd0b7f892fd0cf352ce442"
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a"
integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==
-function-bind@^1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
- integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
-
-get-intrinsic@^1.2.5, get-intrinsic@^1.2.6:
- version "1.2.7"
- resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.7.tgz#dcfcb33d3272e15f445d15124bc0a216189b9044"
- integrity sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==
- dependencies:
- call-bind-apply-helpers "^1.0.1"
- es-define-property "^1.0.1"
- es-errors "^1.3.0"
- es-object-atoms "^1.0.0"
- function-bind "^1.1.2"
- get-proto "^1.0.0"
- gopd "^1.2.0"
- has-symbols "^1.1.0"
- hasown "^2.0.2"
- math-intrinsics "^1.1.0"
-
-get-proto@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1"
- integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==
- dependencies:
- dunder-proto "^1.0.1"
- es-object-atoms "^1.0.0"
-
glob-parent@^6.0.2:
version "6.0.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e"
integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==
-gopd@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
- integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
-
has-flag@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
-has-symbols@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338"
- integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
-
-hasown@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
- integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
- dependencies:
- function-bind "^1.1.2"
-
ignore@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
-math-intrinsics@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9"
- integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
-
minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
-object-inspect@^1.13.3:
- version "1.13.3"
- resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.3.tgz#f14c183de51130243d6d18ae149375ff50ea488a"
- integrity sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==
-
optionator@^0.9.3:
version "0.9.3"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
-qs@^6.9.4:
- version "6.14.0"
- resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.0.tgz#c63fa40680d2c5c941412a0e899c89af60c0a930"
- integrity sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==
- dependencies:
- side-channel "^1.1.0"
-
resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
-side-channel-list@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad"
- integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==
- dependencies:
- es-errors "^1.3.0"
- object-inspect "^1.13.3"
-
-side-channel-map@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42"
- integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==
- dependencies:
- call-bound "^1.0.2"
- es-errors "^1.3.0"
- get-intrinsic "^1.2.5"
- object-inspect "^1.13.3"
-
-side-channel-weakmap@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea"
- integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==
- dependencies:
- call-bound "^1.0.2"
- es-errors "^1.3.0"
- get-intrinsic "^1.2.5"
- object-inspect "^1.13.3"
- side-channel-map "^1.0.1"
-
-side-channel@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9"
- integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==
- dependencies:
- es-errors "^1.3.0"
- object-inspect "^1.13.3"
- side-channel-list "^1.0.0"
- side-channel-map "^1.0.1"
- side-channel-weakmap "^1.0.2"
-
strip-json-comments@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"