uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ env.ruby }}
+ rubygems: 3.4.10
bundler-cache: true
- name: Run rubocop
run: bundle exec rubocop --format fuubar
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ env.ruby }}
+ rubygems: 3.4.10
bundler-cache: true
- name: Run erblint
run: bundle exec erblint .
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ env.ruby }}
+ rubygems: 3.4.10
bundler-cache: true
- name: Cache node modules
uses: actions/cache@v3
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ env.ruby }}
+ rubygems: 3.4.10
bundler-cache: true
- name: Run brakeman
run: bundle exec brakeman -q
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ env.ruby }}
+ rubygems: 3.4.10
bundler-cache: true
- name: Setup database
run: |
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
+ rubygems: 3.4.10
bundler-cache: true
- name: Cache node modules
uses: actions/cache@v3
# Offense count: 26
# Configuration parameters: CountComments, CountAsOne.
Metrics/ClassLength:
- Max: 286
+ Max: 297
# Offense count: 59
# Configuration parameters: AllowedMethods, AllowedPatterns.
# Reduces boot times through caching; required in config/boot.rb
gem "bootsnap", ">= 1.4.2", :require => false
-# Use R2 for RTL conversion
-gem "r2", "~> 0.2.7"
+# Use rtlcss for RTL conversion
+gem "rtlcss"
# Use autoprefixer to generate CSS prefixes
gem "autoprefixer-rails"
activemodel (= 7.1.2)
activesupport (= 7.1.2)
timeout (>= 0.4.0)
- activerecord-import (1.5.0)
+ activerecord-import (1.5.1)
activerecord (>= 4.2)
activestorage (7.1.2)
actionpack (= 7.1.2)
ffi (~> 1.15)
ffi-compiler (~> 1.0)
ast (2.4.2)
- autoprefixer-rails (10.4.15.0)
+ autoprefixer-rails (10.4.16.0)
execjs (~> 2)
- aws-eventstream (1.2.0)
- aws-partitions (1.849.0)
- aws-sdk-core (3.186.0)
+ aws-eventstream (1.3.0)
+ aws-partitions (1.859.0)
+ aws-sdk-core (3.188.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1)
- aws-sdk-kms (1.72.0)
- aws-sdk-core (~> 3, >= 3.184.0)
+ aws-sdk-kms (1.73.0)
+ aws-sdk-core (~> 3, >= 3.188.0)
aws-sigv4 (~> 1.1)
- aws-sdk-s3 (1.136.0)
- aws-sdk-core (~> 3, >= 3.181.0)
+ aws-sdk-s3 (1.140.0)
+ aws-sdk-core (~> 3, >= 3.188.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.6)
- aws-sigv4 (1.6.1)
+ aws-sigv4 (1.7.0)
aws-eventstream (~> 1, >= 1.0.2)
base64 (0.2.0)
better_errors (2.10.1)
activerecord (>= 3.0, < 8.0)
delayed_job (>= 3.0, < 5)
docile (1.4.0)
- doorkeeper (5.6.6)
+ doorkeeper (5.6.7)
railties (>= 5)
doorkeeper-i18n (5.2.7)
doorkeeper (>= 5.2)
erubi (1.12.0)
execjs (2.9.1)
exifr (1.4.0)
- factory_bot (6.2.1)
+ factory_bot (6.4.2)
activesupport (>= 5.0.0)
- factory_bot_rails (6.2.0)
- factory_bot (~> 6.2.0)
+ factory_bot_rails (6.4.2)
+ factory_bot (~> 6.4)
railties (>= 5.0.0)
- faraday (2.7.11)
+ faraday (2.7.12)
base64
faraday-net_http (>= 2.0, < 3.1)
ruby2_keywords (>= 0.0.4)
ffi (>= 1.0.0)
globalid (1.2.1)
activesupport (>= 6.1)
- google-protobuf (3.25.0)
+ google-protobuf (3.25.1)
hashdiff (1.0.1)
hashie (5.0.0)
highline (2.1.0)
image_size (3.3.0)
in_threads (1.6.0)
io-console (0.6.0)
- irb (1.9.0)
+ irb (1.9.1)
rdoc
reline (>= 0.3.8)
jbuilder (2.11.5)
kramdown (2.4.0)
rexml
language_server-protocol (3.17.0.3)
+ libv8-node (18.16.0.0)
libxml-ruby (4.1.2)
listen (3.8.0)
rb-fsevent (~> 0.10, >= 0.10.3)
mini_magick (4.12.0)
mini_mime (1.1.5)
mini_portile2 (2.8.5)
+ mini_racer (0.8.0)
+ libv8-node (~> 18.16.0.0)
minitest (5.20.0)
msgpack (1.7.2)
multi_json (1.15.0)
multi_xml (0.6.0)
mutex_m (0.2.0)
- net-imap (0.4.5)
+ net-imap (0.4.6)
date
net-protocol
net-pop (0.1.2)
timeout
net-smtp (0.4.0)
net-protocol
- nio4r (2.5.9)
- nokogiri (1.15.4)
+ nio4r (2.6.1)
+ nokogiri (1.15.5)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
oauth (0.4.7)
progress (3.6.0)
psych (5.1.1.1)
stringio
- public_suffix (5.0.3)
+ public_suffix (5.0.4)
puma (5.6.7)
nio4r (~> 2.0)
quad_tile (1.0.1)
- r2 (0.2.8)
racc (1.7.3)
rack (2.2.8)
rack-cors (2.0.1)
rdoc (6.6.0)
psych (>= 4.0.0)
regexp_parser (2.8.2)
- reline (0.4.0)
+ reline (0.4.1)
io-console (~> 0.5)
request_store (1.5.1)
rack (>= 1.4)
rinku (2.0.6)
rotp (6.3.0)
rouge (4.2.0)
+ rtlcss (0.2.1)
+ mini_racer (>= 0.6.3)
rubocop (1.57.2)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
rubocop-performance (1.19.1)
rubocop (>= 1.7.0, < 2.0)
rubocop-ast (>= 0.4.0)
- rubocop-rails (2.22.1)
+ rubocop-rails (2.22.2)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0)
+ rubocop-ast (>= 1.30.0, < 2.0)
rubocop-rake (0.6.0)
rubocop (~> 1.0)
ruby-openid (2.9.2)
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
- stringio (3.0.9)
+ stringio (3.1.0)
strong_migrations (1.6.4)
activerecord (>= 5.2)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
- terser (1.1.19)
+ terser (1.1.20)
execjs (>= 0.3.0, < 3)
thor (1.3.0)
tilt (2.3.0)
pg
puma (~> 5.6)
quad_tile (~> 1.0.1)
- r2 (~> 0.2.7)
rack-cors
rack-uri_sanitizer
rails (~> 7.1.0)
rails-i18n (~> 7.0.0)
rinku (>= 2.0.6)
rotp
+ rtlcss
rubocop
rubocop-capybara
rubocop-factory_bot
if Settings.status != "database_offline"
can [:show, :download, :query], Changeset
- can [:index, :create, :comment, :feed, :show, :search], Note
+ can [:index, :create, :feed, :show, :search], Note
can :index, Tracepoint
can [:index, :show], User
can [:index, :show], Node
if Settings.status != "database_offline"
can [:index, :new, :create, :show, :edit, :update, :destroy], ClientApplication
can [:new, :create, :reply, :show, :inbox, :outbox, :mark, :destroy], Message
- can [:close, :reopen], Note
+ can [:comment, :close, :reopen], Note
can [:new, :create], Report
can [:create, :show, :update, :destroy, :data], Trace
can [:details, :gpx_files], User
$("body").removeClass("compact-nav");
+ $("header").removeClass("text-nowrap");
+
updateHeader();
$(window).resize(updateHeader);
}
function updateButton() {
- var disabled = ["mapnik", "cyclemap"].indexOf(map.getMapBaseLayerId()) === -1;
+ var disabled = OSM.LAYERS_WITH_MAP_KEY.indexOf(map.getMapBaseLayerId()) === -1;
button
.toggleClass("disabled", disabled)
.attr("data-bs-original-title",
.text(I18n.t("javascripts.share.short_link")))
.append($("<a class='btn btn-primary'>")
.attr("for", "embed_html")
+ .attr("id", "embed_link")
+ .attr("data-bs-title", I18n.t("javascripts.site.embed_html_disabled"))
.attr("href", "#")
.text(I18n.t("javascripts.share.embed")))
.on("click", "a", function (e) {
e.preventDefault();
+ if (!$(this).hasClass("btn-primary")) return;
var id = "#" + $(this).attr("for");
$(this).siblings("a")
.removeClass("active");
}
function update() {
+ var canEmbed = map.getMapBaseLayerId() !== "tracestracktopo";
var bounds = map.getBounds();
$("#link_marker")
params.marker = latLng.lat + "," + latLng.lng;
}
+ $("#embed_link")
+ .toggleClass("btn-primary", canEmbed)
+ .toggleClass("btn-secondary", !canEmbed)
+ .tooltip(canEmbed ? "disable" : "enable");
+ if (!canEmbed && $("#embed_link").hasClass("active")) {
+ $("#long_link").click();
+ }
+
$("#embed_html").val(
"<iframe width=\"425\" height=\"350\" src=\"" +
escapeHTML(OSM.SERVER_PROTOCOL + "://" + OSM.SERVER_URL + "/export/embed.html?" + $.param(params)) +
//= depend_on settings.yml
//= depend_on settings.local.yml
+//= depend_on key.yml
//= require qs/dist/qs
OSM = {
TRACESTRACK_KEY: <%= Settings.tracestrack_key.to_json %>,
<% end %>
+ 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 %>,
@import "bootstrap";
@import "rails_bootstrap_forms";
-/* Bootstrap + r2 fixes */
-
-:root[dir=rtl] {
- .bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow {
- /* no-r2 */
- right: unset !important;
- left: calc(-1 * var(--bs-tooltip-arrow-height)) !important;
-
- &::before {
- /* no-r2 */
- left: unset !important;
- right: -1px !important;
- }
- }
-
- .bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow {
- /* no-r2 */
- left: unset !important;
- right: calc(-1 * var(--bs-tooltip-arrow-height)) !important;
-
- &::before {
- /* no-r2 */
- right: unset !important;
- left: -1px !important;
- }
- }
-}
-
/* Styles common to large and small screens */
/* Default rules for the body of every page */
overflow: hidden;
}
-.icon.search { /* no-r2 */ background-position: 0 0; }
-.icon.donate { /* no-r2 */ background-position: -20px 0; }
-.icon.zoomin { /* no-r2 */ background-position: -40px 0; }
-.icon.zoomout { /* no-r2 */ background-position: -60px 0; }
-.icon.geolocate { /* no-r2 */ background-position: -80px 0; }
-.active .icon.geolocate { /* no-r2 */ background-position: -80px -20px; }
-.icon.layers { /* no-r2 */ background-position: -100px 0; }
-.icon.key { /* no-r2 */ background-position: -120px 0; }
-.icon.share { /* no-r2 */ background-position: -140px 0; }
-.icon.clipboard { /* no-r2 */ background-position: -160px 0; }
-.icon.link { /* no-r2 */ background-position: -180px 0; }
-.icon.close { /* no-r2 */ background-position: -200px 0; }
-.icon.close:hover { /* no-r2 */ background-position: -200px -20px; }
-.icon.check { /* no-r2 */ background-position: -220px 0; }
-.icon.note { /* no-r2 */ background-position: -240px 0; }
-.icon.note.grey { /* no-r2 */ background-position: -240px -20px; }
-.icon.query { /* no-r2 */ background-position: -260px 0; }
+.icon.search { /*rtl:ignore*/ background-position: 0 0; }
+.icon.donate { /*rtl:ignore*/ background-position: -20px 0; }
+.icon.zoomin { /*rtl:ignore*/ background-position: -40px 0; }
+.icon.zoomout { /*rtl:ignore*/ background-position: -60px 0; }
+.icon.geolocate { /*rtl:ignore*/ background-position: -80px 0; }
+.active .icon.geolocate { /*rtl:ignore*/ background-position: -80px -20px; }
+.icon.layers { /*rtl:ignore*/ background-position: -100px 0; }
+.icon.key { /*rtl:ignore*/ background-position: -120px 0; }
+.icon.share { /*rtl:ignore*/ background-position: -140px 0; }
+.icon.clipboard { /*rtl:ignore*/ background-position: -160px 0; }
+.icon.link { /*rtl:ignore*/ background-position: -180px 0; }
+.icon.close { /*rtl:ignore*/ background-position: -200px 0; }
+.icon.close:hover { /*rtl:ignore*/ background-position: -200px -20px; }
+.icon.check { /*rtl:ignore*/ background-position: -220px 0; }
+.icon.note { /*rtl:ignore*/ background-position: -240px 0; }
+.icon.note.grey { /*rtl:ignore*/ background-position: -240px -20px; }
+.icon.query { /*rtl:ignore*/ background-position: -260px 0; }
/* Utility for de-emphasizing content */
#menu-icon {
display: none;
- float: right;
+ position: absolute;
+ top: 0;
+ right: 0;
background: image-url("menu-icon.png") no-repeat;
background-size: 30px 30px;
width: 30px;
padding: $lineheight * 0.5;
}
- h1, nav.primary {
- float: left;
- }
-
img.logo {
margin-top: -2px;
}
.btn {
font-size: 14px;
}
-}
+ nav.primary {
+ margin-right: auto;
+ }
+}
nav.primary {
& > .btn-group .btn-outline-primary {
}
nav.secondary {
- position: absolute;
- right: 0;
-
.nav-link {
padding: 0.2rem;
color: $darkgrey;
display: block;
}
- nav.primary,
- nav.secondary {
- float: none !important;
- position: relative;
- display: block;
- clear: both;
- }
-
header {
+ flex-direction: column;
height: auto;
min-height: $headerHeight;
background: #fff;
}
nav.primary {
+ margin-right: 0;
padding: 0;
- ul, li {
- border: none;
- border-radius: 0;
- width: 100%;
- }
-
- ul {
- border-top: 1px solid #eee;
- li {
- border-bottom: 1px solid #eee;
- border-right: none;
- > a {
- border-radius: 0;
- width: 100%;
- text-align: center;
- font-size: 15px;
- }
- }
- }
-
.btn-group {
width: 100%;
padding: 10px;
}
}
+/* Force LTR/RTL alignment for placeholder text */
+
+.form-control::placeholder {
+ text-align: left;
+}
+
/* Rules for export sidebar */
.export_form {
#maxlat { margin-top: -1px; }
#minlon {
float: left;
- /* no-r2 */ margin-left: -1px;
+ /*rtl:ignore*/ margin-left: -1px;
}
#maxlon {
float: right;
- /* no-r2 */ margin-right: -1px;
+ /*rtl:ignore*/ margin-right: -1px;
}
#minlat { margin-bottom: -1px; }
}
}
img.user_thumbnail_tiny {
- width: auto;
- height: auto;
- max-width: 25px;
- max-height: 25px;
+ width: 25px;
+ height: 25px;
+ object-fit: contain;
}
/* General styles for action lists / subnavs */
}
.sprite.x {
- /* no-r2 */ background-position: -50px 0;
+ /*rtl:ignore*/ background-position: -50px 0;
}
.sprite.term {
}
.sprite.node {
- /* no-r2 */ background-position: -100px 0;
+ /*rtl:ignore*/ background-position: -100px 0;
}
.sprite.way {
- /* no-r2 */ background-position: -150px 0;
+ /*rtl:ignore*/ background-position: -150px 0;
}
.sprite.tag {
- /* no-r2 */ background-position: -200px 0;
+ /*rtl:ignore*/ background-position: -200px 0;
}
.sprite.editor {
- /* no-r2 */ background-position: -250px 0;
+ /*rtl:ignore*/ background-position: -250px 0;
}
.sprite.question {
- /* no-r2 */ background-position: -300px 0;
+ /*rtl:ignore*/ background-position: -300px 0;
}
.sprite.rules {
- /* no-r2 */ background-position: -350px 0;
+ /*rtl:ignore*/ background-position: -350px 0;
}
.icon.note {
background: 40px 40px image-url('about/sprite.png') no-repeat;
&.local {
- /* no-r2 */
+ /*rtl:ignore*/
background-position: 0px 0px;
}
&.community {
- /* no-r2 */
+ /*rtl:ignore*/
background-position: 0px -40px;
}
&.open {
- /* no-r2 */
+ /*rtl:ignore*/
background-position: 0px -80px;
}
&.partners {
- /* no-r2 */
+ /*rtl:ignore*/
background-position: 0px -120px;
}
&.infringement {
- /* no-r2 */
+ /*rtl:ignore*/
background-position: 0px -160px;
}
&.legal {
- /* no-r2 */
+ /*rtl:ignore*/
background-position: -45px -160px;
}
}
end
def destroy
- current_user.soft_destroy!
+ if current_user.deletion_allowed?
+ current_user.soft_destroy!
- session.delete(:user)
- session_expires_automatically
+ session.delete(:user)
+ session_expires_automatically
- flash[:notice] = t ".success"
- redirect_to root_path
+ flash[:notice] = t ".success"
+ redirect_to root_path
+ else
+ head :bad_request
+ end
end
end
##
# if a bounding box was specified do some sanity checks.
# restrict changesets to those enclosed by a bounding box
- # we need to return both the changesets and the bounding box
def conditions_bbox(changesets, bbox)
if bbox
bbox.check_boundaries
##
# Add a comment to an existing note
def comment
- # Check the ACLs
- raise OSM::APIAccessDenied if current_user.nil? && Acl.no_note_comment(request.remote_ip)
-
# Check the arguments are sane
raise OSM::APIBadUserInput, "No id was given" unless params[:id]
raise OSM::APIBadUserInput, "No text was given" if params[:text].blank?
def add_comment(note, text, event, notify: true)
attributes = { :visible => true, :event => event, :body => text }
- if current_user
- attributes[:author_id] = current_user.id
+ if doorkeeper_token || current_token
+ author = current_user if scope_enabled?(:write_notes)
+ else
+ author = current_user
+ end
+
+ if author
+ attributes[:author_id] = author.id
else
attributes[:author_ip] = request.remote_ip
end
##
# if a bounding box was specified do some sanity checks.
# restrict changesets to those enclosed by a bounding box
- # we need to return both the changesets and the bounding box
def conditions_bbox(changesets, bbox)
if bbox
bbox.check_boundaries
#
# Indexes
#
-# changesets_bbox_idx (min_lat,max_lat,min_lon,max_lon) USING gist
-# changesets_closed_at_idx (closed_at)
-# changesets_created_at_idx (created_at)
-# changesets_user_id_created_at_idx (user_id,created_at)
-# changesets_user_id_id_idx (user_id,id)
+# changesets_bbox_idx (min_lat,max_lat,min_lon,max_lon) USING gist
+# changesets_closed_at_idx (closed_at)
+# changesets_created_at_idx (created_at)
+# changesets_user_id_created_at_idx (user_id,created_at)
+# changesets_user_id_id_idx (user_id,id)
+# index_changesets_on_user_id_and_closed_at (user_id,closed_at)
#
# Foreign Keys
#
end
end
+ def deletion_allowed_at
+ unless Settings.user_account_deletion_delay.nil?
+ last_changeset = changesets.reorder(:closed_at => :desc).first
+ return last_changeset.closed_at.utc + Settings.user_account_deletion_delay.hours if last_changeset
+ end
+ creation_time.utc
+ end
+
+ def deletion_allowed?
+ deletion_allowed_at <= Time.now.utc
+ end
+
private
def encrypt_password
<li><%= t ".retain_email" %></li>
</ul>
-<%= link_to t(".delete_account"), account_path, { :method => :delete, :class => "btn btn-danger", :data => { :confirm => t(".confirm_delete") } } %>
+<% if current_user.deletion_allowed? %>
+ <%= link_to t(".delete_account"), account_path, { :method => :delete, :class => "btn btn-danger", :data => { :confirm => t(".confirm_delete") } } %>
+<% else %>
+ <div class="alert alert-warning">
+ <%= t ".recent_editing_html", :time => friendly_date(current_user.deletion_allowed_at) %>
+ </div>
+ <button class="btn btn-secondary" disabled><%= t(".delete_account") %></button>
+<% end %>
+
<%= link_to t(".cancel"), edit_account_path, :class => "btn btn-link" %>
xml.instruct! :xml, :version => "1.0"
-# basic attributes
-
xml.osm(OSM::API.new.xml_root_attributes) do |osm|
osm << render(@changeset)
end
xml.instruct! :xml, :version => "1.0"
-# basic attributes
-
xml.osm(OSM::API.new.xml_root_attributes) do |osm|
@changesets.each do |changeset|
osm << render(changeset)
-<header class="closed clearfix">
+<header class="d-flex text-nowrap closed">
<h1 class="m-0 fw-semibold">
<a href="<%= root_path %>" class="text-black text-decoration-none geolink">
<%= image_tag "osm_logo.png", :srcset => image_path("osm_logo.svg"), :alt => t("layouts.logo.alt_text"), :width => 30, :height => 30, :class => "logo" %>
</li>
</ul>
<% if current_user && current_user.id %>
- <div class='d-inline-flex dropdown user-menu logged-in clearfix'>
+ <div class='d-inline-flex dropdown user-menu logged-in'>
<button class='dropdown-toggle btn btn-outline-secondary border-grey bg-white text-secondary px-2 py-1 flex-grow-1' type='button' data-bs-toggle='dropdown'>
<%= user_thumbnail_tiny(current_user, :width => 25, :height => 25, :class => "user_thumbnail_tiny rounded-1") %>
<%= render :partial => "layouts/inbox" %>
# Use the test adapter for ActiveJob during testing.
config.active_job.queue_adapter = :test
+
+ # Allow FactoryBot to set primary key attributes
+ config.factory_bot.reject_primary_key_attributes = false
end
required(:max_number_of_relation_members).filled(:int?)
required(:max_issues_count).filled(:int?)
required(:api_timeout).filled(:int?)
+ required(:user_account_deletion_delay).maybe(:number?)
required(:imagery_blacklist).maybe(:array?)
required(:status).filled(:str?, :included_in? => ALLOWED_STATUS)
required(:avatar_storage).filled(:str?)
+++ /dev/null
-require "r2"
-
-class R2ScssProcessor < SassC::Rails::ScssTemplate
- def self.call(input)
- output = super(input)
- data = R2.r2(output[:data])
- output.delete(:map)
- output.merge(:data => data)
- end
-end
-
-Rails.application.config.assets.configure do |env|
- env.register_mime_type "text/r2+scss", :extensions => [".r2.scss"]
- env.register_transformer "text/r2+scss", "text/css", R2ScssProcessor
- env.register_preprocessor "text/r2+scss", Sprockets::DirectiveProcessor.new(:comments => ["//", ["/*", "*/"]])
-end
--- /dev/null
+require "rtlcss"
+
+class RtlcssSCSSProcessor < SassC::Rails::ScssTemplate
+ def self.call(input)
+ output = super(input)
+ data = Rtlcss.flip_css(output[:data])
+ output.delete(:map)
+ output.merge(:data => data)
+ end
+end
+
+Rails.application.config.assets.configure do |env|
+ env.register_mime_type "text/rtlcss+scss", :extensions => [".rtlcss.scss"]
+ env.register_transformer "text/rtlcss+scss", "text/css", RtlcssSCSSProcessor
+ env.register_preprocessor "text/rtlcss+scss", Sprockets::DirectiveProcessor.new(:comments => ["//", ["/*", "*/"]])
+end
- { min_zoom: 13, max_zoom: 19, name: bridleway, image: bridleway.png }
- { min_zoom: 13, max_zoom: 19, name: cycleway, image: cycleway.png }
- { min_zoom: 13, max_zoom: 19, name: footway, image: footway.png }
- - { min_zoom: 8, max_zoom: 12, name: rail, image: rail.png }
- - { min_zoom: 13, max_zoom: 19, name: rail, image: rail13.png }
+ - { min_zoom: 8, max_zoom: 11, name: rail, image: rail.png }
+ - { min_zoom: 12, max_zoom: 19, name: rail, image: rail12.png }
- { min_zoom: 13, max_zoom: 19, name: subway, image: subway.png }
- { min_zoom: 13, max_zoom: 19, name: tram, image: tram.png }
- { min_zoom: 12, max_zoom: 19, name: cable, image: cable.png }
- { min_zoom: 12, max_zoom: 19, name: school, image: school.png }
- { min_zoom: 12, max_zoom: 19, name: building, image: building.png }
- { min_zoom: 12, max_zoom: 19, name: station, image: station.png }
- - { min_zoom: 12, max_zoom: 19, name: summit, image: summit.png }
+ - { min_zoom: 11, max_zoom: 19, name: summit, image: summit.png }
- { min_zoom: 12, max_zoom: 19, name: tunnel, image: tunnel.png }
- { min_zoom: 13, max_zoom: 19, name: bridge, image: bridge.png }
- { min_zoom: 15, max_zoom: 19, name: private, image: private.png }
# Author: Karim185.3
# Author: Kassem7899
# Author: Kuwaity26
+# Author: LaMagiaaa
# Author: MRidhaAJ
# Author: Majid Al-Dharrab
# Author: McDutchie
community_driven_community_blogs: مدونات المجتمع
community_driven_osm_foundation: مؤسسة OSM
open_data_title: البيانات المفتوحة
- open_data_1_html: 'OpenStreetMap هو %{open_data}: أنت حر في استخدامه لأي غرض!
- N! طالما أنك تنسب إلى OpenStreetMap والمساهمين فيه. إذا قمت بتعديل أو! N!
- بÙ\86اء عÙ\84Ù\89 اÙ\84بÙ\8aاÙ\86ات بطرÙ\82 Ù\85عÙ\8aÙ\86Ø© Ø\8c Ù\81Ù\8aجÙ\88ز Ù\84Ù\83 تÙ\88زÙ\8aع اÙ\84Ù\86تÙ\8aجة Ù\81Ù\82Ø·! N! تØت Ù\86Ù\81س اÙ\84ترخÙ\8aص.
- راجع %{copyright_license_link} للحصول على التفاصيل.'
+ open_data_1_html: "\nOpenStreetMap هو %{open_data}: أنت حر في استخدامه لأي غرض\n
+ طالما أنك تنسب إلى OpenStreetMap والمساهمين فيه. إذا قمت بتعديل أو \n بناء
+ عÙ\84Ù\89 اÙ\84بÙ\8aاÙ\86ات بطرÙ\82 Ù\85عÙ\8aÙ\86Ø© Ø\8c Ù\81Ù\8aجÙ\88ز Ù\84Ù\83 تÙ\88زÙ\8aع اÙ\84Ù\86تÙ\8aجة Ù\81Ù\82Ø·\nتØت Ù\86Ù\81س اÙ\84ترخÙ\8aص. راجع
+ %{copyright_license_link} للحصول على التفاصيل."
open_data_open_data: البيانات المفتوحة
open_data_copyright_license: صفحة حقوق النشر والترخيص
legal_title: قانوني
andy_allan: অ্যান্ডি অ্যালান
site:
edit_tooltip: মানচিত্রটি সম্পাদনা করুন
+ embed_html_disabled: এই মানচিত্রের স্তরের জন্য এইচটিএমএল এম্বেডিং উপলব্ধ নয়।
changesets:
show:
comment: মন্তব্য
Degas a reomp da soñj da genlabourerien OSM ne zleont morse lakaat roadennoù a zeu
eus mammennoù dindan wirioù (da sk. : Google Maps pe kartennoù moullet) hep aotre
ezpleg ar re zo ar gwirioù-aozer ganto.
+ trademarks_title: Merkoù marilhet
trademarks_1_1_trademark_policy: Politikerezh e-keñver ar merkoù
index:
js_1: Pe emaoc'h oc'h implijout ur merdeer ha ne skor ket JavaScript, pe hoc'h
retain_notes: Your map notes and note comments, if any, will be retained but hidden from view.
retain_changeset_discussions: Your changeset discussions, if any, will be retained.
retain_email: Your email address will be retained.
+ recent_editing_html: "As you have edited recently your account cannot currently be deleted. Deletion will be possible in %{time}."
confirm_delete: Are you sure?
cancel: Cancel
accounts:
map_data_zoom_in_tooltip: Zoom in to see map data
queryfeature_tooltip: Query features
queryfeature_disabled_tooltip: Zoom in to query features
+ embed_html_disabled: HTML embedding is not available for this map layer
changesets:
show:
comment: "Comment"
openid: OpenID
google: Google
facebook: Facebook
+ microsoft: Microsoft
github: GitHub
wikipedia: Wikipedia
api:
Resources Canada), ja StatCanista (Geography Division,
Statistics Canada).
contributors_ca_canada: Kanada
+ contributors_cz_czechia: Tšekki
contributors_fi_credit_html: '%{finland}: Sisältää karttatietoja Maanmittauslaitoksen
maastotietokannasta ja muista lähteistä %{nlsfi_license_link} mukaisesti.'
contributors_fi_finland: Suomi
retain_changeset_discussions: Vos discussions sur les groupes de modification,
s’il y en a, seront conservées.
retain_email: Votre adresse de courriel sera conservée.
+ recent_editing_html: Comme vous avez récemment fait des modifications, votre
+ compte ne peut pas être supprimé pour le moment. La suppression sera possible
+ dans %{time}.
confirm_delete: Êtes-vous sûr(e) ?
cancel: Annuler
accounts:
map_data_zoom_in_tooltip: Zoomez pour lire voir les données sur la carte
queryfeature_tooltip: Interroger les objets
queryfeature_disabled_tooltip: Zoomer plus pour rechercher des objets
+ embed_html_disabled: L’intégration de HTML n’est pas disponible pour cette couche
+ de carte
changesets:
show:
comment: Commenter
retain_changeset_discussions: Conservaremos os teus conxuntos de modificacións,
se os hai.
retain_email: Conservaremos o teu enderezo de correo electrónico.
+ recent_editing_html: Como editaches hai pouco, a túa conta non se pode eliminar
+ nestes intres. A eliminación será posible en %{time}.
confirm_delete: Queres continuar?
cancel: Cancelar
accounts:
retain_changeset_discussions: הדיונים שלכם על ערכות השינויים, אם יש כאלה,
יישמרו.
retain_email: כתובת הדואר האלקטרוני שלך תישמר.
+ recent_editing_html: כיוון שערכת לאחרונה אין אפשרות למחוק את החשבון שלך. אפשר
+ יהיה למחוק אותו בעוד %{time}.
confirm_delete: להמשיך?
cancel: ביטול
accounts:
role:
administrator: לחשבון הזה יש הרשאות מפעיל
moderator: זהו חשבון מנהל
+ importer: המשתמש הזה הוא מייבא
grant:
administrator: הענקת הרשאות מפעיל
moderator: הענקת הרשאות מנהל
+ importer: הענקת גישת מייבא
revoke:
administrator: שלילת הרשאות מפעיל
moderator: שלילת הרשאות מנהל
+ importer: שלילת גישת מייבא
block_history: חסימות פעילות
moderator_history: חסימות שניתנו
comments: הערות
one: '%{count} महीने पहले'
other: '%{count} महीने पहले'
x_years:
- one: '%{count} साल पहले'
- other: '%{count} साल पहले'
+ one: '%{count} वरà¥\8dष पहले'
+ other: '%{count} वरà¥\8dष पहले'
editor:
default: डिफ़ॉल्ट (currently %{name})
id:
retain_changeset_discussions: Tu discussiones sur gruppos de modificationes,
si existe, essera retenite.
retain_email: Tu adresse de e-mail essera retenite.
+ recent_editing_html: Post que tu ha recentemente apportate modificationes,
+ tu conto non pote esser delite al momento. Le deletion essera possibile
+ in %{time}.
confirm_delete: Es tu secur?
cancel: Cancellar
accounts:
update: ನವೀಕರಿಸಿ
trace:
create: ಅಪ್ಲೋಡ್
+ update: ಬದಲಾವಣೆಗಳನ್ನು ಉಳಿಸಿ
activerecord:
errors:
messages:
home_lon: ರೇಖಾಂಶ
languages: ಅದ್ಯತೆಯ ಭಾಷೆಗಳು
pass_crypt: ಪ್ರವೇಶಪದ
+ pass_crypt_confirmation: ಪ್ರವೇಶಪದವನ್ನು ಧೃಡೀಕರಿಸಿ
datetime:
distance_in_words_ago:
about_x_hours:
one: ೧ ಸೆಕೆಂಡ್ ಹಿಂದೆ
other: '%{count} ಸೆಕೆಂಡುಗಳ ಹಿಂದೆ'
x_minutes:
- one: ೧ ಮಿನಿಟ್ ಹಿಂದೆ
- other: '%{count} ಮಿನಿà²\9fà³\81ಗಳ ಹಿಂದೆ'
+ one: '%{count} ನಿಮಿಷದ ಹಿಂದೆ'
+ other: '%{count} ನಿಮಿಷಗಳ ಹಿಂದೆ'
x_days:
one: ೧ ದಿನದ ಹಿಂದೆ
other: '%{count} ದಿನಗಳ ಹಿಂದೆ'
auth:
providers:
none: ಯಾವುದೂ ಇಲ್ಲ
+ openid: ಓಪನ್ ಐಡಿ
google: ಗೂಗಲ್
facebook: ಫೇಸ್ಬುಕ್
- microsoft: ವಿà²\82ಡà³\8bಸà³\8d ಲà³\88ವ್
+ microsoft: ಮà³\88à²\95à³\8dರà³\8bಸಾಫà³\8dà²\9f್
github: ಗಿಟ್ಹಬ್
wikipedia: ವಿಕಿಪೀಡಿಯ
api:
external auth: ಬಾಹ್ಯ ದೃಢೀಕರಣ
openid:
link text: ಇದು ಏನು?
+ public editing:
+ enabled link text: ಇದು ಏನು?
+ contributor terms:
+ link text: ಇದು ಏನು?
+ save changes button: ಬದಲಾವಣೆಗಳನ್ನು ಉಳಿಸಿ
+ delete_account: ಖಾತೆಯನ್ನು ಅಳಿಸಿ
+ go_public:
+ heading: ಸಾರ್ವಜನಿಕ ಸಂಪಾದನೆ
+ destroy:
+ success: ಖಾತೆಯನ್ನು ಅಳಿಸಲಾಗಿದೆ.
browse:
created: ಸೃಷ್ಟಿಸಲ್ಪಟ್ಟ
closed: ಮುಚ್ಚಲಾಗಿದೆ
km away: '%{count} ಕಿಮೀ ದೂರ'
m away: '%{count} ಮೀ ದೂರ'
popup:
+ your location: ನಿಮ್ಮ ಸ್ಥಳ
friend: ಗೆಳೆಯ
show:
my friends: ನನ್ನ ಗೆಳೆಯರು
in_language_title: ದಿನಚರಿ ದಾಖಲಾತಿ %{language}ನಲ್ಲಿ
new: ಹೊಸದಾದ ದಿನಚರಿ ದಾಖಲು
new_title: ನನ್ನ ಬಳಕೆದಾರ ದಿನಚರಿಯಲ್ಲಿ ಹೊಸ ದಾಖಲಾತಿ ನಿರ್ಮಿಸಿ
+ my_diary: ನನ್ನ ಡೈರಿ
no_entries: ದಿನಚರಿ ದಾಖಲಾತಿಗಳಿಲ್ಲ
recent_entries: ಇತ್ತೀಚೆಗಿನ ದಿನಚರಿ ದಾಖಲಾತಿಗಳು
older_entries: ಹಳೆಯ ದಾಖಲಾತಿಗಳು
comment: ಟಿಪ್ಪಣಿ
newer_comments: ಹೊಸ ಟಿಪ್ಪಣಿಗಳು
older_comments: ಹಳೆ ಟಿಪ್ಪಣಿಗಳು
+ friendships:
+ make_friend:
+ button: ಸ್ನೇಹಿತರಾಗಿ ಸೇರಿಸಿ
geocoder:
search_osm_nominatim:
prefix:
+ aeroway:
+ helipad: ಹೆಲಿಪ್ಯಾಡ್
amenity:
+ arts_centre: ಕಲಾ ಕೇಂದ್ರ
atm: ಎಟಿಎಂ
bank: ಬ್ಯಾಂಕ್
bar: ಬಾರ್
bench: ಬೆಂಚ್
bicycle_parking: ಸೈಕಲ್ ನಿಲುಗಡೆ
+ brothel: ವೇಶ್ಯಾಗೃಹ
bus_station: ಬಸ್ ನಿಲ್ದಾಣ
cafe: ಕೆಫೆ
car_rental: ಬಾಡಿಗೆ ಕಾರು
ferry_terminal: ಹಾಯಿದೋಣಿ ನಿಲ್ದಾಣ
fire_station: ಅಗ್ನಿಶಾಮಕ ಠಾಣೆ
fountain: ಕಾರಂಜಿ
- fuel: ಇಂಧನ
+ fuel: ಪೆಟ್ರೊಲ್ ಪಂಪ್
+ gambling: ಜೂಜಾಟ
grave_yard: ಸ್ಮಾಶಾನ
hospital: ಆಸ್ಪತ್ರೆ
ice_cream: ಐಸ್ ಕ್ರೀಂ
library: ಗ್ರಂಥಾಲಯ
marketplace: ಮಾರುಕಟ್ಟೆ
monastery: ಮಠ
+ parking: ಪಾರ್ಕಿಂಗ್
pharmacy: ಔಷಧಾಲಯ
place_of_worship: ಆರಾಧನಾ ಮಂದಿರ
police: ಆರಕ್ಷಕ
post_box: ಟಪಾಲು
post_office: ಅಂಚೆ ಕಛೇರಿ
prison: ಕಾರಾಗೃಹ
+ pub: ಪಬ್
public_building: ಸಾರ್ವಜನಿಕ ಕಟ್ಟಡ
restaurant: ರೆಸ್ಟೋರೆಂಟ್
school: ಶಾಲೆ
social_centre: ಸಾಮಾಜಿಕ ತಾಣ
swimming_pool: ಈಜು ಕೊಳ
+ taxi: ಟ್ಯಾಕ್ಸಿ
theatre: ಕಲಾಭವನ
toilets: ಶೌಚಾಲಯ
townhall: ಪುರಭವನ
bridge:
"yes": ಸೇತುವೆ
building:
+ bungalow: ಬಂಗಲೆ
+ hospital: ಆಸ್ಪತ್ರೆ ಕಟ್ಟಡ
+ hotel: ಹೋಟೆಲ್ ಕಟ್ಟಡ
+ house: ಮನೆ
+ houseboat: ಹೌಸ್ ಬೋಟ್
+ hut: ಗುಡಿಸಲು
+ industrial: ಕೈಗಾರಿಕಾ ಕಟ್ಟಡ
+ kindergarten: ಶಿಶುವಿಹಾರ ಕಟ್ಟಡ
+ manufacture: ಉತ್ಪಾದನಾ ಕಟ್ಟಡ
+ office: ಕಚೇರಿ ಕಟ್ಟಡ
public: ಸಾರ್ವಜನಿಕ ಕಟ್ಟಡ
+ residential: ವಸತಿ ಕಟ್ಟಡ
roof: ಛಾವಣಿ
school: ಶಾಲಾ ಕಟ್ಟಡ
"yes": ಕಟ್ಟಡ
craft:
carpenter: ಬಡಗಿ
+ electrician: ಎಲೆಕ್ಟ್ರಿಷಿಯನ್
photographer: ಛಾಯಾಗ್ರಾಹಕ
tailor: ದರ್ಜಿ
"yes": ಕರಕುಶಲ ಅಂಗಡಿಯು
railway: ಐತಿಹಾಸಿಕ ರೈಲ್ವೆ
roman_road: ರೋಮನ್ ರಸ್ತೆ
stone: ಕಲ್ಲು
+ tomb: ಸಮಾಧಿ
tower: ಗೋಪುರ
+ junction:
+ "yes": ಜಂಕ್ಷನ್
landuse:
cemetery: ಸ್ಮಶಾನ
forest: ಅರಣ್ಯ
grass: ಹುಲ್ಲು
mine: ಗಣಿ
orchard: ತೋಟ
+ reservoir: ಜಲಾಶಯ
leisure:
dog_park: ಶ್ವಾನ ಉದ್ಯಾನ
garden: ತೋಟ
administrative: ಆಡಳಿತ
architect: ವಾಸ್ತುಶಿಲ್ಪಿ
company: ಕಂಪನಿ
+ educational_institution: ಶೈಕ್ಷಣಿಕ ಸಂಸ್ಥೆ
+ employment_agency: ಉದ್ಯೋಗ ಸಂಸ್ಥೆ
government: ಸರ್ಕಾರಿ ಕಛೇರಿ
lawyer: ವಕೀಲ
ngo: ಸರ್ಕಾರೇತರ ಕಛೇರಿ
+ tax_advisor: ತೆರಿಗೆ ಸಲಹೆಗಾರರು
"yes": ಕಛೇರಿ
place:
archipelago: ದ್ವೀಪ ಸಮೂಹ
halt: ರೈಲು ನಿಲ್ದಾಣ
junction: ರೈಲು ಜಂಕ್ಷನ್
monorail: ಮೊನೊರೈಲು
+ rail: ರೈಲು
station: ರೈಲು ನಿಲ್ದಾಣ
stop: ರೈಲು ನಿಲ್ದಾಣ
shop:
chocolate: ಚಾಕೊಲೇಟ್
clothes: ಬಟ್ಟೆಯ ಅಂಗಡಿ
computer: ಗಣಕಯಂತ್ರದ ಅಂಗಡಿ
+ dairy: ಡೈರಿ ಅಂಗಡಿ
florist: ಹೂವಿನಂಗಡಿ
furniture: ಪೀಠೋಪಕರಣ
general: ಕಿರಾಣಿ ಅಂಗಡಿ
gift: ಉಡುಗೊರೆ ಅಂಗಡಿ
jewelry: ಆಭರಣಗಳ ಆಂಗಡಿ
+ kitchen: ಅಡುಗೆ ಅಂಗಡಿ
"yes": ಅಂಗಡಿ
tourism:
hostel: ವಸತಿ ನಿಲಯ
index:
search: ಹುಡುಕು
user_not_found: ಬಳಕೆದಾರ ಅಸ್ತಿತ್ವದಲ್ಲಿಲ್ಲ
+ status: ಸ್ಥಿತಿಗತಿ
reports: ವರದಿಗಳು
+ last_updated: ಕೊನೆಯ ಬದಲಾವಣೆ
+ states:
+ open: ತೆರೆ
+ resolved: ಪರಿಹರಿಸಲಾಗಿದೆ
show:
+ resolve: ಪರಿಹರಿಸಿ
+ ignore: ನಿರ್ಲಕ್ಷಿಸಿ
new_reports: ಹೊಸ ವರದಿಗಳು
reports:
new:
export_data: ದತ್ತಾಂಶ ರಫ್ತುಮಾಡು
intro_header: ಒಪನ್ ಸ್ಟ್ರೀಟ್ ಮ್ಯಾಪ್ ಗೆ ಸುಸ್ವಾಗತ!
intro_2_create_account: ಹೊಸ ಬಳಕೆದಾರ ಖಾತೆಯನ್ನು ರಚಿಸಿ
+ partners_ucl: ಯುಸಿಎಲ್
+ partners_bytemark: ಬೈಟ್ಮಾರ್ಕ್ ಹೋಸ್ಟಿಂಗ್
tou: ಬಳಕೆಯ ನಿಬಂಧನೆಗಳು
help: ಸಹಾಯ
about: ನಮ್ಮ ಬಗ್ಗೆ
copyright: ಕಾಯ್ದಿರಿಸಿದ ಹಕ್ಕುಗಳು
+ communities: ಸಮುದಾಯಗಳು
community: ಸಮುದಾಯ
community_blogs: ಸಮುದಾಯದ ಬ್ಲಾಗ್ ಗಳು
make_a_donation:
greeting: ನಮಸ್ತೆ,
changeset_comment_notification:
greeting: ನಮಸ್ತೆ,
+ confirmations:
+ confirm:
+ button: ಧೃಡಪಡಿಸಿ
+ confirm_email:
+ button: ಧೃಡಪಡಿಸಿ
messages:
inbox:
from: ಇಂದ
new:
title: ಸಂದೇಶ ಕಳುಹಿಸಿ
send_message_to_html: ಹೊಸ ಸಂದೇಶವನ್ನು %{name} ಗೆ ಕಳುಹಿಸಿ
+ no_such_message:
+ title: ಅಂತಹ ಯಾವುದೇ ಸಂದೇಶವಿಲ್ಲ
+ heading: ಅಂತಹ ಯಾವುದೇ ಸಂದೇಶವಿಲ್ಲ
outbox:
to: ಗೆ
subject: ವಿಷಯ
preferences:
show:
title: ನನ್ನ ಪ್ರಾಶಸ್ತ್ಯಗಳು
+ preferred_languages: ಅದ್ಯತೆಯ ಭಾಷೆಗಳು
+ edit_preferences: ಪ್ರಾಶಸ್ತ್ಯಗಳನ್ನು ಸಂಪಾದಿಸಿ
+ edit:
+ title: ಪ್ರಾಶಸ್ತ್ಯಗಳನ್ನು ಸಂಪಾದಿಸಿ
profiles:
edit:
image: ಚಿತ್ರ
+ show: ತೋರಿಸಿ
+ delete: ಅಳಿಸಿ
sessions:
new:
title: ಲಾಗ್ ಇನ್
heading: ಲಾಗಿನ್
password: 'ಪ್ರವೇಶಪದ:'
login_button: ಲಾಗಿನ್
+ auth_providers:
+ google:
+ title: ಗೂಗಲ್ ಮೂಲಕ ಲಾಗಿನ್ ಆಗಿರಿ
+ alt: ಗೂಗಲ್ ಓಪನ್ ಐಡಿಯೊಂದಿಗೆ ಲಾಗಿನ್ ಮಾಡಿ
+ facebook:
+ title: ಫೇಸ್ಬುಕ್ ಮೂಲಕ ಲಾಗಿನ್ ಆಗಿರಿ
+ alt: ಫೇಸ್ಬುಕ್ ಖಾತೆಯೊಂದಿಗೆ ಲಾಗಿನ್ ಮಾಡಿ
+ microsoft:
+ alt: ಮೈಕ್ರೋಸಾಫ್ಟ್ ಖಾತೆಯೊಂದಿಗೆ ಪ್ರವೇಶಿಸಿ
+ github:
+ alt: ಗಿಟ್ಹಬ್ ಖಾತೆಯೊಂದಿಗೆ ಲಾಗಿನ್ ಮಾಡಿ
+ wikipedia:
+ title: ವಿಕಿಪೀಡಿಯದೊಂದಿಗೆ ಪ್ರವೇಶಿಸಿ
+ alt: ವಿಕಿಪೀಡಿಯ ಖಾತೆಯೊಂದಿಗೆ ಪ್ರವೇಶಿಸಿ
destroy:
title: ಲಾಗ್ ಔಟ್
logout_button: ಲಾಗ್ ಔಟ್
site:
about:
next: ಮುಂದಿನ
+ local_knowledge_title: ಸ್ಥಳೀಯ ಜ್ಞಾನ
open_data_title: ಮುಕ್ತ ದತ್ತಾಂಶ
copyright:
foreign:
mapping_link: ನಕ್ಷೆಯನ್ನು ಸಂಪಾದಿಸಿಲು ಪ್ರಾರಂಭಿಸಿ
legal_babble:
title_html: ಕೃತಿಸ್ವಾಮ್ಯ ಮತ್ತು ಪರವಾನಗಿ
+ contributors_at_austria: ಆಸ್ಟ್ರಿಯಾ
+ contributors_au_australia: ಆಸ್ಟ್ರೇಲಿಯಾ
+ contributors_ca_canada: ಕೆನಡಾ
+ contributors_cz_czechia: ಜೆಕಿಯಾ
+ contributors_fi_finland: ಫಿನ್ಲ್ಯಾಂಡ್
+ contributors_fr_france: ಫ಼್ರಾನ್ಸ್
+ contributors_nl_netherlands: ನೆದರ್ಲೆಂಡ್
+ contributors_nz_new_zealand: ನ್ಯೂಜಿಲ್ಯಾಂಡ್
+ contributors_rs_serbia: ಸರ್ಬಿಯಾ
+ contributors_si_slovenia: ಸ್ಲೊವೆನಿಯಾ
+ contributors_es_spain: ಸ್ಪೇನ್
+ contributors_za_south_africa: ದಕ್ಷಿಣ ಆಫ್ರಿಕಾ
+ contributors_gb_united_kingdom: ಯುನೈಟೆಡ್ ಕಿಂಗ್ಡಮ್
export:
title: ರಫ್ತು ಮಾಡು
licence: ಪರವಾನಗಿ
traces:
new:
help: ಸಹಾಯ
+ oauth_clients:
+ show:
+ edit: ವಿವರಗಳನ್ನು ಸಂಪಾದಿಸಿ
+ oauth2_applications:
+ application:
+ edit: ಸಂಪಾದಿಸಿ
+ delete: ಅಳಿಸಿ
+ show:
+ edit: ಸಂಪಾದಿಸಿ
users:
terms:
legale_names:
france: ಫ಼್ರಾನ್ಸ್
italy: ಇಟಲಿ
+ show:
+ my messages: ನನ್ನ ಸಂದೇಶಗಳು
+ edits: ಸಂಪಾದನೆಗಳು
user_blocks:
show:
created: 'ಸೃಷ್ಟಿಸಲ್ಪಟ್ಟಿದೆ:'
retain_notes: Вашите белешки и коментари на картата (но нема да бидат видливи).
retain_changeset_discussions: Вашите разговори за збировите промени.
retain_email: Вашите е-поштенски адреси.
+ recent_editing_html: Бидејќи неодамна уредувавте, вашата сметка засега не
+ може да се избрише. Бришењето ќе може да се изведе за %{time}.
confirm_delete: Дали сте сигурни?
cancel: Откажи
accounts:
map_data_zoom_in_tooltip: Приближете за да ги видите податоците
queryfeature_tooltip: Пребарување на елементи
queryfeature_disabled_tooltip: Зголеми на пребарувањето на елементи
+ embed_html_disabled: Вградувањето на HTML не е достапно за овој слој на картата
changesets:
show:
comment: Коментирај
retain_changeset_discussions: Uw overleg over wijzigingensets, indien van
toepassing, blijft behouden.
retain_email: Uw e-mailadres blijft behouden.
+ recent_editing_html: Omdat u onlangs bewerkingen hebt aangebracht, kan uw
+ account momenteel niet worden verwijderd. Verwijderen is pas over %{time}
+ mogelijk.
confirm_delete: Weet u het zeker?
cancel: Annuleren
accounts:
role:
administrator: Deze gebruiker is beheerder
moderator: Deze gebruiker is moderator
+ importer: Deze gebruiker is een importeur
grant:
administrator: Beheerdersrechten toekennen
moderator: Moderatorrechten toekennen
+ importer: Importeurstoegang verlenen
revoke:
administrator: Beheerdersrechten intrekken
moderator: Moderatorrechten intrekken
+ importer: Importeurstoegang intrekken
block_history: Actieve blokkades
moderator_history: Uitgevoerde blokkades
comments: Reacties
map_data_zoom_in_tooltip: Inzoomen om kaartgegevens te bekijken
queryfeature_tooltip: Nabije objecten opvragen
queryfeature_disabled_tooltip: Inzoomen om objecten op te vragen
+ embed_html_disabled: Het inbedden van HTML-code is voor deze kaartlaag niet
+ mogelijk
changesets:
show:
comment: Reageren
tracetag: Eticheta de su sestadu
user: Utente
user_preference: Preferèntzias de s'utente
- user_token: Còdighe de s'utente
+ user_token: Getone de s'utente
way: Lìnia
way_node: Nodu de su caminu
way_tag: Eticheta de sa lìnia
retain_changeset_discussions: Sos arresonos tuos in sos annantos de modìficas,
si bi nd'at, s'ant a cunservare.
retain_email: S'indiritzu tuo de posta eletrònica s'at a cunservare.
+ recent_editing_html: Sende chi as modificadu dae pagu su contu tuo non si
+ podet iscantzellare. Sa cantzelladura at a èssere possìbile in %{time}.
confirm_delete: Seguru ses?
cancel: Annulla
accounts:
de s'utente finale
interaction_required: Su serbidore de autorizatzione tenet bisòngiu de s'interatzione
de s'utente finale
+ login_required: Su serbidore de autorizatzione tenet bisòngiu de s'autenticatzione
+ de s'utente finale
flash:
applications:
create:
notice: Aplicatzione registrada.
+ openid_connect:
+ errors:
+ messages:
+ auth_time_from_resource_owner_not_configured: Errore pro neghe de sa cunfiguratzione
+ mancante de Doorkeeper::OpenidConnect.configure.auth_time_from_resource_owner.
+ reauthenticate_resource_owner_not_configured: Errore pro neghe de sa cunfiguratzione
+ mancante de Doorkeeper::OpenidConnect.configure.reauthenticate_resource_owner.
+ resource_owner_from_access_token_not_configured: Errore pro neghe de sa
+ cunfiguratzione mancante de Doorkeeper::OpenidConnect.configure.resource_owner_from_access_token.
+ select_account_for_resource_owner_not_configured: Errore pro neghe de sa
+ cunfiguratzione mancante de Doorkeeper::OpenidConnect.configure.select_account_for_resource_owner.
+ subject_not_configured: Sa generatzione de su getone ID est fallida pro
+ neghe de sa cunfiguratzione mancante de Doorkeeper::OpenidConnect.configure.subject.
+ scopes:
+ address: Pòmpia s'indiritzu fìsicu tuo
+ email: Pòmpia s'indiritzu de posta eletrònica tuo
+ openid: Autèntica su contu tuo
+ phone: Pòmpia su nùmeru tuo de telèfonu
+ profile: Pòmpia sas informatziones de su profilu tuo
errors:
contact:
contact_url_title: Canales de cuntatu diferentes ispiegados
Naturales de su Cànada), e StatCan (Divisione de Geografia,
Istatìsticas de su Cànada).
contributors_ca_canada: Cànada
+ contributors_cz_credit_html: '%{czechia}: Cuntenet datos de s''Amministratzione
+ Istatale pro sa Medida de su Terrinu e de su Catastu cun litzèntzia suta
+ de sa %{cc_licence_link}'
+ contributors_cz_czechia: Tzèchia
+ contributors_cz_cc_licence: Litzèntzia internatzionale Creative Commons Atributzione
+ 4.0 (CC BY 4.0)
contributors_fi_credit_html: |-
%{finland}: Cuntenet datos dae sa
base de datos topogràficos de su Servìtziu Natzionale de su Territòriu Finlandesu e àteros annantos de datos, suta de sa %{nlsfi_license_link}.
permissions:
missing: No as cuntzèdidu s'atzessu a custa caraterìstica a s'aplicatzione
scopes:
+ openid: Intra impreende OpenStreetMap
read_prefs: Leghe sas preferèntzias de utente
write_prefs: Modìfica sas preferèntzias de utente
write_diary: Crea intradas de su diàriu, cummentos e faghe amistades
role:
administrator: Custu utente est un'amministradore
moderator: Custu utente est unu moderadore
+ importer: Custu impitadore est un'importadore
grant:
administrator: Cuntzede s'atzessu comente amministradore
moderator: Cuntzede s'atzessu comente moderadore
+ importer: Cuntzede s'atzessu comente importadore
revoke:
administrator: Rèvoca s'atzessu comente amministradore
moderator: Rèvoca s'atzessu comente moderadore
+ importer: Rèvoca s'atzessu comente importadore
block_history: Blocos ativos
moderator_history: Blocos fatos
comments: Cummentos
cyclosm: CyclOSM
cycle_map: Mapa tziclìstica
transport_map: Mapa de sos trasportos
+ tracestracktop_topo: Tracestrack Topo
hot: Umanitàriu
opnvkarte: ÖPNVKarte
layers:
andy_allan: Andy Allan
opnvkarte_credit: Tasseddos frunidos pro cortesia dae %{memomaps_link}
memomaps: MeMoMaps
+ tracestrack_credit: Tasseddos frunidos pro cortesia dae %{tracestrack_link}
hotosm_credit: Istile de sos tasseddos de %{hotosm_link} acasagiadu dae %{osm_france_link}
hotosm_name: Iscuadra umanitària de OpenStreetMap
site:
stay_roundabout_without_exit: Stay on roondaboot - %{name}
start_without_exit: Stairt at end o %{name}
destination_without_exit: Reak destination
- against_oneway_without_exit: Gae against ane-wey on %{name}
+ against_oneway_without_exit: Gae agin ane-wey on %{name}
end_oneway_without_exit: End o ane-wey on %{name}
roundabout_with_exit: At roondaboot tak exit %{exit} ontae %{name}
unnamed: unnamed road
retain_notes: 若有您的地圖註記與註記評論內容,這將會繼續保留;不過會隱藏起來。
retain_changeset_discussions: 若有您的變更集討論,這將會繼續保留。
retain_email: 您的電子郵件地址將會繼續保留。
+ recent_editing_html: 因為您最近有作過編輯,目前無法刪除您的帳號。在 %{time} 後才可刪除。
confirm_delete: 您確定嗎?
cancel: 取消
accounts:
map_data_zoom_in_tooltip: 放大以查看地圖圖資
queryfeature_tooltip: 查詢圖徵
queryfeature_disabled_tooltip: 放大地圖以查询圖徵
+ embed_html_disabled: HTML 內嵌對此地圖圖層不可用
changesets:
show:
comment: 評論
web_timeout: 30
# Periods (in hours) which are allowed for user blocks
user_block_periods: [0, 1, 3, 6, 12, 24, 48, 96, 168, 336, 731, 4383, 8766, 87660]
+# Account deletion cooldown period (in hours) since last changeset close; null to disable, 0 to make sure there aren't any open changesets when the deletion happens
+user_account_deletion_delay: null
# Rate limit for message sending
max_messages_per_hour: 60
# Rate limit for friending
--- /dev/null
+class AddClosedAtIndexToChangesets < ActiveRecord::Migration[7.1]
+ disable_ddl_transaction!
+
+ def change
+ add_index :changesets, [:user_id, :closed_at], :algorithm => :concurrently
+ end
+end
CREATE INDEX index_changeset_comments_on_created_at ON public.changeset_comments USING btree (created_at);
+--
+-- Name: index_changesets_on_user_id_and_closed_at; Type: INDEX; Schema: public; Owner: -
+--
+
+CREATE INDEX index_changesets_on_user_id_and_closed_at ON public.changesets USING btree (user_id, closed_at);
+
+
--
-- Name: index_changesets_subscribers_on_changeset_id; Type: INDEX; Schema: public; Owner: -
--
('23'),
('22'),
('21'),
+('20231117170422'),
('20231101222146'),
('20231029151516'),
('20231010194809'),
test "note permissions for a guest" do
ability = ApiAbility.new nil
- [:index, :create, :comment, :feed, :show, :search].each do |action|
+ [:index, :create, :feed, :show, :search].each do |action|
assert ability.can?(action, Note), "should be able to #{action} Notes"
end
- [:close, :reopen, :destroy].each do |action|
+ [:comment, :close, :reopen, :destroy].each do |action|
assert ability.cannot?(action, Note), "should not be able to #{action} Notes"
end
end
# Make sure we have a button to "go public"
assert_select "form.button_to[action='/user/go_public']", true
end
+
+ def test_destroy_allowed
+ user = create(:user)
+ session_for(user)
+
+ delete account_path
+ assert_response :redirect
+ end
+
+ def test_destroy_not_allowed
+ with_user_account_deletion_delay(24) do
+ user = create(:user)
+ create(:changeset, :user => user, :created_at => Time.now.utc)
+ session_for(user)
+
+ delete account_path
+ assert_response :bad_request
+ end
+ end
end
:redirect_uri => "https://bad.example.com/",
:response_type => "code",
:scope => "write_api")
- assert_response :success
+ assert_response :bad_request
assert_template "oauth2_authorizations/error"
assert_select "p", "The requested redirect uri is malformed or doesn't match client redirect URI."
end
:redirect_uri => application.redirect_uri,
:response_type => "code",
:scope => "bad_scope")
- assert_response :success
+ assert_response :bad_request
assert_template "oauth2_authorizations/error"
assert_select "p", "The requested scope is invalid, unknown, or malformed."
:redirect_uri => application.redirect_uri,
:response_type => "code",
:scope => "write_prefs")
- assert_response :success
+ assert_response :bad_request
assert_template "oauth2_authorizations/error"
assert_select "p", "The requested scope is invalid, unknown, or malformed."
end
oauth_access_token.reload
assert_predicate oauth_access_token, :revoked?
end
+
+ def test_deletion_allowed_when_no_changesets
+ with_user_account_deletion_delay(10000) do
+ user = create(:user)
+ assert_predicate user, :deletion_allowed?
+ end
+ end
+
+ def test_deletion_allowed_without_delay
+ with_user_account_deletion_delay(nil) do
+ user = create(:user)
+ create(:changeset, :user => user)
+ user.reload
+ assert_predicate user, :deletion_allowed?
+ end
+ end
+
+ def test_deletion_allowed_past_delay
+ with_user_account_deletion_delay(10) do
+ user = create(:user)
+ create(:changeset, :user => user, :created_at => Time.now.utc - 12.hours, :closed_at => Time.now.utc - 10.hours)
+ user.reload
+ assert_predicate user, :deletion_allowed?
+ end
+ end
+
+ def test_deletion_allowed_during_delay
+ with_user_account_deletion_delay(10) do
+ user = create(:user)
+ create(:changeset, :user => user, :created_at => Time.now.utc - 11.hours, :closed_at => Time.now.utc - 9.hours)
+ user.reload
+ assert_not_predicate user, :deletion_allowed?
+ assert_equal Time.now.utc + 1.hour, user.deletion_allowed_at
+ end
+ end
+
+ def test_deletion_allowed_past_zero_delay
+ with_user_account_deletion_delay(0) do
+ user = create(:user)
+ create(:changeset, :user => user, :created_at => Time.now.utc, :closed_at => Time.now.utc + 1.hour)
+ travel 90.minutes do
+ user.reload
+ assert_predicate user, :deletion_allowed?
+ end
+ end
+ end
+
+ def test_deletion_allowed_during_zero_delay
+ with_user_account_deletion_delay(0) do
+ user = create(:user)
+ create(:changeset, :user => user, :created_at => Time.now.utc, :closed_at => Time.now.utc + 1.hour)
+ travel 30.minutes do
+ user.reload
+ assert_not_predicate user, :deletion_allowed?
+ assert_equal Time.now.utc + 30.minutes, user.deletion_allowed_at
+ end
+ end
+ end
end
assert_content "Account Deleted"
end
+
+ test "can delete with any delay setting value if the user has no changesets" do
+ with_user_account_deletion_delay(10000) do
+ travel 1.hour do
+ visit edit_account_path
+
+ click_link "Delete Account..."
+
+ assert_no_content "cannot currently be deleted"
+ end
+ end
+ end
+
+ test "can delete with delay disabled" do
+ with_user_account_deletion_delay(nil) do
+ create(:changeset, :user => @user)
+
+ travel 1.hour do
+ visit edit_account_path
+
+ click_link "Delete Account..."
+
+ assert_no_content "cannot currently be deleted"
+ end
+ end
+ end
+
+ test "can delete when last changeset is old enough" do
+ with_user_account_deletion_delay(10) do
+ create(:changeset, :user => @user, :created_at => Time.now.utc, :closed_at => Time.now.utc + 1.hour)
+
+ travel 12.hours do
+ visit edit_account_path
+
+ click_link "Delete Account..."
+
+ assert_no_content "cannot currently be deleted"
+ end
+ end
+ end
+
+ test "can't delete when last changeset isn't old enough" do
+ with_user_account_deletion_delay(10) do
+ create(:changeset, :user => @user, :created_at => Time.now.utc, :closed_at => Time.now.utc + 1.hour)
+
+ travel 10.hours do
+ visit edit_account_path
+
+ click_link "Delete Account..."
+
+ assert_content "cannot currently be deleted"
+ assert_content "in about 1 hour"
+ end
+ end
+ end
end
el << tag_el
end
end
+
+ def with_user_account_deletion_delay(value)
+ freeze_time
+ default_value = Settings.user_account_deletion_delay
+ Settings.user_account_deletion_delay = value
+
+ yield
+
+ Settings.user_account_deletion_delay = default_value
+ unfreeze_time
+ end
end
end
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
-"@eslint/js@8.53.0":
- version "8.53.0"
- resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.53.0.tgz#bea56f2ed2b5baea164348ff4d5a879f6f81f20d"
- integrity sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==
+"@eslint/js@8.54.0":
+ version "8.54.0"
+ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.54.0.tgz#4fab9a2ff7860082c304f750e94acd644cf984cf"
+ integrity sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==
"@humanwhocodes/config-array@^0.11.13":
version "0.11.13"
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
eslint@^8.0.0:
- version "8.53.0"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.53.0.tgz#14f2c8244298fcae1f46945459577413ba2697ce"
- integrity sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==
+ version "8.54.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.54.0.tgz#588e0dd4388af91a2e8fa37ea64924074c783537"
+ integrity sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==
dependencies:
"@eslint-community/eslint-utils" "^4.2.0"
"@eslint-community/regexpp" "^4.6.1"
"@eslint/eslintrc" "^2.1.3"
- "@eslint/js" "8.53.0"
+ "@eslint/js" "8.54.0"
"@humanwhocodes/config-array" "^0.11.13"
"@humanwhocodes/module-importer" "^1.0.1"
"@nodelib/fs.walk" "^1.2.8"